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

Commit 5ca6e32f authored by Shashank Mittal's avatar Shashank Mittal Committed by Steve Kondik
Browse files

LocationServiceManager: Fix deadlock due to updateMonitoring.

AppOps can be blocked if askOperation is called from main thread.
This causes location service manager to block while updating monitor
information of all location update receivers.

Fix AppOps to report all askOperation calls from main thread.
Also fix location service manager to handle MODE_ASK.

Change-Id: I085f01e992f60456ad24921bf4ce508ece54e8a6
parent d196beb2
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ import android.os.AsyncTask;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -88,6 +89,8 @@ public class AppOpsService extends IAppOpsService.Stub {
        AppOpsManager.OP_READ_SMS
    };

    Looper mLooper;

    boolean mWriteScheduled;
    final Runnable mWriteRunner = new Runnable() {
        public void run() {
@@ -215,6 +218,7 @@ public class AppOpsService extends IAppOpsService.Stub {
    public AppOpsService(File storagePath) {
        mStrictEnable = AppOpsManager.isStrictEnable();
        mFile = new AtomicFile(storagePath);
        mLooper = Looper.myLooper();
        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                switch (msg.what) {
@@ -655,6 +659,11 @@ public class AppOpsService extends IAppOpsService.Stub {
                op.allowedCount++;
                return AppOpsManager.MODE_ALLOWED;
            } else {
                if (Looper.myLooper() == mLooper) {
                    Log.e(TAG, "noteOperation: This method will deadlock if called from the main thread. (Code: "
                            + code + " uid: " + uid + " package: " + packageName + ")");
                    return switchOp.mode;
                }
                op.noteOpCount++;
                userDialogResult = askOperationLocked(code, uid, packageName,
                    switchOp);
@@ -701,6 +710,11 @@ public class AppOpsService extends IAppOpsService.Stub {
                }
                return AppOpsManager.MODE_ALLOWED;
            } else {
                if (Looper.myLooper() == mLooper) {
                    Log.e(TAG, "startOperation: This method will deadlock if called from the main thread. (Code: "
                            + code + " uid: " + uid + " package: " + packageName +")");
                    return switchOp.mode;
                }
                op.startOpCount++;
                IBinder clientToken = client.mAppToken;
                op.mClientTokens.add(clientToken);
+9 −3
Original line number Diff line number Diff line
@@ -648,8 +648,13 @@ public class LocationManagerService extends ILocationManager.Stub {
                            == AppOpsManager.MODE_ALLOWED;
                }
            } else {
                if (!allowMonitoring || mAppOps.checkOpNoThrow(op, mUid, mPackageName)
                        != AppOpsManager.MODE_ALLOWED) {
                int mode =  mAppOps.checkOpNoThrow(op, mUid, mPackageName);

                if(allowMonitoring && mode == AppOpsManager.MODE_ASK) {
                    return true;
                }

                if (!allowMonitoring || mode != AppOpsManager.MODE_ALLOWED) {
                    mAppOps.finishOp(op, mUid, mPackageName);
                    return false;
                }
@@ -1051,7 +1056,8 @@ public class LocationManagerService extends ILocationManager.Stub {
    boolean checkLocationAccess(int uid, String packageName, int allowedResolutionLevel) {
        int op = resolutionLevelToOp(allowedResolutionLevel);
        if (op >= 0) {
            if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) {
            int mode = mAppOps.checkOp(op, uid, packageName);
            if (mode != AppOpsManager.MODE_ALLOWED && mode != AppOpsManager.MODE_ASK ) {
                return false;
            }
        }