diff options
Diffstat (limited to 'services/appfunctions/java')
4 files changed, 36 insertions, 72 deletions
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java index 1f98334bb8ce..c3b7087a44c3 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionExecutors.java @@ -16,15 +16,7 @@ package com.android.server.appfunctions; -import android.annotation.NonNull; -import android.os.UserHandle; -import android.util.SparseArray; - -import com.android.internal.annotations.GuardedBy; - import java.util.concurrent.Executor; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; @@ -41,50 +33,5 @@ public final class AppFunctionExecutors { /* unit= */ TimeUnit.SECONDS, /* workQueue= */ new LinkedBlockingQueue<>()); - /** A map of per-user executors for queued work. */ - @GuardedBy("sLock") - private static final SparseArray<ExecutorService> mPerUserExecutorsLocked = new SparseArray<>(); - - private static final Object sLock = new Object(); - - /** - * Returns a per-user executor for queued metadata sync request. - * - * <p>The work submitted to these executor (Sync request) needs to be synchronous per user hence - * the use of a single thread. - * - * <p>Note: Use a different executor if not calling {@code submitSyncRequest} on a {@code - * MetadataSyncAdapter}. - */ - // TODO(b/357551503): Restrict the scope of this executor to the MetadataSyncAdapter itself. - public static ExecutorService getPerUserSyncExecutor(@NonNull UserHandle user) { - synchronized (sLock) { - ExecutorService executor = mPerUserExecutorsLocked.get(user.getIdentifier(), null); - if (executor == null) { - executor = Executors.newSingleThreadExecutor(); - mPerUserExecutorsLocked.put(user.getIdentifier(), executor); - } - return executor; - } - } - - /** - * Shuts down and removes the per-user executor for queued work. - * - * <p>This should be called when the user is removed. - */ - public static void shutDownAndRemoveUserExecutor(@NonNull UserHandle user) - throws InterruptedException { - ExecutorService executor; - synchronized (sLock) { - executor = mPerUserExecutorsLocked.get(user.getIdentifier()); - mPerUserExecutorsLocked.remove(user.getIdentifier()); - } - if (executor != null) { - executor.shutdown(); - var unused = executor.awaitTermination(30, TimeUnit.SECONDS); - } - } - private AppFunctionExecutors() {} } diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java index b4713d9f11af..1e723b5a1da2 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java @@ -95,12 +95,7 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { public void onUserStopping(@NonNull TargetUser user) { Objects.requireNonNull(user); - try { - AppFunctionExecutors.shutDownAndRemoveUserExecutor(user.getUserHandle()); - MetadataSyncPerUser.removeUserSyncAdapter(user.getUserHandle()); - } catch (InterruptedException e) { - Slog.e(TAG, "Unable to remove data for: " + user.getUserHandle(), e); - } + MetadataSyncPerUser.removeUserSyncAdapter(user.getUserHandle()); } @Override diff --git a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java index e29b6e403f2a..d84b20556053 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java +++ b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncAdapter.java @@ -42,6 +42,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Slog; +import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.infra.AndroidFuture; import com.android.server.appfunctions.FutureAppSearchSession.FutureSearchResults; @@ -53,7 +54,9 @@ import java.util.List; import java.util.Objects; import java.util.Set; import java.util.concurrent.ExecutionException; -import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; /** * This class implements helper methods for synchronously interacting with AppSearch while @@ -63,9 +66,15 @@ import java.util.concurrent.Executor; */ public class MetadataSyncAdapter { private static final String TAG = MetadataSyncAdapter.class.getSimpleName(); - private final Executor mSyncExecutor; + + private final ExecutorService mExecutor; + private final AppSearchManager mAppSearchManager; private final PackageManager mPackageManager; + private final Object mLock = new Object(); + + @GuardedBy("mLock") + private Future<?> mCurrentSyncTask; // Hidden constants in {@link SetSchemaRequest} that restricts runtime metadata visibility // by permissions. @@ -73,12 +82,10 @@ public class MetadataSyncAdapter { public static final int EXECUTE_APP_FUNCTIONS_TRUSTED = 10; public MetadataSyncAdapter( - @NonNull Executor syncExecutor, - @NonNull PackageManager packageManager, - @NonNull AppSearchManager appSearchManager) { - mSyncExecutor = Objects.requireNonNull(syncExecutor); + @NonNull PackageManager packageManager, @NonNull AppSearchManager appSearchManager) { mPackageManager = Objects.requireNonNull(packageManager); mAppSearchManager = Objects.requireNonNull(appSearchManager); + mExecutor = Executors.newSingleThreadExecutor(); } /** @@ -97,7 +104,7 @@ public class MetadataSyncAdapter { AppFunctionRuntimeMetadata.APP_FUNCTION_RUNTIME_METADATA_DB) .build(); AndroidFuture<Boolean> settableSyncStatus = new AndroidFuture<>(); - mSyncExecutor.execute( + Runnable runnable = () -> { try (FutureAppSearchSession staticMetadataSearchSession = new FutureAppSearchSessionImpl( @@ -117,10 +124,23 @@ public class MetadataSyncAdapter { } catch (Exception ex) { settableSyncStatus.completeExceptionally(ex); } - }); + }; + + synchronized (mLock) { + if (mCurrentSyncTask != null && !mCurrentSyncTask.isDone()) { + var unused = mCurrentSyncTask.cancel(false); + } + mCurrentSyncTask = mExecutor.submit(runnable); + } + return settableSyncStatus; } + /** This method shuts down the {@link MetadataSyncAdapter} scheduler. */ + public void shutDown() { + mExecutor.shutdown(); + } + @WorkerThread @VisibleForTesting void trySyncAppFunctionMetadataBlocking( diff --git a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncPerUser.java b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncPerUser.java index f421527e72d0..e933ec1ba4b1 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncPerUser.java +++ b/services/appfunctions/java/com/android/server/appfunctions/MetadataSyncPerUser.java @@ -55,10 +55,7 @@ public final class MetadataSyncPerUser { PackageManager perUserPackageManager = userContext.getPackageManager(); if (perUserAppSearchManager != null) { metadataSyncAdapter = - new MetadataSyncAdapter( - AppFunctionExecutors.getPerUserSyncExecutor(user), - perUserPackageManager, - perUserAppSearchManager); + new MetadataSyncAdapter(perUserPackageManager, perUserAppSearchManager); sPerUserMetadataSyncAdapter.put(user.getIdentifier(), metadataSyncAdapter); return metadataSyncAdapter; } @@ -74,7 +71,12 @@ public final class MetadataSyncPerUser { */ public static void removeUserSyncAdapter(UserHandle user) { synchronized (sLock) { - sPerUserMetadataSyncAdapter.remove(user.getIdentifier()); + MetadataSyncAdapter metadataSyncAdapter = + sPerUserMetadataSyncAdapter.get(user.getIdentifier(), null); + if (metadataSyncAdapter != null) { + metadataSyncAdapter.shutDown(); + sPerUserMetadataSyncAdapter.remove(user.getIdentifier()); + } } } } |