Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 542d7729 authored by Gabriele M's avatar Gabriele M Committed by Michael W
Browse files

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
parent eed0399e
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.am.ActivityManagerService;
import com.android.server.PermissionDialogReqQueue.PermissionDialogReq;

import libcore.util.EmptyArray;
@@ -109,6 +110,7 @@ public class AppOpsService extends IAppOpsService.Stub {
    final boolean mStrictEnable;
    AppOpsPolicy mPolicy;
    private boolean mIsInteractive = true;
    private final ActivityManagerService mActivityManagerService;

    boolean mWriteScheduled;
    boolean mFastWriteScheduled;
@@ -282,12 +284,13 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    }

    public AppOpsService(File storagePath, Handler handler) {
    public AppOpsService(File storagePath, Handler handler, ActivityManagerService service) {
        LockGuard.installLock(this, LockGuard.INDEX_APP_OPS);
        mFile = new AtomicFile(storagePath);
        mHandler = handler;
        mLooper = Looper.myLooper();
        mStrictEnable = AppOpsManager.isStrictEnable();
        mActivityManagerService = service;
        readState();
    }

@@ -1287,7 +1290,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                    op.ignoredCount++;
                    return switchOp.mode;
                } else if (switchOp.mode == AppOpsManager.MODE_ASK) {
                    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
@@ -1424,7 +1427,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
+6 −4
Original line number Diff line number Diff line
@@ -2745,7 +2745,7 @@ public class ActivityManagerService extends IActivityManager.Stub
        GL_ES_VERSION = 0;
        mActivityStarter = null;
        mAppErrors = null;
        mAppOpsService = mInjector.getAppOpsService(null, null);
        mAppOpsService = mInjector.getAppOpsService(null, null, this);
        mBatteryStatsService = null;
        mCompatModePackages = null;
        mConstants = null;
@@ -2824,7 +2824,8 @@ public class ActivityManagerService extends IActivityManager.Stub
        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler);
        mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler,
                this);
        mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
                new IAppOpsCallback.Stub() {
                    @Override public void opChanged(int op, int uid, String packageName) {
@@ -24709,8 +24710,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            return null;
        }
        public AppOpsService getAppOpsService(File file, Handler handler) {
            return new AppOpsService(file, handler);
        public AppOpsService getAppOpsService(File file, Handler handler,
                                              ActivityManagerService service) {
            return new AppOpsService(file, handler, service);
        }
        public Handler getUiHandler(ActivityManagerService service) {