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

Commit e5c72065 authored by Atneya Nair's avatar Atneya Nair Committed by Android (Google) Code Review
Browse files

Merge changes from topic "audio_appop_refcount_tm" into tm-dev

* changes:
  [RESTRICT AUTOMERGE] [appops] Preflight skip datasource validation
  [RESTRICT AUTOMERGE] Fix recording config mic indicator suppression
  [RESTRICT AUTOMERGE] appop: Finish all when last in chain fail
parents 0aecb03c a440a043
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -270,7 +270,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon
            if (item == null && active) {
                item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime());
                if (isOpMicrophone(code)) {
                    item.setDisabled(isAnyRecordingPausedLocked(uid));
                    item.setDisabled(isAllRecordingPausedLocked(uid));
                } else if (isOpCamera(code)) {
                    item.setDisabled(mCameraDisabled);
                }
@@ -472,18 +472,21 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon

    }

    private boolean isAnyRecordingPausedLocked(int uid) {
    // TODO(b/365843152) remove AudioRecordingConfiguration listening
    private boolean isAllRecordingPausedLocked(int uid) {
        if (mMicMuted) {
            return true;
        }
        List<AudioRecordingConfiguration> configs = mRecordingsByUid.get(uid);
        if (configs == null) return false;
        // If we are aware of AudioRecordConfigs, suppress the indicator if all of them are known
        // to be silenced.
        int configsNum = configs.size();
        for (int i = 0; i < configsNum; i++) {
            AudioRecordingConfiguration config = configs.get(i);
            if (config.isClientSilenced()) return true;
            if (!config.isClientSilenced()) return false;
        }
        return false;
        return true;
    }

    private void updateSensorDisabledStatus() {
@@ -494,7 +497,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon

                boolean paused = false;
                if (isOpMicrophone(item.getCode())) {
                    paused = isAnyRecordingPausedLocked(item.getUid());
                    paused = isAllRecordingPausedLocked(item.getUid());
                } else if (isOpCamera(item.getCode())) {
                    paused = mCameraDisabled;
                }
+32 −2
Original line number Diff line number Diff line
@@ -1263,6 +1263,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
            final boolean hasChain = attributionChainId != ATTRIBUTION_CHAIN_ID_NONE;
            AttributionSource current = attributionSource;
            AttributionSource next = null;
            AttributionSource prev = null;
            // We consider the chain trusted if the start node has UPDATE_APP_OPS_STATS, and
            // every attributionSource in the chain is registered with the system.
            final boolean isChainStartTrusted = !hasChain || checkPermission(context,
@@ -1330,6 +1331,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                        selfAccess, singleReceiverFromDatasource, attributedOp,
                        proxyAttributionFlags, proxiedAttributionFlags, attributionChainId);

                if (startDataDelivery && opMode != AppOpsManager.MODE_ALLOWED) {
                    // Current failed the perm check, so if we are part-way through an attr chain,
                    // we need to clean up the already started proxy op higher up the chain.  Note,
                    // proxy ops are verified two by two, which means we have to clear the 2nd next
                    // from the previous iteration (since it is actually curr.next which failed
                    // to pass the perm check).
                    if (prev != null) {
                        final var cutAttrSourceState = prev.asState();
                        if (cutAttrSourceState.next.length > 0) {
                            cutAttrSourceState.next[0].next = new AttributionSourceState[0];
                        }
                        finishDataDelivery(context, attributedOp,
                                cutAttrSourceState, fromDatasource);
                    }
                }

                switch (opMode) {
                    case AppOpsManager.MODE_ERRORED: {
                        return PermissionChecker.PERMISSION_HARD_DENIED;
@@ -1349,6 +1366,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                    return PermissionChecker.PERMISSION_GRANTED;
                }

                // an attribution we have already possibly started an op for
                prev = current;
                current = next;
            }
        }
@@ -1516,8 +1535,19 @@ public class PermissionManagerService extends IPermissionManager.Stub {
                if (resolvedAccessorPackageName == null) {
                    return AppOpsManager.MODE_ERRORED;
                }
                final int opMode = appOpsManager.unsafeCheckOpRawNoThrow(op,
                        accessorSource.getUid(), resolvedAccessorPackageName);
                // Avoid checking the first attr in the chain in some cases for consistency with
                // checks for data delivery.
                // In particular, for chains of 2 or more, when skipProxyOperation is true, the
                // for data delivery implementation does not actually check the first link in the
                // chain. If the attribution is just a singleReceiverFromDatasource, this
                // exemption does not apply, since it does not go through proxyOp flow, and the top
                // of the chain is actually removed above.
                // Skipping the check avoids situations where preflight checks fail since the data
                // source itself does not have the op (e.g. audioserver).
                final int opMode = (skipProxyOperation && !singleReceiverFromDatasource) ?
                        AppOpsManager.MODE_ALLOWED :
                        appOpsManager.unsafeCheckOpRawNoThrow(op, accessorSource.getUid(),
                                resolvedAccessorPackageName);
                final AttributionSource next = accessorSource.getNext();
                if (!selfAccess && opMode == AppOpsManager.MODE_ALLOWED && next != null) {
                    final String resolvedNextPackageName = resolvePackageName(context, next);