From 40b300fd80708fd100d22f22ff6100db20ee467f Mon Sep 17 00:00:00 2001 From: riddle_hsu Date: Mon, 23 Nov 2015 13:22:03 +0800 Subject: [PATCH] Fix race condition when collecting op callback. Other threads may change mOpModeWatchers, mPackageModeWatchers by startWatchingMode, stopWatchingMode. Change-Id: Id260172979ddfc2df9331880805d16ee13e183eb --- .../java/com/android/server/AppOpsService.java | 48 +++++++++++----------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index c373fb8933cd..8eb01833d484 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -513,33 +513,35 @@ public class AppOpsService extends IAppOpsService.Stub { String[] uidPackageNames = getPackagesForUid(uid); ArrayMap> callbackSpecs = null; - ArrayList callbacks = mOpModeWatchers.get(code); - if (callbacks != null) { - final int callbackCount = callbacks.size(); - for (int i = 0; i < callbackCount; i++) { - Callback callback = callbacks.get(i); - ArraySet changedPackages = new ArraySet<>(); - Collections.addAll(changedPackages, uidPackageNames); - callbackSpecs = new ArrayMap<>(); - callbackSpecs.put(callback, changedPackages); - } - } - - for (String uidPackageName : uidPackageNames) { - callbacks = mPackageModeWatchers.get(uidPackageName); + synchronized (this) { + ArrayList callbacks = mOpModeWatchers.get(code); if (callbacks != null) { - if (callbackSpecs == null) { - callbackSpecs = new ArrayMap<>(); - } final int callbackCount = callbacks.size(); for (int i = 0; i < callbackCount; i++) { Callback callback = callbacks.get(i); - ArraySet changedPackages = callbackSpecs.get(callback); - if (changedPackages == null) { - changedPackages = new ArraySet<>(); - callbackSpecs.put(callback, changedPackages); + ArraySet changedPackages = new ArraySet<>(); + Collections.addAll(changedPackages, uidPackageNames); + callbackSpecs = new ArrayMap<>(); + callbackSpecs.put(callback, changedPackages); + } + } + + for (String uidPackageName : uidPackageNames) { + callbacks = mPackageModeWatchers.get(uidPackageName); + if (callbacks != null) { + if (callbackSpecs == null) { + callbackSpecs = new ArrayMap<>(); + } + final int callbackCount = callbacks.size(); + for (int i = 0; i < callbackCount; i++) { + Callback callback = callbacks.get(i); + ArraySet changedPackages = callbackSpecs.get(callback); + if (changedPackages == null) { + changedPackages = new ArraySet<>(); + callbackSpecs.put(callback, changedPackages); + } + changedPackages.add(uidPackageName); } - changedPackages.add(uidPackageName); } } } @@ -1773,7 +1775,7 @@ public class AppOpsService extends IAppOpsService.Stub { private static String[] getPackagesForUid(int uid) { String[] packageNames = null; try { - packageNames= AppGlobals.getPackageManager().getPackagesForUid(uid); + packageNames = AppGlobals.getPackageManager().getPackagesForUid(uid); } catch (RemoteException e) { /* ignore - local call */ } -- 2.11.0