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

Commit 00344da6 authored by Atneya Nair's avatar Atneya Nair Committed by Android Build Coastguard Worker
Browse files

[RESTRICT AUTOMERGE] Fix recording config mic indicator suppression

We should suppress the indicator when AllOf the configs are silenced,
instead of AnyOf.

Bug: 293603271
Bug: 325912429
Test: CtsMediaAudioPermissionTestCases
Test: AppOpsControllerTest
Flag: EXEMPT security
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:5d74fac4d1dd1c3c91a830c1d239b2312831c956)
Merged-In: I8b1fe0bc2a4474467a1ef2510b29c5164e32aad8
Change-Id: I8b1fe0bc2a4474467a1ef2510b29c5164e32aad8
parent acbd37d2
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -319,7 +319,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);
                }
@@ -521,18 +521,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() {
@@ -543,7 +546,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;
                }
+23 −7
Original line number Diff line number Diff line
@@ -103,11 +103,10 @@ public class AppOpsControllerTest extends SysuiTestCase {
    @Mock()
    private BroadcastDispatcher mDispatcher;
    @Mock(stubOnly = true)
    private AudioManager.AudioRecordingCallback mRecordingCallback;
    @Mock(stubOnly = true)
    private AudioRecordingConfiguration mPausedMockRecording;

    private AppOpsControllerImpl mController;
    private AudioManager.AudioRecordingCallback mRecordingCallback;
    private TestableLooper mTestableLooper;
    private final FakeExecutor mBgExecutor = new FakeExecutor(new FakeSystemClock());

@@ -975,6 +974,7 @@ public class AppOpsControllerTest extends SysuiTestCase {
    }

    private void verifyUnPausedSentActive(int micOpCode) {
        // Setup stubs the initial active recording list with a single silenced client
        mController.addCallback(new int[]{micOpCode}, mCallback);
        mBgExecutor.runAllReady();
        mTestableLooper.processAllMessages();
@@ -982,11 +982,20 @@ public class AppOpsControllerTest extends SysuiTestCase {
                TEST_PACKAGE_NAME, true);

        mTestableLooper.processAllMessages();
        mRecordingCallback.onRecordingConfigChanged(Collections.emptyList());

        // Update with multiple recording configs, of which one is unsilenced
        var mockARCUnsilenced = mock(AudioRecordingConfiguration.class);
        when(mockARCUnsilenced.getClientUid()).thenReturn(TEST_UID);
        when(mockARCUnsilenced.isClientSilenced()).thenReturn(false);

        mRecordingCallback.onRecordingConfigChanged(List.of(
                    mockARCUnsilenced, mPausedMockRecording));

        mTestableLooper.processAllMessages();

        verify(mCallback).onActiveStateChanged(micOpCode, TEST_UID, TEST_PACKAGE_NAME, true);
        // For consistency since this runs in a loop
        mController.removeCallback(new int[]{micOpCode}, mCallback);
    }

    private void verifyAudioPausedSentInactive(int micOpCode) {
@@ -997,11 +1006,16 @@ public class AppOpsControllerTest extends SysuiTestCase {
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();

        AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class);
        when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER);
        when(mockARC.isClientSilenced()).thenReturn(true);
        // Multiple recording configs, which are all silenced
        AudioRecordingConfiguration mockARCOne = mock(AudioRecordingConfiguration.class);
        when(mockARCOne.getClientUid()).thenReturn(TEST_UID_OTHER);
        when(mockARCOne.isClientSilenced()).thenReturn(true);

        AudioRecordingConfiguration mockARCTwo = mock(AudioRecordingConfiguration.class);
        when(mockARCTwo.getClientUid()).thenReturn(TEST_UID_OTHER);
        when(mockARCTwo.isClientSilenced()).thenReturn(true);

        mRecordingCallback.onRecordingConfigChanged(List.of(mockARC));
        mRecordingCallback.onRecordingConfigChanged(List.of(mockARCOne, mockARCTwo));
        mTestableLooper.processAllMessages();

        InOrder inOrder = inOrder(mCallback);
@@ -1009,6 +1023,8 @@ public class AppOpsControllerTest extends SysuiTestCase {
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        inOrder.verify(mCallback).onActiveStateChanged(
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false);
        // For consistency since this runs in a loop
        mController.removeCallback(new int[]{micOpCode}, mCallback);
    }

    private void verifySingleActiveOps(int op) {