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

Commit d3bed8a7 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix recording config mic indicator suppression" into main

parents 7562054f 456c0935
Loading
Loading
Loading
Loading
+8 −5
Original line number Original line Diff line number Diff line
@@ -319,7 +319,7 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon
            if (item == null && active) {
            if (item == null && active) {
                item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime());
                item = new AppOpItem(code, uid, packageName, mClock.elapsedRealtime());
                if (isOpMicrophone(code)) {
                if (isOpMicrophone(code)) {
                    item.setDisabled(isAnyRecordingPausedLocked(uid));
                    item.setDisabled(isAllRecordingPausedLocked(uid));
                } else if (isOpCamera(code)) {
                } else if (isOpCamera(code)) {
                    item.setDisabled(mCameraDisabled);
                    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) {
        if (mMicMuted) {
            return true;
            return true;
        }
        }
        List<AudioRecordingConfiguration> configs = mRecordingsByUid.get(uid);
        List<AudioRecordingConfiguration> configs = mRecordingsByUid.get(uid);
        if (configs == null) return false;
        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();
        int configsNum = configs.size();
        for (int i = 0; i < configsNum; i++) {
        for (int i = 0; i < configsNum; i++) {
            AudioRecordingConfiguration config = configs.get(i);
            AudioRecordingConfiguration config = configs.get(i);
            if (config.isClientSilenced()) return true;
            if (!config.isClientSilenced()) return false;
        }
        }
        return false;
        return true;
    }
    }


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


                boolean paused = false;
                boolean paused = false;
                if (isOpMicrophone(item.getCode())) {
                if (isOpMicrophone(item.getCode())) {
                    paused = isAnyRecordingPausedLocked(item.getUid());
                    paused = isAllRecordingPausedLocked(item.getUid());
                } else if (isOpCamera(item.getCode())) {
                } else if (isOpCamera(item.getCode())) {
                    paused = mCameraDisabled;
                    paused = mCameraDisabled;
                }
                }
+23 −7
Original line number Original line Diff line number Diff line
@@ -103,11 +103,10 @@ public class AppOpsControllerTest extends SysuiTestCase {
    @Mock()
    @Mock()
    private BroadcastDispatcher mDispatcher;
    private BroadcastDispatcher mDispatcher;
    @Mock(stubOnly = true)
    @Mock(stubOnly = true)
    private AudioManager.AudioRecordingCallback mRecordingCallback;
    @Mock(stubOnly = true)
    private AudioRecordingConfiguration mPausedMockRecording;
    private AudioRecordingConfiguration mPausedMockRecording;


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


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


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


        mTestableLooper.processAllMessages();
        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();
        mTestableLooper.processAllMessages();


        verify(mCallback).onActiveStateChanged(micOpCode, TEST_UID, TEST_PACKAGE_NAME, true);
        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) {
    private void verifyAudioPausedSentInactive(int micOpCode) {
@@ -997,11 +1006,16 @@ public class AppOpsControllerTest extends SysuiTestCase {
                TEST_PACKAGE_NAME, true);
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();


        AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class);
        // Multiple recording configs, which are all silenced
        when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER);
        AudioRecordingConfiguration mockARCOne = mock(AudioRecordingConfiguration.class);
        when(mockARC.isClientSilenced()).thenReturn(true);
        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();
        mTestableLooper.processAllMessages();


        InOrder inOrder = inOrder(mCallback);
        InOrder inOrder = inOrder(mCallback);
@@ -1009,6 +1023,8 @@ public class AppOpsControllerTest extends SysuiTestCase {
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        inOrder.verify(mCallback).onActiveStateChanged(
        inOrder.verify(mCallback).onActiveStateChanged(
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false);
                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) {
    private void verifySingleActiveOps(int op) {