Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b2b415d0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 1cbf9f39 97844f31
Loading
Loading
Loading
Loading
+330 −330
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
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 */
public class AppSearchManagerService extends SystemService {
@@ -77,6 +81,14 @@ public class AppSearchManagerService extends SystemService {
    private ImplInstanceManager mImplInstanceManager;
    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
    // "locked" suffix refers to the fact that access to the field should be locked; unrelated to
    // the unlocked status of user ids.
@@ -166,7 +178,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -181,7 +193,8 @@ public class AppSearchManagerService extends SystemService {
                        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)));
                            packageIdentifiers.add(
                                    new PackageIdentifier(entry.getValue().get(i)));
                        }
                        schemasPackageAccessible.put(entry.getKey(), packageIdentifiers);
                    }
@@ -198,9 +211,8 @@ public class AppSearchManagerService extends SystemService {
                            AppSearchResult.newSuccessfulResult(setSchemaResponse.getBundle()));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -214,7 +226,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -222,12 +234,12 @@ public class AppSearchManagerService extends SystemService {
                            mImplInstanceManager.getAppSearchImpl(callingUserId);
                    GetSchemaResponse response = impl.getSchema(packageName, databaseName);
                    invokeCallbackOnResult(
                        callback, AppSearchResult.newSuccessfulResult(response.getBundle()));
                            callback,
                            AppSearchResult.newSuccessfulResult(response.getBundle()));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -241,19 +253,19 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
                    AppSearchImpl impl =
                            mImplInstanceManager.getAppSearchImpl(callingUserId);
                    List<String> namespaces = impl.getNamespaces(packageName, databaseName);
                invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(namespaces));
                    invokeCallbackOnResult(callback,
                            AppSearchResult.newSuccessfulResult(namespaces));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -269,7 +281,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -280,20 +292,19 @@ public class AppSearchManagerService extends SystemService {
                    for (int i = 0; i < documentBundles.size(); i++) {
                        GenericDocument document = new GenericDocument(documentBundles.get(i));
                        try {
                        // TODO(b/173451571): reduce burden of binder thread by enqueue request onto
                        // a separate thread.
                        impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
                            impl.putDocument(packageName, databaseName, document,
                                    /*logger=*/ null);
                            resultBuilder.setSuccess(document.getUri(), /*result=*/ null);
                        } catch (Throwable t) {
                        resultBuilder.setResult(document.getUri(), throwableToFailedResult(t));
                            resultBuilder.setResult(document.getUri(),
                                    throwableToFailedResult(t));
                        }
                    }
                    invokeCallbackOnResult(callback, resultBuilder.build());
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -312,7 +323,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -338,12 +349,10 @@ public class AppSearchManagerService extends SystemService {
                    invokeCallbackOnResult(callback, resultBuilder.build());
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        // TODO(sidchhabra): Do this in a threadpool.
        @Override
        public void query(
                @NonNull String packageName,
@@ -359,7 +368,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -376,9 +385,8 @@ public class AppSearchManagerService extends SystemService {
                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -394,7 +402,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -411,9 +419,8 @@ public class AppSearchManagerService extends SystemService {
                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
                }  catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -424,9 +431,9 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            // TODO(b/162450968) check nextPageToken is being advanced by the same uid as originally
            // opened it
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    AppSearchImpl impl =
@@ -437,16 +444,15 @@ public class AppSearchManagerService extends SystemService {
                            AppSearchResult.newSuccessfulResult(searchResultPage.getBundle()));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
        public void invalidateNextPageToken(long nextPageToken, @UserIdInt int userId) {
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    AppSearchImpl impl =
@@ -454,9 +460,8 @@ public class AppSearchManagerService extends SystemService {
                    impl.invalidateNextPageToken(nextPageToken);
                } catch (Throwable t) {
                    Log.e(TAG, "Unable to invalidate the query page token", t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -470,7 +475,7 @@ public class AppSearchManagerService extends SystemService {
                @NonNull IAppSearchResultCallback callback) {
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyCallingPackage(callingUid, packageName);
                    AppSearchImpl impl =
@@ -489,15 +494,15 @@ public class AppSearchManagerService extends SystemService {
                                        outputStream, searchResultPage.getResults().get(i)
                                                .getGenericDocument().getBundle());
                            }
                        searchResultPage = impl.getNextPage(searchResultPage.getNextPageToken());
                            searchResultPage = impl.getNextPage(
                                    searchResultPage.getNextPageToken());
                        }
                    }
                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -509,7 +514,7 @@ public class AppSearchManagerService extends SystemService {
                @NonNull IAppSearchResultCallback callback) {
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyCallingPackage(callingUid, packageName);
                    AppSearchImpl impl =
@@ -528,15 +533,16 @@ public class AppSearchManagerService extends SystemService {
                                break;
                            }
                            try {
                            impl.putDocument(packageName, databaseName, document, /*logger=*/ null);
                                impl.putDocument(packageName, databaseName, document,
                                        /*logger=*/ null);
                            } catch (Throwable t) {
                                migrationFailureBundles.add(
                                        new SetSchemaResponse.MigrationFailure.Builder()
                                                .setNamespace(document.getNamespace())
                                                .setSchemaType(document.getSchemaType())
                                                .setUri(document.getUri())
                                            .setAppSearchResult(
                                                    AppSearchResult.throwableToFailedResult(t))
                                                .setAppSearchResult(AppSearchResult
                                                        .throwableToFailedResult(t))
                                                .build().getBundle());
                            }
                        }
@@ -546,9 +552,8 @@ public class AppSearchManagerService extends SystemService {
                            AppSearchResult.newSuccessfulResult(migrationFailureBundles));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -567,7 +572,7 @@ public class AppSearchManagerService extends SystemService {
            Objects.requireNonNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);

@@ -584,9 +589,8 @@ public class AppSearchManagerService extends SystemService {
                            callback, AppSearchResult.newSuccessfulResult(/*result=*/ null));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -603,7 +607,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -623,9 +627,8 @@ public class AppSearchManagerService extends SystemService {
                    invokeCallbackOnResult(callback, resultBuilder.build());
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -643,7 +646,7 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
@@ -657,9 +660,8 @@ public class AppSearchManagerService extends SystemService {
                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -673,28 +675,28 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    verifyCallingPackage(callingUid, packageName);
                    AppSearchImpl impl =
                            mImplInstanceManager.getAppSearchImpl(callingUserId);
                StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName, databaseName);
                    StorageInfo storageInfo = impl.getStorageInfoForDatabase(packageName,
                            databaseName);
                    Bundle storageInfoBundle = storageInfo.getBundle();
                    invokeCallbackOnResult(
                            callback, AppSearchResult.newSuccessfulResult(storageInfoBundle));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
        public void persistToDisk(@UserIdInt int userId) {
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    AppSearchImpl impl =
@@ -702,9 +704,8 @@ public class AppSearchManagerService extends SystemService {
                    impl.persistToDisk();
                } catch (Throwable t) {
                    Log.e(TAG, "Unable to persist the data to disk", t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        @Override
@@ -712,16 +713,15 @@ public class AppSearchManagerService extends SystemService {
            Preconditions.checkNotNull(callback);
            int callingUid = Binder.getCallingUid();
            int callingUserId = handleIncomingUser(userId, callingUid);
            final long callingIdentity = Binder.clearCallingIdentity();
            EXECUTOR.execute(() -> {
                try {
                    verifyUserUnlocked(callingUserId);
                    mImplInstanceManager.getOrCreateAppSearchImpl(mContext, callingUserId);
                    invokeCallbackOnResult(callback, AppSearchResult.newSuccessfulResult(null));
                } catch (Throwable t) {
                    invokeCallbackOnError(callback, t);
            } finally {
                Binder.restoreCallingIdentity(callingIdentity);
                }
            });
        }

        private void verifyUserUnlocked(int callingUserId) {