Merge "Add background executor to AppSearchManagerService." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
b2b415d0a0
@@ -68,6 +68,10 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.SynchronousQueue;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/** TODO(b/142567528): add comments when implement this class */
|
/** TODO(b/142567528): add comments when implement this class */
|
||||||
public class AppSearchManagerService extends SystemService {
|
public class AppSearchManagerService extends SystemService {
|
||||||
@@ -77,6 +81,14 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
private ImplInstanceManager mImplInstanceManager;
|
private ImplInstanceManager mImplInstanceManager;
|
||||||
private UserManager mUserManager;
|
private UserManager mUserManager;
|
||||||
|
|
||||||
|
// Never call shutdownNow(). It will cancel the futures it's returned. And since
|
||||||
|
// Executor#execute won't return anything, we will hang forever waiting for the execution.
|
||||||
|
// AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all
|
||||||
|
// mutate requests will need to gain write lock and query requests need to gain read lock.
|
||||||
|
private static final Executor EXECUTOR = new ThreadPoolExecutor(/*corePoolSize=*/1,
|
||||||
|
Runtime.getRuntime().availableProcessors(), /*keepAliveTime*/ 60L, TimeUnit.SECONDS,
|
||||||
|
new SynchronousQueue<Runnable>());
|
||||||
|
|
||||||
// Cache of unlocked user ids so we don't have to query UserManager service each time. The
|
// Cache of unlocked user ids so we don't have to query UserManager service each time. The
|
||||||
// "locked" suffix refers to the fact that access to the field should be locked; unrelated to
|
// "locked" suffix refers to the fact that access to the field should be locked; unrelated to
|
||||||
// the unlocked status of user ids.
|
// the unlocked status of user ids.
|
||||||
@@ -166,41 +178,41 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
|
List<AppSearchSchema> schemas = new ArrayList<>(schemaBundles.size());
|
||||||
for (int i = 0; i < schemaBundles.size(); i++) {
|
for (int i = 0; i < schemaBundles.size(); i++) {
|
||||||
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
|
schemas.add(new AppSearchSchema(schemaBundles.get(i)));
|
||||||
}
|
|
||||||
Map<String, List<PackageIdentifier>> schemasPackageAccessible =
|
|
||||||
new ArrayMap<>(schemasPackageAccessibleBundles.size());
|
|
||||||
for (Map.Entry<String, List<Bundle>> entry :
|
|
||||||
schemasPackageAccessibleBundles.entrySet()) {
|
|
||||||
List<PackageIdentifier> packageIdentifiers =
|
|
||||||
new ArrayList<>(entry.getValue().size());
|
|
||||||
for (int i = 0; i < entry.getValue().size(); i++) {
|
|
||||||
packageIdentifiers.add(new PackageIdentifier(entry.getValue().get(i)));
|
|
||||||
}
|
}
|
||||||
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
|
Map<String, List<PackageIdentifier>> schemasPackageAccessible =
|
||||||
|
new ArrayMap<>(schemasPackageAccessibleBundles.size());
|
||||||
|
for (Map.Entry<String, List<Bundle>> entry :
|
||||||
|
schemasPackageAccessibleBundles.entrySet()) {
|
||||||
|
List<PackageIdentifier> packageIdentifiers =
|
||||||
|
new ArrayList<>(entry.getValue().size());
|
||||||
|
for (int i = 0; i < entry.getValue().size(); i++) {
|
||||||
|
packageIdentifiers.add(
|
||||||
|
new PackageIdentifier(entry.getValue().get(i)));
|
||||||
|
}
|
||||||
|
schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
|
||||||
|
}
|
||||||
|
AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
|
SetSchemaResponse setSchemaResponse = impl.setSchema(
|
||||||
|
packageName,
|
||||||
|
databaseName,
|
||||||
|
schemas,
|
||||||
|
schemasNotDisplayedBySystem,
|
||||||
|
schemasPackageAccessible,
|
||||||
|
forceOverride,
|
||||||
|
schemaVersion);
|
||||||
|
invokeCallbackOnResult(callback,
|
||||||
|
AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
AppSearchImpl impl = mImplInstanceManager.getAppSearchImpl(callingUserId);
|
});
|
||||||
SetSchemaResponse setSchemaResponse = impl.setSchema(
|
|
||||||
packageName,
|
|
||||||
databaseName,
|
|
||||||
schemas,
|
|
||||||
schemasNotDisplayedBySystem,
|
|
||||||
schemasPackageAccessible,
|
|
||||||
forceOverride,
|
|
||||||
schemaVersion);
|
|
||||||
invokeCallbackOnResult(callback,
|
|
||||||
AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -214,20 +226,20 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
GetSchemaResponse response = impl.getSchema(packageName, databaseName);
|
GetSchemaResponse response = impl.getSchema(packageName, databaseName);
|
||||||
invokeCallbackOnResult(
|
invokeCallbackOnResult(
|
||||||
callback, AppSearchResult.newSuccessfulResult(response.getBundle()));
|
callback,
|
||||||
} catch (Throwable t) {
|
AppSearchResult.newSuccessfulResult(response.getBundle()));
|
||||||
invokeCallbackOnError(callback, t);
|
} catch (Throwable t) {
|
||||||
} finally {
|
invokeCallbackOnError(callback, t);
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -241,19 +253,19 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
List<String> namespaces = impl.getNamespaces(packageName, databaseName);
|
List<String> namespaces = impl.getNamespaces(packageName, databaseName);
|
||||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces));
|
invokeCallbackOnResult(callback,
|
||||||
} catch (Throwable t) {
|
AppSearchResult.newSuccessfulResult(namespaces));
|
||||||
invokeCallbackOnError(callback, t);
|
} catch (Throwable t) {
|
||||||
} finally {
|
invokeCallbackOnError(callback, t);
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -269,31 +281,30 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||||
new AppSearchBatchResult.Builder<>();
|
new AppSearchBatchResult.Builder<>();
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
for (int i = 0; i < documentBundles.size(); i++) {
|
for (int i = 0; i < documentBundles.size(); i++) {
|
||||||
GenericDocument document = new GenericDocument(documentBundles.get(i));
|
GenericDocument document = new GenericDocument(documentBundles.get(i));
|
||||||
try {
|
try {
|
||||||
// TODO(b/173451571): reduce burden of binder thread by enqueue request onto
|
impl.putDocument(packageName, databaseName, document,
|
||||||
// a separate thread.
|
/*logger=*/ null);
|
||||||
impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
|
resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
|
||||||
resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
|
} catch (Throwable t) {
|
||||||
} catch (Throwable t) {
|
resultBuilder.setResult(document.getUri(),
|
||||||
resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
|
throwableToFailedResult(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
invokeCallbackOnResult(callback, resultBuilder.build());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
invokeCallbackOnResult(callback, resultBuilder.build());
|
});
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -312,38 +323,36 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
|
AppSearchBatchResult.Builder<String, Bundle> resultBuilder =
|
||||||
new AppSearchBatchResult.Builder<>();
|
new AppSearchBatchResult.Builder<>();
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
for (int i = 0; i < uris.size(); i++) {
|
for (int i = 0; i < uris.size(); i++) {
|
||||||
String uri = uris.get(i);
|
String uri = uris.get(i);
|
||||||
try {
|
try {
|
||||||
GenericDocument document =
|
GenericDocument document =
|
||||||
impl.getDocument(
|
impl.getDocument(
|
||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
namespace,
|
namespace,
|
||||||
uri,
|
uri,
|
||||||
typePropertyPaths);
|
typePropertyPaths);
|
||||||
resultBuilder.setSuccess(uri, document.getBundle());
|
resultBuilder.setSuccess(uri, document.getBundle());
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
invokeCallbackOnResult(callback, resultBuilder.build());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
invokeCallbackOnResult(callback, resultBuilder.build());
|
});
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sidchhabra): Do this in a threadpool.
|
|
||||||
@Override
|
@Override
|
||||||
public void query(
|
public void query(
|
||||||
@NonNull String packageName,
|
@NonNull String packageName,
|
||||||
@@ -359,26 +368,25 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
impl.query(
|
impl.query(
|
||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle));
|
||||||
invokeCallbackOnResult(
|
invokeCallbackOnResult(
|
||||||
callback,
|
callback,
|
||||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
invokeCallbackOnError(callback, t);
|
invokeCallbackOnError(callback, t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -394,26 +402,25 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
SearchResultPage searchResultPage =
|
SearchResultPage searchResultPage =
|
||||||
impl.globalQuery(
|
impl.globalQuery(
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle),
|
new SearchSpec(searchSpecBundle),
|
||||||
packageName,
|
packageName,
|
||||||
callingUid);
|
callingUid);
|
||||||
invokeCallbackOnResult(
|
invokeCallbackOnResult(
|
||||||
callback,
|
callback,
|
||||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
invokeCallbackOnError(callback, t);
|
invokeCallbackOnError(callback, t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -424,39 +431,37 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
|
||||||
// TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
|
// TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
|
||||||
// opened it
|
// opened it
|
||||||
try {
|
EXECUTOR.execute(() -> {
|
||||||
verifyUserUnlocked(callingUserId);
|
try {
|
||||||
AppSearchImpl impl =
|
verifyUserUnlocked(callingUserId);
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
AppSearchImpl impl =
|
||||||
SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
invokeCallbackOnResult(
|
SearchResultPage searchResultPage = impl.getNextPage(nextPageToken);
|
||||||
callback,
|
invokeCallbackOnResult(
|
||||||
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
callback,
|
||||||
} catch (Throwable t) {
|
AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
|
||||||
invokeCallbackOnError(callback, t);
|
} catch (Throwable t) {
|
||||||
} finally {
|
invokeCallbackOnError(callback, t);
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
|
public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
impl.invalidateNextPageToken(nextPageToken);
|
impl.invalidateNextPageToken(nextPageToken);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Log.e(TAG, "Unable to invalidate the query page token", t);
|
Log.e(TAG, "Unable to invalidate the query page token", t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -470,34 +475,34 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
@NonNull IAppSearchResultCallback callback) {
|
@NonNull IAppSearchResultCallback callback) {
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
// we don't need to append the file. The file is always brand new.
|
// we don't need to append the file. The file is always brand new.
|
||||||
try (DataOutputStream outputStream = new DataOutputStream(
|
try (DataOutputStream outputStream = new DataOutputStream(
|
||||||
new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
|
new FileOutputStream(fileDescriptor.getFileDescriptor()))) {
|
||||||
SearchResultPage searchResultPage = impl.query(
|
SearchResultPage searchResultPage = impl.query(
|
||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle));
|
||||||
while (!searchResultPage.getResults().isEmpty()) {
|
while (!searchResultPage.getResults().isEmpty()) {
|
||||||
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
for (int i = 0; i < searchResultPage.getResults().size(); i++) {
|
||||||
AppSearchMigrationHelper.writeBundleToOutputStream(
|
AppSearchMigrationHelper.writeBundleToOutputStream(
|
||||||
outputStream, searchResultPage.getResults().get(i)
|
outputStream, searchResultPage.getResults().get(i)
|
||||||
.getGenericDocument().getBundle());
|
.getGenericDocument().getBundle());
|
||||||
|
}
|
||||||
|
searchResultPage = impl.getNextPage(
|
||||||
|
searchResultPage.getNextPageToken());
|
||||||
}
|
}
|
||||||
searchResultPage = impl.getNextPage(searchResultPage.getNextPageToken());
|
|
||||||
}
|
}
|
||||||
|
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
});
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -509,46 +514,46 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
@NonNull IAppSearchResultCallback callback) {
|
@NonNull IAppSearchResultCallback callback) {
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
|
|
||||||
GenericDocument document;
|
GenericDocument document;
|
||||||
ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
|
ArrayList<Bundle> migrationFailureBundles = new ArrayList<>();
|
||||||
try (DataInputStream inputStream = new DataInputStream(
|
try (DataInputStream inputStream = new DataInputStream(
|
||||||
new FileInputStream(fileDescriptor.getFileDescriptor()))) {
|
new FileInputStream(fileDescriptor.getFileDescriptor()))) {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
document = AppSearchMigrationHelper
|
document = AppSearchMigrationHelper
|
||||||
.readDocumentFromInputStream(inputStream);
|
.readDocumentFromInputStream(inputStream);
|
||||||
} catch (EOFException e) {
|
} catch (EOFException e) {
|
||||||
// nothing wrong, we just finish the reading.
|
// nothing wrong, we just finish the reading.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
|
impl.putDocument(packageName, databaseName, document,
|
||||||
} catch (Throwable t) {
|
/*logger=*/ null);
|
||||||
migrationFailureBundles.add(
|
} catch (Throwable t) {
|
||||||
new SetSchemaResponse.MigrationFailure.Builder()
|
migrationFailureBundles.add(
|
||||||
.setNamespace(document.getNamespace())
|
new SetSchemaResponse.MigrationFailure.Builder()
|
||||||
.setSchemaType(document.getSchemaType())
|
.setNamespace(document.getNamespace())
|
||||||
.setUri(document.getUri())
|
.setSchemaType(document.getSchemaType())
|
||||||
.setAppSearchResult(
|
.setUri(document.getUri())
|
||||||
AppSearchResult.throwableToFailedResult(t))
|
.setAppSearchResult(AppSearchResult
|
||||||
.build().getBundle());
|
.throwableToFailedResult(t))
|
||||||
|
.build().getBundle());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl.persistToDisk();
|
||||||
|
invokeCallbackOnResult(callback,
|
||||||
|
AppSearchResult.newSuccessfulResult(migrationFailureBundles));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
impl.persistToDisk();
|
});
|
||||||
invokeCallbackOnResult(callback,
|
|
||||||
AppSearchResult.newSuccessfulResult(migrationFailureBundles));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -567,26 +572,25 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Objects.requireNonNull(callback);
|
Objects.requireNonNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
|
|
||||||
if (systemUsage) {
|
if (systemUsage) {
|
||||||
// TODO(b/183031844): Validate that the call comes from the system
|
// TODO(b/183031844): Validate that the call comes from the system
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSearchImpl impl =
|
||||||
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
|
impl.reportUsage(
|
||||||
|
packageName, databaseName, namespace, uri,
|
||||||
|
usageTimeMillis, systemUsage);
|
||||||
|
invokeCallbackOnResult(
|
||||||
|
callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
AppSearchImpl impl =
|
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
|
||||||
impl.reportUsage(
|
|
||||||
packageName, databaseName, namespace, uri,
|
|
||||||
usageTimeMillis, systemUsage);
|
|
||||||
invokeCallbackOnResult(
|
|
||||||
callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
|
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -603,29 +607,28 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
AppSearchBatchResult.Builder<String, Void> resultBuilder =
|
||||||
new AppSearchBatchResult.Builder<>();
|
new AppSearchBatchResult.Builder<>();
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
for (int i = 0; i < uris.size(); i++) {
|
for (int i = 0; i < uris.size(); i++) {
|
||||||
String uri = uris.get(i);
|
String uri = uris.get(i);
|
||||||
try {
|
try {
|
||||||
impl.remove(packageName, databaseName, namespace, uri);
|
impl.remove(packageName, databaseName, namespace, uri);
|
||||||
resultBuilder.setSuccess(uri, /*result= */ null);
|
resultBuilder.setSuccess(uri, /*result= */ null);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
resultBuilder.setResult(uri, throwableToFailedResult(t));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
invokeCallbackOnResult(callback, resultBuilder.build());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
invokeCallbackOnError(callback, t);
|
||||||
}
|
}
|
||||||
invokeCallbackOnResult(callback, resultBuilder.build());
|
});
|
||||||
} catch (Throwable t) {
|
|
||||||
invokeCallbackOnError(callback, t);
|
|
||||||
} finally {
|
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -643,23 +646,22 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
impl.removeByQuery(
|
impl.removeByQuery(
|
||||||
packageName,
|
packageName,
|
||||||
databaseName,
|
databaseName,
|
||||||
queryExpression,
|
queryExpression,
|
||||||
new SearchSpec(searchSpecBundle));
|
new SearchSpec(searchSpecBundle));
|
||||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
invokeCallbackOnError(callback, t);
|
invokeCallbackOnError(callback, t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -673,38 +675,37 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
verifyCallingPackage(callingUid, packageName);
|
verifyCallingPackage(callingUid, packageName);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, databaseName);
|
StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
|
||||||
Bundle storageInfoBundle = storageInfo.getBundle();
|
databaseName);
|
||||||
invokeCallbackOnResult(
|
Bundle storageInfoBundle = storageInfo.getBundle();
|
||||||
callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
|
invokeCallbackOnResult(
|
||||||
} catch (Throwable t) {
|
callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
|
||||||
invokeCallbackOnError(callback, t);
|
} catch (Throwable t) {
|
||||||
} finally {
|
invokeCallbackOnError(callback, t);
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void persistToDisk(@UserIdInt int userId) {
|
public void persistToDisk(@UserIdInt int userId) {
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
AppSearchImpl impl =
|
AppSearchImpl impl =
|
||||||
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
mImplInstanceManager.getAppSearchImpl(callingUserId);
|
||||||
impl.persistToDisk();
|
impl.persistToDisk();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Log.e(TAG, "Unable to persist the data to disk", t);
|
Log.e(TAG, "Unable to persist the data to disk", t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -712,16 +713,15 @@ public class AppSearchManagerService extends SystemService {
|
|||||||
Preconditions.checkNotNull(callback);
|
Preconditions.checkNotNull(callback);
|
||||||
int callingUid = Binder.getCallingUid();
|
int callingUid = Binder.getCallingUid();
|
||||||
int callingUserId = handleIncomingUser(userId, callingUid);
|
int callingUserId = handleIncomingUser(userId, callingUid);
|
||||||
final long callingIdentity = Binder.clearCallingIdentity();
|
EXECUTOR.execute(() -> {
|
||||||
try {
|
try {
|
||||||
verifyUserUnlocked(callingUserId);
|
verifyUserUnlocked(callingUserId);
|
||||||
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId);
|
mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId);
|
||||||
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
invokeCallbackOnError(callback, t);
|
invokeCallbackOnError(callback, t);
|
||||||
} finally {
|
}
|
||||||
Binder.restoreCallingIdentity(callingIdentity);
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyUserUnlocked(int callingUserId) {
|
private void verifyUserUnlocked(int callingUserId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user