summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGabriele M <moto.falcon.git@gmail.com>2017-07-25 18:47:06 +0200
committerGabriele M <moto.falcon.git@gmail.com>2017-09-03 11:44:01 +0000
commit0ef6da6baee73c4e951fb43c1afd7e07f8223cc5 (patch)
tree0c9cbddc35343d33630d16d690c64e47c8fe65f4
parentf579e002869f3d066b848eb5525bba0dd76f92a1 (diff)
downloadframeworks_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.java9
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java2
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"));