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

Commit 556cf9a5 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix deadlock in app op listeners."

parents 55d7feeb c3f20ed7
Loading
Loading
Loading
Loading
+48 −42
Original line number Diff line number Diff line
@@ -932,53 +932,17 @@ public class AppOpsService extends IAppOpsService.Stub {
                new AppOpsCheckingServiceInterface.AppOpsModeChangedListener() {
                    @Override
                    public void onUidModeChanged(int uid, int code, int mode) {
                        notifyOpChangedForAllPkgsInUid(code, uid, false);
                        mHandler.sendMessage(PooledLambda.obtainMessage(
                                AppOpsService::notifyOpChangedForAllPkgsInUid, AppOpsService.this,
                                code, uid, false));
                    }

                    @Override
                    public void onPackageModeChanged(String packageName, int userId, int code,
                            int mode) {
                        ArraySet<OnOpModeChangedListener> repCbs = null;
                        int uid = -1;
                        synchronized (AppOpsService.this) {
                            ArraySet<OnOpModeChangedListener> cbs =
                                    mOpModeWatchers.get(code);
                            if (cbs != null) {
                                if (repCbs == null) {
                                    repCbs = new ArraySet<>();
                                }
                                repCbs.addAll(cbs);
                            }
                            cbs = mPackageModeWatchers.get(packageName);
                            if (cbs != null) {
                                if (repCbs == null) {
                                    repCbs = new ArraySet<>();
                                }
                                repCbs.addAll(cbs);
                            }
                            if (repCbs != null && mIgnoredCallback != null) {
                                repCbs.remove(mModeWatchers.get(mIgnoredCallback.asBinder()));
                            }
                            uid = getPackageManagerInternal().getPackageUid(packageName,
                                    PackageManager.MATCH_KNOWN_PACKAGES, userId);
                            Op op = getOpLocked(code, uid, packageName, null, false, null,
                                    /* edit */ false);
                            if (op != null && mode == AppOpsManager.opToDefaultMode(op.op)) {
                                // If going into the default mode, prune this op
                                // if there is nothing else interesting in it.
                                pruneOpLocked(op, uid, packageName);
                            }
                            scheduleFastWriteLocked();
                            if (mode != MODE_ERRORED) {
                                updateStartedOpModeForUidLocked(code, mode == MODE_IGNORED, uid);
                            }
                        }

                        if (repCbs != null && uid != -1) {
                        mHandler.sendMessage(PooledLambda.obtainMessage(
                                    AppOpsService::notifyOpChanged,
                                    AppOpsService.this, repCbs, code, uid, packageName));
                        }
                                AppOpsService::notifyOpChangedForPkg, AppOpsService.this,
                                packageName, code, mode, userId));
                    }
                });
        //mAppOpsCheckingService = new AppOpsCheckingServiceLoggingDecorator(
