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

Commit a296e3d5 authored by Faye Yan's avatar Faye Yan Committed by Android (Google) Code Review
Browse files

Merge "Ambient Activation p2.3" into main

parents 49346585 42f1565e
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -34,7 +34,6 @@ 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;
@@ -122,7 +121,6 @@ public class AppOpsControllerImpl extends BroadcastReceiver implements AppOpsCon
            AppOpsManager.OP_SYSTEM_ALERT_WINDOW
    };


    protected static final int[] OPS = concatOps(OPS_MIC, OPS_CAMERA, OPS_LOC, OPS_OTHERS);

    /**
+102 −38
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import static android.hardware.SensorPrivacyManager.Sensors.MICROPHONE;

import static com.android.systemui.appops.AppOpsControllerImpl.OPS_MIC;

import static com.google.common.truth.Truth.assertThat;

import static junit.framework.TestCase.assertFalse;

import static org.junit.Assert.assertEquals;
@@ -66,6 +68,7 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@@ -543,69 +546,114 @@ public class AppOpsControllerTest extends SysuiTestCase {

    @Test
    public void testAudioFilteredWhenMicDisabled() {
        mController.addCallback(new int[]{AppOpsManager.OP_RECORD_AUDIO, AppOpsManager.OP_CAMERA},
                mCallback);
        int micOp = AppOpsManager.OP_RECORD_AUDIO;
        int nonMicOp = AppOpsManager.OP_CAMERA;

        // Add callbacks for the micOp and nonMicOp, called for the micOp active state change,
        // verify the micOp is the only active op returned.
        mController.addCallback(new int[]{micOp, nonMicOp}, mCallback);
        mTestableLooper.processAllMessages();
        mController.onOpActiveChanged(
                AppOpsManager.OPSTR_RECORD_AUDIO, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
                AppOpsManager.opToPublicName(micOp), TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        List<AppOpItem> list = mController.getActiveAppOps();
        assertEquals(1, list.size());
        assertEquals(AppOpsManager.OP_RECORD_AUDIO, list.get(0).getCode());
        assertFalse(list.get(0).isDisabled());
        verifySingleActiveOps(micOp);

        // Add a camera op, and disable the microphone. The camera op should be the only op returned
        // Add a non-mic op, and disable the microphone. The camera op should be the only active op
        // returned.
        mController.onSensorBlockedChanged(MICROPHONE, true);
        mController.onOpActiveChanged(
                AppOpsManager.OPSTR_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        mController.onOpActiveChanged(AppOpsManager.opToPublicName(nonMicOp), TEST_UID_OTHER,
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        list = mController.getActiveAppOps();
        assertEquals(1, list.size());
        assertEquals(AppOpsManager.OP_CAMERA, list.get(0).getCode());
        verifySingleActiveOps(nonMicOp);


        // Re enable the microphone, and verify the op returns
        // Re-enable the microphone, and verify the active op returns.
        mController.onSensorBlockedChanged(MICROPHONE, false);
        mTestableLooper.processAllMessages();

        list = mController.getActiveAppOps();
        assertEquals(2, list.size());
        int micIdx = list.get(0).getCode() == AppOpsManager.OP_CAMERA ? 1 : 0;
        assertEquals(AppOpsManager.OP_RECORD_AUDIO, list.get(micIdx).getCode());
        verifyActiveOps(micOp, nonMicOp);
    }

    @Test
    public void testPhoneCallMicrophoneFilteredWhenMicDisabled() {
        mController.addCallback(
                new int[]{AppOpsManager.OP_PHONE_CALL_MICROPHONE, AppOpsManager.OP_CAMERA},
                mCallback);
        int micOp = AppOpsManager.OP_PHONE_CALL_MICROPHONE;
        int nonMicOp = AppOpsManager.OP_CAMERA;

        // Add callbacks for the micOp and nonMicOp, called for the micOp active state change,
        // verify the micOp is the only active op returned.
        mController.addCallback(new int[]{micOp, nonMicOp}, mCallback);
        mTestableLooper.processAllMessages();
        mController.onOpActiveChanged(
                AppOpsManager.OPSTR_PHONE_CALL_MICROPHONE, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
                AppOpsManager.opToPublicName(micOp), TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        List<AppOpItem> list = mController.getActiveAppOps();
        assertEquals(1, list.size());
        assertEquals(AppOpsManager.OP_PHONE_CALL_MICROPHONE, list.get(0).getCode());
        assertFalse(list.get(0).isDisabled());
        verifySingleActiveOps(micOp);

        // Add a camera op, and disable the microphone. The camera op should be the only op returned
        // Add a non-mic op, and disable the microphone. The camera op should be the only active op
        // returned.
        mController.onSensorBlockedChanged(MICROPHONE, true);
        mController.onOpActiveChanged(AppOpsManager.opToPublicName(nonMicOp), TEST_UID_OTHER,
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        verifySingleActiveOps(nonMicOp);

        // Re-enable the microphone, and verify the active op returns.
        mController.onSensorBlockedChanged(MICROPHONE, false);
        mTestableLooper.processAllMessages();
        verifyActiveOps(micOp, nonMicOp);
    }

    @Test
    public void testAmbientTriggerMicrophoneFilteredWhenMicDisabled() {
        int micOp = AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
        int nonMicOp = AppOpsManager.OP_CAMERA;

        // Add callbacks for the micOp and nonMicOp, called for the micOp active state change,
        // verify the micOp is the only active op returned.
        mController.addCallback(new int[]{micOp, nonMicOp}, mCallback);
        mTestableLooper.processAllMessages();
        mController.onOpActiveChanged(
                AppOpsManager.OPSTR_CAMERA, TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
                AppOpsManager.opToPublicName(micOp), TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        list = mController.getActiveAppOps();
        assertEquals(1, list.size());
        assertEquals(AppOpsManager.OP_CAMERA, list.get(0).getCode());
        verifySingleActiveOps(micOp);

        // Add a non-mic op, and disable the microphone. The camera op should be the only active op
        // returned.
        mController.onSensorBlockedChanged(MICROPHONE, true);
        mController.onOpActiveChanged(AppOpsManager.opToPublicName(nonMicOp), TEST_UID_OTHER,
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        verifySingleActiveOps(nonMicOp);

        // Re enable the microphone, and verify the op returns
        // Re-enable the microphone, and verify the active op returns.
        mController.onSensorBlockedChanged(MICROPHONE, false);
        mTestableLooper.processAllMessages();
        verifyActiveOps(micOp, nonMicOp);
    }

        list = mController.getActiveAppOps();
        assertEquals(2, list.size());
        int micIdx = list.get(0).getCode() == AppOpsManager.OP_CAMERA ? 1 : 0;
        assertEquals(AppOpsManager.OP_PHONE_CALL_MICROPHONE, list.get(micIdx).getCode());
    @Test
    public void testSandboxTriggerMicrophoneFilteredWhenMicDisabled() {
        int micOp = AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
        int nonMicOp = AppOpsManager.OP_CAMERA;

        // Add callbacks for the micOp and nonMicOp, called for the micOp active state change,
        // verify the micOp is the only active op returned.
        mController.addCallback(new int[]{micOp, nonMicOp}, mCallback);
        mTestableLooper.processAllMessages();
        mController.onOpActiveChanged(
                AppOpsManager.opToPublicName(micOp), TEST_UID_OTHER, TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        verifySingleActiveOps(micOp);

        // Add a non-mic op, and disable the microphone. The camera op should be the only active op
        // returned.
        mController.onSensorBlockedChanged(MICROPHONE, true);
        mController.onOpActiveChanged(AppOpsManager.opToPublicName(nonMicOp), TEST_UID_OTHER,
                TEST_PACKAGE_NAME, true);
        mTestableLooper.processAllMessages();
        verifySingleActiveOps(nonMicOp);

        // Re-enable the microphone, and verify the active op returns.
        mController.onSensorBlockedChanged(MICROPHONE, false);
        mTestableLooper.processAllMessages();
        verifyActiveOps(micOp, nonMicOp);
    }

    @Test
@@ -708,6 +756,22 @@ public class AppOpsControllerTest extends SysuiTestCase {
                micOpCode, TEST_UID_OTHER, TEST_PACKAGE_NAME, false);
    }

    private void verifySingleActiveOps(int op) {
        List<AppOpItem> list = mController.getActiveAppOps();
        assertEquals(1, list.size());
        assertEquals(op, list.get(0).getCode());
        assertFalse(list.get(0).isDisabled());
    }

    private void verifyActiveOps(int micOp, int nonMicOp) {
        List<AppOpItem> list = mController.getActiveAppOps();
        assertEquals(2, list.size());
        List<Integer> codes = Arrays.asList(list.get(0).getCode(), list.get(1).getCode());
        assertThat(codes).containsExactly(micOp, nonMicOp);
        assertFalse(list.get(0).isDisabled());
        assertFalse(list.get(1).isDisabled());
    }

    private class TestHandler extends AppOpsControllerImpl.H {
        TestHandler(Looper looper) {
            mController.super(looper);
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import static android.app.AppOpsManager.OP_PHONE_CALL_CAMERA;
import static android.app.AppOpsManager.OP_PHONE_CALL_MICROPHONE;
import static android.app.AppOpsManager.OP_RECEIVE_AMBIENT_TRIGGER_AUDIO;
import static android.app.AppOpsManager.OP_RECEIVE_EXPLICIT_USER_INTERACTION_AUDIO;
import static android.app.AppOpsManager.OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
@@ -1125,6 +1126,8 @@ public final class SensorPrivacyService extends SystemService {
                case MICROPHONE:
                    mAppOpsManagerInternal.setGlobalRestriction(OP_RECORD_AUDIO, enabled,
                            mAppOpsRestrictionToken);
                    mAppOpsManagerInternal.setGlobalRestriction(
                                OP_RECEIVE_SANDBOX_TRIGGER_AUDIO, enabled, mAppOpsRestrictionToken);
                    mAppOpsManagerInternal.setGlobalRestriction(OP_PHONE_CALL_MICROPHONE, enabled,
                            mAppOpsRestrictionToken);
                    // We don't show the dialog for RECEIVE_SOUNDTRIGGER_AUDIO, but still want to