diff options
author | 2024-10-16 19:10:05 +0000 | |
---|---|---|
committer | 2024-10-16 19:10:05 +0000 | |
commit | 2dfe0bdfdc810fc34f8b10d45583756f36f958c2 (patch) | |
tree | 1667ab5f9dca671670c29add83c8d4ff13dfcf15 /services/appfunctions/java | |
parent | 913b4f1bd2c07dac5282899d192fe30e31c6bd61 (diff) | |
parent | 6fe30c4440a9702adec10e7fcc70c1e10f97c484 (diff) |
Merge "Add per-package lock in setAppFunctionEnabled." into main
Diffstat (limited to 'services/appfunctions/java')
-rw-r--r-- | services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java index 28e57775523b..89f14b09d397 100644 --- a/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java +++ b/services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java @@ -68,7 +68,10 @@ import com.android.server.SystemService.TargetUser; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.util.Collections; +import java.util.Map; import java.util.Objects; +import java.util.WeakHashMap; import java.util.concurrent.CompletionException; import java.util.concurrent.Executor; @@ -81,7 +84,8 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { private final ServiceHelper mInternalServiceHelper; private final ServiceConfig mServiceConfig; private final Context mContext; - private final Object mLock = new Object(); + private final Map<String, Object> mLocks = new WeakHashMap<>(); + public AppFunctionManagerServiceImpl(@NonNull Context context) { this( @@ -316,9 +320,7 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { THREAD_POOL_EXECUTOR.execute( () -> { try { - // TODO(357551503): Instead of holding a global lock, hold a per-package - // lock. - synchronized (mLock) { + synchronized (getLockForPackage(callingPackage)) { setAppFunctionEnabledInternalLocked( callingPackage, functionIdentifier, userHandle, enabledState); } @@ -346,7 +348,7 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { * process. */ @WorkerThread - @GuardedBy("mLock") + @GuardedBy("getLockForPackage(callingPackage)") private void setAppFunctionEnabledInternalLocked( @NonNull String callingPackage, @NonNull String functionIdentifier, @@ -541,6 +543,26 @@ public class AppFunctionManagerServiceImpl extends IAppFunctionManager.Stub { }); } } + /** + * Retrieves the lock object associated with the given package name. + * + * This method returns the lock object from the {@code mLocks} map if it exists. + * If no lock is found for the given package name, a new lock object is created, + * stored in the map, and returned. + */ + @VisibleForTesting + @NonNull + Object getLockForPackage(String callingPackage) { + // Synchronized the access to mLocks to prevent race condition. + synchronized (mLocks) { + // By using a WeakHashMap, we allow the garbage collector to reclaim memory by removing + // entries associated with unused callingPackage keys. Therefore, we remove the null + // values before getting/computing a new value. The goal is to not let the size of this + // map grow without an upper bound. + mLocks.values().removeAll(Collections.singleton(null)); // Remove null values + return mLocks.computeIfAbsent(callingPackage, k -> new Object()); + } + } private static class AppFunctionMetadataObserver implements ObserverCallback { @Nullable private final MetadataSyncAdapter mPerUserMetadataSyncAdapter; |