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

Commit 490567fd authored by Evan Severson's avatar Evan Severson
Browse files

Add app op reserved specifically for testing

In preparation for using the permission state to compute the app op mode
of runtime permissions it will be needed to have an app op specific for
keeping tests working correctly. In DiscreteAppopsTest the test uses
OPSTR_CAMERA to make noteOps to validate discrete history; the problem
is that the test app doesn't actually request the camera permission so
PermissionPolicyService never syncs the permission state to the appop's
mode which leads to the default mode being used which is the fully
permissive MODE_ALLOWED. When permission grant state is used
synchronously for checking mode this is going to behave differently
since a permission not requested will not be granted.

We will need an app op that is written to discrete registry and can be
granted the fully permissive mode to test background discrete events
and when permission state is used camera will never be able to. The
location app ops are the only qualifying app ops that exist today but we
see the problem that other features on the device also noteOp quickly
after install contaminating expected results and failing the test.
Because of that this can also be seen as a quality and stability
improvement by providing better isolation between the api behaviors we
want to test and other uses on the device of these apis.

Test: Create this constant, update the test, and watch
Bug: 266164193
Change-Id: I90bd030f36a9de4ab63768aedc6ad0b5317d91d0
parent 31db3e5b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -259,6 +259,7 @@ package android.app {
    field public static final String OPSTR_ACTIVITY_RECOGNITION_SOURCE = "android:activity_recognition_source";
    field public static final String OPSTR_MANAGE_ONGOING_CALLS = "android:manage_ongoing_calls";
    field public static final String OPSTR_RECORD_AUDIO_HOTWORD = "android:record_audio_hotword";
    field public static final String OPSTR_RESERVED_FOR_TESTING = "android:reserved_for_testing";
    field public static final String OPSTR_USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = "android:use_icc_auth_with_device_identifier";
    field public static final int OP_COARSE_LOCATION = 0; // 0x0
    field public static final int OP_RECORD_AUDIO = 27; // 0x1b
+24 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package android.app;

import static android.view.contentprotection.flags.Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED;
import static android.permission.flags.Flags.FLAG_OP_ENABLE_MOBILE_DATA_BY_USER;
import static android.view.contentprotection.flags.Flags.FLAG_CREATE_ACCESSIBILITY_OVERLAY_APP_OP_ENABLED;

import static java.lang.Long.max;

@@ -1521,9 +1521,17 @@ public class AppOpsManager {
     */
    public static final int OP_MEDIA_ROUTING_CONTROL = AppProtoEnums.APP_OP_MEDIA_ROUTING_CONTROL;

    /**
     * Op code for use by tests to avoid interfering history logs that the wider system might
     * trigger.
     *
     * @hide
     */
    public static final int OP_RESERVED_FOR_TESTING = AppProtoEnums.APP_OP_RESERVED_FOR_TESTING;

    /** @hide */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public static final int _NUM_OP = 141;
    public static final int _NUM_OP = 142;

    /**
     * All app ops represented as strings.
@@ -1671,6 +1679,7 @@ public class AppOpsManager {
            OPSTR_CREATE_ACCESSIBILITY_OVERLAY,
            OPSTR_MEDIA_ROUTING_CONTROL,
            OPSTR_ENABLE_MOBILE_DATA_BY_USER,
            OPSTR_RESERVED_FOR_TESTING,
    })
    public @interface AppOpString {}

@@ -2330,6 +2339,17 @@ public class AppOpsManager {
    public static final String OPSTR_ENABLE_MOBILE_DATA_BY_USER =
            "android:enable_mobile_data_by_user";

    /**
     * Reserved for use by appop tests so that operations done legitimately by the platform don't
     * interfere with expected results. Platform code should never use this.
     *
     * @hide
     */
    @TestApi
    @SuppressLint("UnflaggedApi")
    public static final String OPSTR_RESERVED_FOR_TESTING =
            "android:reserved_for_testing";

    /** {@link #sAppOpsToNote} not initialized yet for this op */
    private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
    /** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2887,6 +2907,8 @@ public class AppOpsManager {
                .setPermission(Manifest.permission.MEDIA_ROUTING_CONTROL).build(),
        new AppOpInfo.Builder(OP_ENABLE_MOBILE_DATA_BY_USER, OPSTR_ENABLE_MOBILE_DATA_BY_USER,
                "ENABLE_MOBILE_DATA_BY_USER").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
        new AppOpInfo.Builder(OP_RESERVED_FOR_TESTING, OPSTR_RESERVED_FOR_TESTING,
                "OP_RESERVED_FOR_TESTING").setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
    };

    // The number of longs needed to form a full bitmask of app ops
+2 −1
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ 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_SANDBOX_TRIGGER_AUDIO;
import static android.app.AppOpsManager.OP_RECORD_AUDIO;
import static android.app.AppOpsManager.OP_RESERVED_FOR_TESTING;
import static android.app.AppOpsManager.flagsToString;
import static android.app.AppOpsManager.getUidStateName;

@@ -136,7 +137,7 @@ final class DiscreteRegistry {
    private static final String DEFAULT_DISCRETE_OPS = OP_FINE_LOCATION + "," + OP_COARSE_LOCATION
            + "," + OP_CAMERA + "," + OP_RECORD_AUDIO + "," + OP_PHONE_CALL_MICROPHONE + ","
            + OP_PHONE_CALL_CAMERA + "," + OP_RECEIVE_AMBIENT_TRIGGER_AUDIO + ","
            + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO;
            + OP_RECEIVE_SANDBOX_TRIGGER_AUDIO + "," + OP_RESERVED_FOR_TESTING;
    private static final long DEFAULT_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(7).toMillis();
    private static final long MAXIMUM_DISCRETE_HISTORY_CUTOFF = Duration.ofDays(30).toMillis();
    private static final long DEFAULT_DISCRETE_HISTORY_QUANTIZATION =