Loading packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +57 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; import static android.media.AudioManager.ACTION_MICROPHONE_MUTE_CHANGED; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -33,6 +34,7 @@ import android.os.UserHandle; import android.permission.PermissionManager; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import androidx.annotation.WorkerThread; Loading Loading @@ -96,19 +98,58 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon private final SparseArray<ArrayList<AudioRecordingConfiguration>> mRecordingsByUid = new SparseArray<>(); protected static final int[] OPS = new int[] { AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, @VisibleForTesting protected static final int[] OPS_MIC = new int[] { AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO }; protected static final int[] OPS_CAMERA = new int[] { AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA }; protected static final int[] OPS_LOC = new int[] { AppOpsManager.OP_FINE_LOCATION, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION }; protected static final int[] OPS_OTHERS = new int[] { AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO }; protected static final int[] OPS = concatOps(OPS_MIC, OPS_CAMERA, OPS_LOC, OPS_OTHERS); /** * @param opArrays the given op arrays. * @return the concatenations of the given op arrays. Null arrays are treated as empty. */ private static int[] concatOps(@Nullable int[]...opArrays) { if (opArrays == null) { return new int[0]; } int totalLength = 0; for (int[] opArray : opArrays) { if (opArray == null || opArray.length == 0) { continue; } totalLength += opArray.length; } final int[] concatOps = new int[totalLength]; int index = 0; for (int[] opArray : opArrays) { if (opArray == null || opArray.length == 0) continue; System.arraycopy(opArray, 0, concatOps, index, opArray.length); index += opArray.length; } return concatOps; } @Inject public AppOpsControllerImpl( Context context, Loading Loading @@ -533,12 +574,17 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } private boolean isOpCamera(int op) { return op == AppOpsManager.OP_CAMERA || op == AppOpsManager.OP_PHONE_CALL_CAMERA; for (int i = 0; i < OPS_CAMERA.length; i++) { if (op == OPS_CAMERA[i]) return true; } return false; } private boolean isOpMicrophone(int op) { return op == AppOpsManager.OP_RECORD_AUDIO || op == AppOpsManager.OP_PHONE_CALL_MICROPHONE || op == AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; for (int i = 0; i < OPS_MIC.length; i++) { if (op == OPS_MIC[i]) return true; } return false; } protected class H extends Handler { Loading packages/SystemUI/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitor.kt +7 −3 Original line number Diff line number Diff line Loading @@ -53,11 +53,14 @@ class AppOpsPrivacyItemMonitor @Inject constructor( @VisibleForTesting companion object { val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, val OPS_MIC_CAMERA = intArrayOf( AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO) AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO) val OPS_LOCATION = intArrayOf( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION) Loading Loading @@ -212,6 +215,7 @@ class AppOpsPrivacyItemMonitor @Inject constructor( AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE else -> return null } Loading packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +66 −31 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.appops; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; import static com.android.systemui.appops.AppOpsControllerImpl.OPS_MIC; import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; Loading Loading @@ -171,6 +173,28 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_UID, TEST_PACKAGE_NAME, true); } // Only the app ops in the {@link com.android.systemui.appops.AppOpsControllerImpl.OPS} will be // supported by the {@link AppOpsControllerImpl} to add callbacks. The state changes of active // app ops will be notified by the callback. @Test public void addCallback_partialIncludedCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); assertEquals(2, mController.getActiveAppOps().size()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); verify(mCallback, never()).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } @Test public void addCallback_notIncludedCode() { mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); Loading Loading @@ -504,41 +528,17 @@ public class AppOpsControllerTest extends SysuiTestCase { } @Test public void testUnpausedRecordingSentActive() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); mRecordingCallback.onRecordingConfigChanged(Collections.emptyList()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); public void testUnPausedRecordingSentActive() { for (int i = 0; i < OPS_MIC.length; i++) { verifyUnPausedSentActive(OPS_MIC[i]); } } @Test public void testAudioPausedSentInactive() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class); when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER); when(mockARC.isClientSilenced()).thenReturn(true); mRecordingCallback.onRecordingConfigChanged(List.of(mockARC)); mTestableLooper.processAllMessages(); InOrder inOrder = inOrder(mCallback); inOrder.verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); inOrder.verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, false); for (int i = 0; i < OPS_MIC.length; i++) { verifyAudioPausedSentInactive(OPS_MIC[i]); } } @Test Loading Loading @@ -673,6 +673,41 @@ public class AppOpsControllerTest extends SysuiTestCase { assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(cameraIdx).getCode()); } private void verifyUnPausedSentActive(int micOpCode) { mController.addCallback(new int[]{micOpCode}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged(AppOpsManager.opToPublicName(micOpCode), TEST_UID, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); mRecordingCallback.onRecordingConfigChanged(Collections.emptyList()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(micOpCode, TEST_UID, TEST_PACKAGE_NAME, true); } private void verifyAudioPausedSentInactive(int micOpCode) { mController.addCallback(new int[]{micOpCode}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged(AppOpsManager.opToPublicName(micOpCode), TEST_UID_OTHER, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class); when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER); when(mockARC.isClientSilenced()).thenReturn(true); mRecordingCallback.onRecordingConfigChanged(List.of(mockARC)); mTestableLooper.processAllMessages(); InOrder inOrder = inOrder(mCallback); inOrder.verify(mCallback).onActiveStateChanged( micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); inOrder.verify(mCallback).onActiveStateChanged( micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false); } private class TestHandler extends AppOpsControllerImpl.H { TestHandler(Looper looper) { mController.super(looper); Loading packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,16 @@ class AppOpsPrivacyItemMonitorTest : SysuiTestCase() { assertEquals(1, appOpsPrivacyItemMonitor.getActivePrivacyItems().size) } @Test fun testVoiceActivationPrivacyItems() { doReturn(listOf(AppOpItem(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, 0))) .`when`(appOpsController).getActiveAppOps(anyBoolean()) val privacyItems = appOpsPrivacyItemMonitor.getActivePrivacyItems() assertEquals(1, privacyItems.size) assertEquals(PrivacyType.TYPE_MICROPHONE, privacyItems[0].privacyType) } @Test fun testSimilarItemsDifferentTimeStamp() { doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, 0), Loading Loading
packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java +57 −11 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; import static android.media.AudioManager.ACTION_MICROPHONE_MUTE_CHANGED; import android.annotation.Nullable; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.Context; Loading @@ -33,6 +34,7 @@ import android.os.UserHandle; import android.permission.PermissionManager; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.util.SparseArray; import androidx.annotation.WorkerThread; Loading Loading @@ -96,19 +98,58 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon private final SparseArray<ArrayList<AudioRecordingConfiguration>> mRecordingsByUid = new SparseArray<>(); protected static final int[] OPS = new int[] { AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION, AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_SYSTEM_ALERT_WINDOW, @VisibleForTesting protected static final int[] OPS_MIC = new int[] { AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO }; protected static final int[] OPS_CAMERA = new int[] { AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA }; protected static final int[] OPS_LOC = new int[] { AppOpsManager.OP_FINE_LOCATION, AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION }; protected static final int[] OPS_OTHERS = new int[] { AppOpsManager.OP_SYSTEM_ALERT_WINDOW, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO }; protected static final int[] OPS = concatOps(OPS_MIC, OPS_CAMERA, OPS_LOC, OPS_OTHERS); /** * @param opArrays the given op arrays. * @return the concatenations of the given op arrays. Null arrays are treated as empty. */ private static int[] concatOps(@Nullable int[]...opArrays) { if (opArrays == null) { return new int[0]; } int totalLength = 0; for (int[] opArray : opArrays) { if (opArray == null || opArray.length == 0) { continue; } totalLength += opArray.length; } final int[] concatOps = new int[totalLength]; int index = 0; for (int[] opArray : opArrays) { if (opArray == null || opArray.length == 0) continue; System.arraycopy(opArray, 0, concatOps, index, opArray.length); index += opArray.length; } return concatOps; } @Inject public AppOpsControllerImpl( Context context, Loading Loading @@ -533,12 +574,17 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon } private boolean isOpCamera(int op) { return op == AppOpsManager.OP_CAMERA || op == AppOpsManager.OP_PHONE_CALL_CAMERA; for (int i = 0; i < OPS_CAMERA.length; i++) { if (op == OPS_CAMERA[i]) return true; } return false; } private boolean isOpMicrophone(int op) { return op == AppOpsManager.OP_RECORD_AUDIO || op == AppOpsManager.OP_PHONE_CALL_MICROPHONE || op == AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO; for (int i = 0; i < OPS_MIC.length; i++) { if (op == OPS_MIC[i]) return true; } return false; } protected class H extends Handler { Loading
packages/SystemUI/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitor.kt +7 −3 Original line number Diff line number Diff line Loading @@ -53,11 +53,14 @@ class AppOpsPrivacyItemMonitor @Inject constructor( @VisibleForTesting companion object { val OPS_MIC_CAMERA = intArrayOf(AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, val OPS_MIC_CAMERA = intArrayOf( AppOpsManager.OP_CAMERA, AppOpsManager.OP_PHONE_CALL_CAMERA, AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO) AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO) val OPS_LOCATION = intArrayOf( AppOpsManager.OP_COARSE_LOCATION, AppOpsManager.OP_FINE_LOCATION) Loading Loading @@ -212,6 +215,7 @@ class AppOpsPrivacyItemMonitor @Inject constructor( AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO, AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO, AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, AppOpsManager.OP_RECORD_AUDIO -> PrivacyType.TYPE_MICROPHONE else -> return null } Loading
packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java +66 −31 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.appops; import static android.hardware.SensorPrivacyManager.Sensors.CAMERA; import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE; import static com.android.systemui.appops.AppOpsControllerImpl.OPS_MIC; import static junit.framework.TestCase.assertFalse; import static org.junit.Assert.assertEquals; Loading Loading @@ -171,6 +173,28 @@ public class AppOpsControllerTest extends SysuiTestCase { TEST_UID, TEST_PACKAGE_NAME, true); } // Only the app ops in the {@link com.android.systemui.appops.AppOpsControllerImpl.OPS} will be // supported by the {@link AppOpsControllerImpl} to add callbacks. The state changes of active // app ops will be notified by the callback. @Test public void addCallback_partialIncludedCode() { mController.addCallback(new int[]{AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, AppOpsManager.OP_FINE_LOCATION}, mCallback); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); assertEquals(2, mController.getActiveAppOps().size()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); verify(mCallback, never()).onActiveStateChanged(AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); } @Test public void addCallback_notIncludedCode() { mController.addCallback(new int[]{AppOpsManager.OP_FINE_LOCATION}, mCallback); Loading Loading @@ -504,41 +528,17 @@ public class AppOpsControllerTest extends SysuiTestCase { } @Test public void testUnpausedRecordingSentActive() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); mRecordingCallback.onRecordingConfigChanged(Collections.emptyList()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID, TEST_PACKAGE_NAME, true); public void testUnPausedRecordingSentActive() { for (int i = 0; i < OPS_MIC.length; i++) { verifyUnPausedSentActive(OPS_MIC[i]); } } @Test public void testAudioPausedSentInactive() { mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged( AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class); when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER); when(mockARC.isClientSilenced()).thenReturn(true); mRecordingCallback.onRecordingConfigChanged(List.of(mockARC)); mTestableLooper.processAllMessages(); InOrder inOrder = inOrder(mCallback); inOrder.verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); inOrder.verify(mCallback).onActiveStateChanged( AppOpsManager.OP_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, false); for (int i = 0; i < OPS_MIC.length; i++) { verifyAudioPausedSentInactive(OPS_MIC[i]); } } @Test Loading Loading @@ -673,6 +673,41 @@ public class AppOpsControllerTest extends SysuiTestCase { assertEquals(AppOpsManager.OP_PHONE_CALL_CAMERA, list.get(cameraIdx).getCode()); } private void verifyUnPausedSentActive(int micOpCode) { mController.addCallback(new int[]{micOpCode}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged(AppOpsManager.opToPublicName(micOpCode), TEST_UID, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); mRecordingCallback.onRecordingConfigChanged(Collections.emptyList()); mTestableLooper.processAllMessages(); verify(mCallback).onActiveStateChanged(micOpCode, TEST_UID, TEST_PACKAGE_NAME, true); } private void verifyAudioPausedSentInactive(int micOpCode) { mController.addCallback(new int[]{micOpCode}, mCallback); mTestableLooper.processAllMessages(); mController.onOpActiveChanged(AppOpsManager.opToPublicName(micOpCode), TEST_UID_OTHER, TEST_PACKAGE_NAME, true); mTestableLooper.processAllMessages(); AudioRecordingConfiguration mockARC = mock(AudioRecordingConfiguration.class); when(mockARC.getClientUid()).thenReturn(TEST_UID_OTHER); when(mockARC.isClientSilenced()).thenReturn(true); mRecordingCallback.onRecordingConfigChanged(List.of(mockARC)); mTestableLooper.processAllMessages(); InOrder inOrder = inOrder(mCallback); inOrder.verify(mCallback).onActiveStateChanged( micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, true); inOrder.verify(mCallback).onActiveStateChanged( micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false); } private class TestHandler extends AppOpsControllerImpl.H { TestHandler(Looper looper) { mController.super(looper); Loading
packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt +10 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,16 @@ class AppOpsPrivacyItemMonitorTest : SysuiTestCase() { assertEquals(1, appOpsPrivacyItemMonitor.getActivePrivacyItems().size) } @Test fun testVoiceActivationPrivacyItems() { doReturn(listOf(AppOpItem(AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, TEST_UID, TEST_PACKAGE_NAME, 0))) .`when`(appOpsController).getActiveAppOps(anyBoolean()) val privacyItems = appOpsPrivacyItemMonitor.getActivePrivacyItems() assertEquals(1, privacyItems.size) assertEquals(PrivacyType.TYPE_MICROPHONE, privacyItems[0].privacyType) } @Test fun testSimilarItemsDifferentTimeStamp() { doReturn(listOf(AppOpItem(AppOpsManager.OP_CAMERA, TEST_UID, TEST_PACKAGE_NAME, 0), Loading