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

Commit 0cf7be1a authored by Sandy Pan's avatar Sandy Pan
Browse files

[Bypass restriction] Offer local override option for restrictions set by the...

[Bypass restriction] Offer local override option for restrictions set by the SupervisionService system authority.

The local override will require authenticating with the parental controls PIN. If authenticated successfully, the restrictions will be released until SupervisionService optionally reapplies them at next onUserStart.

Bug: 383624414
Flag: android.app.supervision.flags.supervision_manager_apis
Test: atest SupervisionServiceTest
Change-Id: Id4a2d27aa5f8a77bab8266abcfb20d94d2fc0c93
parent 87a4aea8
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -2703,6 +2703,30 @@ public final class Settings {
    public static final String ACTION_MANAGE_SUPERVISOR_RESTRICTED_SETTING =
            "android.settings.MANAGE_SUPERVISOR_RESTRICTED_SETTING";
    /**
     * Activity action: Launch UI to bypass the user restrictions set by the SupervisionService
     * system entity.
     *
     * <p>Input: {@link #EXTRA_SUPERVISION_RESTRICTION} specifies the restriction to bypass.
     *
     * <p>Output: Nothing.
     *
     * @hide
     */
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_BYPASS_SUPERVISION_RESTRICTION =
            "android.settings.BYPASS_SUPERVISION_RESTRICTION";
    /**
     * Intent extra: supervision restriction that we are trying to pybass.
     *
     * <p>This should be used when launching {@link #ACTION_BYPASS_SUPERVISION_RESTRICTION} .
     *
     * @hide
     */
    public static final String EXTRA_SUPERVISION_RESTRICTION =
            "android.settings.EXTRA_SUPERVISION_RESTRICTION";
    /**
     * Activity Action: Show a dialog for remote bugreport flow.
     * <p>
+30 −2
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package com.android.settingslib.enterprise;

import android.app.admin.EnforcingAdmin;
import android.app.admin.SystemAuthority;
import android.app.supervision.SupervisionManager;
import android.app.supervision.flags.Flags;
import android.content.ComponentName;
import android.content.Context;
@@ -31,7 +33,6 @@ import androidx.annotation.Nullable;

import com.android.settingslib.RestrictedLockUtils;


final class SupervisedDeviceActionDisabledByAdminController
        extends BaseActionDisabledByAdminController {
    private static final String TAG = "SupervisedDeviceActionDisabledByAdminController";
@@ -77,7 +78,18 @@ final class SupervisedDeviceActionDisabledByAdminController
    @Override
    public DialogInterface.OnClickListener getPositiveButtonListener(@NonNull Context context,
            @Nullable EnforcingAdmin enforcingAdmin) {
        if (enforcingAdmin == null || TextUtils.isEmpty(enforcingAdmin.getPackageName())) {
        if (enforcingAdmin == null) {
            return null;
        }
        if (Flags.supervisionManagerApis()
                && enforcingAdmin.getAuthority() instanceof SystemAuthority authority
                && authority
                        .getSystemEntity()
                        .equals(SupervisionManager.SUPERVISION_SYSTEM_ENTITY)) {
            return startBypassRestrictionActivity(context);

        }
        if (TextUtils.isEmpty(enforcingAdmin.getPackageName())) {
            return null;
        }
        return getPositiveButtonListener(context, enforcingAdmin.getPackageName());
@@ -102,4 +114,20 @@ final class SupervisedDeviceActionDisabledByAdminController
            context.startActivity(intent);
        };
    }

    @Nullable
    private DialogInterface.OnClickListener startBypassRestrictionActivity(
            @NonNull Context context) {
        final Intent intent =
                new Intent(Settings.ACTION_BYPASS_SUPERVISION_RESTRICTION)
                        .putExtra(Settings.EXTRA_SUPERVISION_RESTRICTION, mRestriction);
        ComponentName resolvedSupervisionActivity =
                intent.resolveActivity(context.getPackageManager());
        if (resolvedSupervisionActivity == null) {
            return null;
        }
        return (dialog, which) -> {
            context.startActivity(intent);
        };
    }
}
+9 −0
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import static com.google.common.truth.Truth.assertWithMessage;

import android.app.admin.DeviceAdminAuthority;
import android.app.admin.EnforcingAdmin;
import android.app.admin.SystemAuthority;
import android.app.supervision.SupervisionManager;
import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
@@ -52,6 +54,13 @@ public final class ActionDisabledByAdminControllerTestUtils {
                    UserHandle.of(ENFORCEMENT_ADMIN_USER_ID),
                    ADMIN_COMPONENT);

    static final EnforcingAdmin SUPERVISION_SYSTEM =
            new EnforcingAdmin(
                    "",
                    new SystemAuthority(SupervisionManager.SUPERVISION_SYSTEM_ENTITY),
                    UserHandle.of(UserHandle.USER_SYSTEM)
            );

    static final String URL = "https://testexample.com";

    // NOTE: fields below must be public because of DebugUtils.constantToString() call
+27 −1
Original line number Diff line number Diff line
@@ -19,8 +19,9 @@ package com.android.settingslib.enterprise;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ADMIN_COMPONENT;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ADMIN_PACKAGE_NAME;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCED_ADMIN;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCING_ADMIN;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCEMENT_ADMIN_USER_ID;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.ENFORCING_ADMIN;
import static com.android.settingslib.enterprise.ActionDisabledByAdminControllerTestUtils.SUPERVISION_SYSTEM;
import static com.android.settingslib.enterprise.FakeDeviceAdminStringProvider.DEFAULT_DEVICE_ADMIN_STRING_PROVIDER;

import static junit.framework.Assert.assertNotNull;
@@ -31,12 +32,14 @@ import static org.mockito.Mockito.mock;
import static org.robolectric.Shadows.shadowOf;

import android.app.Activity;
import android.app.supervision.flags.Flags;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.UserManager;
import android.platform.test.annotations.EnableFlags;
import android.provider.Settings;

import org.junit.Before;
@@ -111,6 +114,29 @@ public class SupervisedDeviceActionDisabledByAdminControllerTest {
        assertEquals(ADMIN_PACKAGE_NAME, nextIntent.getPackage());
    }

    @Test
    @EnableFlags(Flags.FLAG_SUPERVISION_MANAGER_APIS)
    public void buttonClicked_enforcingAdmin_supervisionSystem() {
        String restriction = "no_add_user";
        Intent intent =
                new Intent(Settings.ACTION_BYPASS_SUPERVISION_RESTRICTION)
                        .putExtra(Settings.EXTRA_SUPERVISION_RESTRICTION, restriction);
        ResolveInfo resolveInfo =
                ShadowResolveInfo.newResolveInfo(
                        "Bypass Activity", ADMIN_COMPONENT.getPackageName(), "BypassActivity");
        shadowOf(mContext.getPackageManager()).addResolveInfoForIntent(intent, resolveInfo);

        DialogInterface.OnClickListener listener =
                mController.getPositiveButtonListener(mContext, SUPERVISION_SYSTEM);
        assertNotNull("Supervision controller must supply a non-null listener", listener);
        listener.onClick(mock(DialogInterface.class), 0 /* which */);

        Intent nextIntent = shadowOf(RuntimeEnvironment.application).getNextStartedActivity();
        assertEquals(Settings.ACTION_BYPASS_SUPERVISION_RESTRICTION, nextIntent.getAction());
        assertEquals(
                restriction, nextIntent.getStringExtra(Settings.EXTRA_SUPERVISION_RESTRICTION));
    }

    @Test
    public void noButton() {
        // No supervisor restricted setting Activity
+1 −0
Original line number Diff line number Diff line
@@ -833,6 +833,7 @@ public class SupervisionService extends ISupervisionManager.Stub {
            if (Flags.enableSyncWithDpm() && !user.isPreCreated()) {
                mSupervisionService.syncStateWithDevicePolicyManager(user.getUserIdentifier());
            }
            mSupervisionService.maybeApplyUserRestrictionsFor(user.getUserHandle());
        }

        private final class ProfileOwnerBroadcastReceiver extends BroadcastReceiver {
Loading