diff options
author | Gabriele M <moto.falcon.git@gmail.com> | 2017-07-25 18:47:06 +0200 |
---|---|---|
committer | Gabriele M <moto.falcon.git@gmail.com> | 2017-09-03 11:44:01 +0000 |
commit | 0ef6da6baee73c4e951fb43c1afd7e07f8223cc5 (patch) | |
tree | 0c9cbddc35343d33630d16d690c64e47c8fe65f4 | |
parent | f579e002869f3d066b848eb5525bba0dd76f92a1 (diff) | |
download | frameworks_base-0ef6da6baee73c4e951fb43c1afd7e07f8223cc5.tar.gz frameworks_base-0ef6da6baee73c4e951fb43c1afd7e07f8223cc5.tar.bz2 frameworks_base-0ef6da6baee73c4e951fb43c1afd7e07f8223cc5.zip |
AppOps: Prevent deadlock when making note of applications
If noteOperation() is called with ActivityManagerService locked,
AppOpsService won't be able to show the PermissionDialog, causing
noteOperation() to wait indefinitely. Keep a reference to the
current ActivityManagerService instance so that we can check
whether showing the PermissionDialog is safe or not.
Even though there's currently no code path that causes startOperation()
to be called with ActivityManagerService locked, add the same check
there to prevent the same from happening in future.
BUGBASH-17
Change-Id: I118aac6ddf91774a038d73047162cfdb8395e58d
-rw-r--r-- | services/core/java/com/android/server/AppOpsService.java | 9 | ||||
-rwxr-xr-x | services/core/java/com/android/server/am/ActivityManagerService.java | 2 |
2 files changed, 7 insertions, 4 deletions
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index b205d24fb90..f599250e433 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -76,6 +76,7 @@ import com.android.internal.os.Zygote; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; +import com.android.server.am.ActivityManagerService; import com.android.server.PermissionDialogReqQueue.PermissionDialogReq; import libcore.util.EmptyArray; @@ -100,6 +101,7 @@ public class AppOpsService extends IAppOpsService.Stub { final boolean mStrictEnable; AppOpsPolicy mPolicy; private PowerManager mPowerManager; + private final ActivityManagerService mActivityManagerService; private static final int[] PRIVACY_GUARD_OP_STATES = new int[] { AppOpsManager.OP_COARSE_LOCATION, @@ -278,11 +280,12 @@ public class AppOpsService extends IAppOpsService.Stub { } } - public AppOpsService(File storagePath, Handler handler) { + public AppOpsService(File storagePath, Handler handler, ActivityManagerService service) { mFile = new AtomicFile(storagePath); mHandler = handler; mLooper = Looper.myLooper(); mStrictEnable = AppOpsManager.isStrictEnable(); + mActivityManagerService = service; readState(); } @@ -1097,7 +1100,7 @@ public class AppOpsService extends IAppOpsService.Stub { return AppOpsManager.MODE_ALLOWED; } else { - if (Looper.myLooper() == mLooper) { + if (Looper.myLooper() == mLooper || Thread.holdsLock(mActivityManagerService)) { Log.e(TAG, "noteOperation: This method will deadlock if called from the main thread. (Code: " + code @@ -1217,7 +1220,7 @@ public class AppOpsService extends IAppOpsService.Stub { broadcastOpIfNeeded(code); return AppOpsManager.MODE_ALLOWED; } else { - if (Looper.myLooper() == mLooper) { + if (Looper.myLooper() == mLooper || Thread.holdsLock(mActivityManagerService)) { Log.e(TAG, "startOperation: This method will deadlock if called from the main thread. (Code: " + code diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 37156204e30..6c076d06f21 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2561,7 +2561,7 @@ public final class ActivityManagerService extends ActivityManagerNative mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); - mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); + mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler, this); mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); |