Merge "Add background executor to AppSearchManagerService." into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-07 22:10:30 +00:00
committed by Android (Google) Code Review

View File

@@ -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) {