summaryrefslogtreecommitdiff
path: root/services/appfunctions/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/appfunctions/java')
-rw-r--r--services/appfunctions/java/com/android/server/appfunctions/AppFunctionManagerServiceImpl.java32
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;