@@ -1994,6 +1958,48 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    }

    private void notifyOpChangedForPkg(@NonNull String packageName, int code, int mode,
            @UserIdInt int userId) {
        ArraySet<OnOpModeChangedListener> repCbs = null;
        int uid = -1;
        synchronized (AppOpsService.this) {
            ArraySet<OnOpModeChangedListener> cbs = mOpModeWatchers.get(code);
            if (cbs != null) {
                if (repCbs == null) {
                    repCbs = new ArraySet<>();
                }
                repCbs.addAll(cbs);
            }
            cbs = mPackageModeWatchers.get(packageName);
            if (cbs != null) {
                if (repCbs == null) {
                    repCbs = new ArraySet<>();
                }
                repCbs.addAll(cbs);
            }
            if (repCbs != null && mIgnoredCallback != null) {
                repCbs.remove(mModeWatchers.get(mIgnoredCallback.asBinder()));
            }
            uid = getPackageManagerInternal().getPackageUid(packageName,
                    PackageManager.MATCH_KNOWN_PACKAGES, userId);
            Op op = getOpLocked(code, uid, packageName, null, false, null, /* edit */ false);
            if (op != null && mode == AppOpsManager.opToDefaultMode(op.op)) {
                // If going into the default mode, prune this op
                // if there is nothing else interesting in it.
                pruneOpLocked(op, uid, packageName);
            }
            scheduleFastWriteLocked();
            if (mode != MODE_ERRORED) {
                updateStartedOpModeForUidLocked(code, mode == MODE_IGNORED, uid);
            }
        }

        if (repCbs != null && uid != -1) {
            mHandler.sendMessage(PooledLambda.obtainMessage(AppOpsService::notifyOpChanged, this,
                    repCbs, code, uid, packageName));
        }
    }

    private void updatePermissionRevokedCompat(int uid, int switchCode, int mode) {
        PackageManager packageManager = mContext.getPackageManager();
        if (packageManager == null) {
+23 −4
Original line number Diff line number Diff line
@@ -43,23 +43,42 @@ import com.android.server.permission.access.util.tagName

class AppIdPermissionPersistence {
    fun BinaryXmlPullParser.parseSystemState(state: MutableAccessState) {
        val systemState = state.mutateSystemState(WriteMode.NONE)
        when (tagName) {
            TAG_PERMISSION_TREES -> parsePermissions(systemState.mutatePermissionTrees())
            TAG_PERMISSIONS -> parsePermissions(systemState.mutatePermissions())
            TAG_PERMISSION_TREES -> parsePermissions(state, true)
            TAG_PERMISSIONS -> parsePermissions(state, false)
            else -> {}
        }
    }

    private fun BinaryXmlPullParser.parsePermissions(
        permissions: MutableIndexedMap<String, Permission>
        state: MutableAccessState,
        isPermissionTree: Boolean
    ) {
        val systemState = state.mutateSystemState(WriteMode.NONE)
        val permissions = if (isPermissionTree) {
            systemState.mutatePermissionTrees()
        } else {
            systemState.mutatePermissions()
        }
        forEachTag {
            when (val tagName = tagName) {
                TAG_PERMISSION -> parsePermission(permissions)
                else -> Log.w(LOG_TAG, "Ignoring unknown tag $tagName when parsing permissions")
            }
        }
        permissions.forEachReversedIndexed { permissionIndex, _, permission ->
            val packageName = permission.packageName
            val externalState = state.externalState
            if (packageName !in externalState.packageStates &&
                packageName !in externalState.disabledSystemPackageStates) {
                Log.w(
                    LOG_TAG,
                    "Dropping permission with unknown package $packageName when parsing permissions"
                )
                permissions.removeAt(permissionIndex)
                systemState.requestWriteMode(WriteMode.ASYNCHRONOUS)
            }
        }
    }

    private fun BinaryXmlPullParser.parsePermission(
+25 −6
Original line number Diff line number Diff line
@@ -1815,18 +1815,36 @@ class PermissionService(
        withIndent {
            state.systemState.permissions.forEachIndexed { _, _, permission ->
                val protectionLevel = PermissionInfo.protectionToString(permission.protectionLevel)
                println("${permission.name}: appId=${permission.appId}, " +
                println(
                    "${permission.name}: " +
                        "type=${Permission.typeToString(permission.type)}, " +
                        "packageName=${permission.packageName}, " +
                        "appId=${permission.appId}, " +
                        "gids=${permission.gids.contentToString()}, " +
                    "protection=[$protectionLevel], " +
                        "protectionLevel=[$protectionLevel], " +
                        "flags=${PermissionInfo.flagsToString(permission.permissionInfo.flags)}"
                )
            }
        }

        println("Permission groups:")
        withIndent {
            state.systemState.permissionGroups.forEachIndexed { _, _, permissionGroup ->
                println(
                    "${permissionGroup.name}: " +
                        "packageName=${permissionGroup.packageName}"
                )
            }
        }

        println("Permission trees:")
        withIndent {
            state.systemState.permissionTrees.forEachIndexed { _, _, permissionTree ->
                println("${permissionTree.name}: appId=${permissionTree.appId}")
                println(
                    "${permissionTree.name}: " +
                        "packageName=${permissionTree.packageName}, " +
                        "appId=${permissionTree.appId}"
                )
            }
        }
    }
@@ -1859,6 +1877,7 @@ class PermissionService(
                            println("$appOpName: mode=${AppOpsManager.modeToName(appOpMode)}")
                        }
                    }

                    packageNames?.forEachIndexed { _, packageName ->
                        println("Package: $packageName")
                        withIndent {