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

Commit 9e1e5ddb authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Further refactoring on ActionDisabledByAdminDialog classes." into sc-dev

parents 6c2d3450 e89c2fd4
Loading
Loading
Loading
Loading
+26 −29
Original line number Diff line number Diff line
@@ -46,30 +46,25 @@ import java.util.Objects;
/**
 * Helper class for {@link ActionDisabledByAdminDialog} which sets up the dialog.
 */
public class ActionDisabledByAdminDialogHelper {
public final class ActionDisabledByAdminDialogHelper {

    private static final String TAG = ActionDisabledByAdminDialogHelper.class.getName();
    @VisibleForTesting EnforcedAdmin mEnforcedAdmin;
    private ViewGroup mDialogView;
    private String mRestriction = null;
    private final Activity mActivity;
    private String mRestriction;
    private final ActionDisabledByAdminController mActionDisabledByAdminController;
    private final Activity mActivity;

    public ActionDisabledByAdminDialogHelper(Activity activity) {
        mActivity = activity;
        mActionDisabledByAdminController =
                ActionDisabledByAdminControllerFactory.createInstance(
                        mActivity.getSystemService(DevicePolicyManager.class),
                        new ActionDisabledLearnMoreButtonLauncherImpl(),
                        new DeviceAdminStringProviderImpl(mActivity));
        mDialogView = (ViewGroup) LayoutInflater.from(mActivity).inflate(
                R.layout.admin_support_details_dialog, null);
        mActionDisabledByAdminController = ActionDisabledByAdminControllerFactory
                .createInstance(mActivity, new DeviceAdminStringProviderImpl(mActivity));
    }

    private @UserIdInt int getEnforcementAdminUserId(@NonNull EnforcedAdmin admin) {
        if (admin.user == null) {
            return UserHandle.USER_NULL;
        } else {
            return admin.user.getIdentifier();
        }
        return admin.user == null ? UserHandle.USER_NULL : admin.user.getIdentifier();
    }

    private @UserIdInt int getEnforcementAdminUserId() {
@@ -78,21 +73,24 @@ public class ActionDisabledByAdminDialogHelper {

    public AlertDialog.Builder prepareDialogBuilder(String restriction,
            EnforcedAdmin enforcedAdmin) {
        mEnforcedAdmin = enforcedAdmin;
        mRestriction = restriction;
        final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
        mDialogView = (ViewGroup) LayoutInflater.from(mActivity).inflate(
                R.layout.admin_support_details_dialog, null);
        initializeDialogViews(mDialogView, mEnforcedAdmin, getEnforcementAdminUserId(),
                mRestriction, mActionDisabledByAdminController);
        builder.setPositiveButton(R.string.okay, null).setView(mDialogView);
        maybeSetLearnMoreButton(builder);
        AlertDialog.Builder builder = new AlertDialog.Builder(mActivity)
                .setPositiveButton(R.string.okay, null)
                .setView(mDialogView);
        prepareDialogBuilder(builder, restriction, enforcedAdmin);
        return builder;
    }

    @VisibleForTesting
    void maybeSetLearnMoreButton(AlertDialog.Builder builder) {
        mActionDisabledByAdminController.setupLearnMoreButton(mActivity, builder);
    void prepareDialogBuilder(AlertDialog.Builder builder, String restriction,
            EnforcedAdmin enforcedAdmin) {
        mActionDisabledByAdminController.initialize(
                new ActionDisabledLearnMoreButtonLauncherImpl(mActivity, builder));

        mEnforcedAdmin = enforcedAdmin;
        mRestriction = restriction;
        initializeDialogViews(mDialogView, mEnforcedAdmin, getEnforcementAdminUserId(),
                mRestriction);
        mActionDisabledByAdminController.setupLearnMoreButton(mActivity);
    }

    public void updateDialog(String restriction, EnforcedAdmin admin) {
@@ -102,17 +100,17 @@ public class ActionDisabledByAdminDialogHelper {
        mEnforcedAdmin = admin;
        mRestriction = restriction;
        initializeDialogViews(mDialogView, mEnforcedAdmin, getEnforcementAdminUserId(),
                mRestriction, mActionDisabledByAdminController);
                mRestriction);
    }

    private void initializeDialogViews(View root, EnforcedAdmin enforcedAdmin, int userId,
            String restriction, ActionDisabledByAdminController controller) {
            String restriction) {
        ComponentName admin = enforcedAdmin.component;
        if (admin == null) {
            return;
        }

        controller.updateEnforcedAdmin(enforcedAdmin, userId);
        mActionDisabledByAdminController.updateEnforcedAdmin(enforcedAdmin, userId);
        setAdminSupportIcon(root, admin, userId);

        if (isNotCurrentUserOrProfile(admin, userId)) {
@@ -151,8 +149,7 @@ public class ActionDisabledByAdminDialogHelper {
        if (titleView == null) {
            return;
        }
        titleView.setText(
                mActionDisabledByAdminController.getAdminSupportTitle(restriction));
        titleView.setText(mActionDisabledByAdminController.getAdminSupportTitle(restriction));
    }

    @VisibleForTesting
+35 −72
Original line number Diff line number Diff line
@@ -20,104 +20,67 @@ import static java.util.Objects.requireNonNull;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;

import androidx.appcompat.app.AlertDialog;

import com.android.settings.R;
import com.android.settings.Settings;
import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
import com.android.settingslib.enterprise.ActionDisabledLearnMoreButtonLauncher;

import java.util.function.BiConsumer;

/**
 * Helper class to set up the "Learn more" button in the action disabled dialog.
 */
public class ActionDisabledLearnMoreButtonLauncherImpl
        implements ActionDisabledLearnMoreButtonLauncher {

    static final BiConsumer<Activity, EnforcedAdmin> SHOW_ADMIN_POLICIES =
            (activity, enforcedAdmin) -> {
                showAdminPolicies(enforcedAdmin, activity);
                activity.finish();
            };
public final class ActionDisabledLearnMoreButtonLauncherImpl
        extends ActionDisabledLearnMoreButtonLauncher {

    static final BiConsumer<Activity, String> LAUNCH_HELP_PAGE = (activity, url) -> {
        launchLearnMoreHelpPage(activity, url);
        activity.finish();
    };
    private final Activity mActivity;
    private final AlertDialog.Builder mBuilder;

    @Override
    public void setupLearnMoreButtonToShowAdminPolicies(
            Context context,
            Object alertDialogBuilder,
            int enforcementAdminUserId,
            EnforcedAdmin enforcedAdmin) {
        requireNonNull(context);
        requireNonNull(alertDialogBuilder);
        requireNonNull(enforcedAdmin);
        // The "Learn more" button appears only if the restriction is enforced by an admin in the
        // same profile group. Otherwise the admin package and its policies are not accessible to
        // the current user.
        final UserManager um = UserManager.get(context);
        if (um.isSameProfileGroup(enforcementAdminUserId, um.getUserHandle())) {
            setupLearnMoreButton((AlertDialog.Builder) alertDialogBuilder, () ->
                    SHOW_ADMIN_POLICIES.accept((Activity) context, enforcedAdmin));
        }
    ActionDisabledLearnMoreButtonLauncherImpl(Activity activity, AlertDialog.Builder builder) {
        mActivity = requireNonNull(activity, "activity cannot be null");
        mBuilder = requireNonNull(builder, "builder cannot be null");
    }

    @Override
    public void setupLearnMoreButtonToLaunchHelpPage(
            Context context,
            Object alertDialogBuilder,
            String url) {
        requireNonNull(context);
        requireNonNull(alertDialogBuilder);
        requireNonNull(url);
        setupLearnMoreButton((AlertDialog.Builder) alertDialogBuilder,
                () -> LAUNCH_HELP_PAGE.accept((Activity) context, url));
    }
    public void setLearnMoreButton(Runnable action) {
        requireNonNull(action, "action cannot be null");

    private void setupLearnMoreButton(AlertDialog.Builder builder, Runnable runnable) {
        builder.setNeutralButton(R.string.learn_more, (dialog, which) -> {
            runnable.run();
        });
        mBuilder.setNeutralButton(R.string.learn_more, (dialog, which) -> action.run());
    }

    private static void launchLearnMoreHelpPage(Activity activity, String url) {
        activity.startActivityAsUser(createLearnMoreIntent(url), UserHandle.SYSTEM);
    }
    @Override
    protected void launchShowAdminPolicies(Context context, UserHandle user, ComponentName admin) {
        requireNonNull(context, "context cannot be null");
        requireNonNull(user, "user cannot be null");
        requireNonNull(admin, "admin cannot be null");

    private static Intent createLearnMoreIntent(String url) {
        final Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        return intent;
        Intent intent = new Intent()
                .setClass(mActivity, DeviceAdminAdd.class)
                .putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, admin)
                .putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true);
        // DeviceAdminAdd class may need to run as managed profile.
        mActivity.startActivityAsUser(intent, user);
    }

    private static void showAdminPolicies(
            EnforcedAdmin enforcedAdmin,
            Activity activity) {
        final Intent intent = new Intent();
        if (enforcedAdmin.component != null) {
            intent.setClass(activity, DeviceAdminAdd.class);
            intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                    enforcedAdmin.component);
            intent.putExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, true);
            // DeviceAdminAdd class may need to run as managed profile.
            activity.startActivityAsUser(intent, enforcedAdmin.user);
        } else {
            intent.setClass(activity, Settings.DeviceAdminSettingsActivity.class);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    @Override
    protected void launchShowAdminSettings(Context context) {
        requireNonNull(context, "context cannot be null");

        Intent intent = new Intent()
                .setClass(mActivity, Settings.DeviceAdminSettingsActivity.class)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // Activity merges both managed profile and parent users
        // admins so show as same user as this activity.
            activity.startActivity(intent);
        mActivity.startActivity(intent);
    }

    @Override
    protected void finishSelf() {
        mActivity.finish();
    }
}
+5 −8
Original line number Diff line number Diff line
@@ -200,24 +200,21 @@ public class ActionDisabledByAdminDialogHelperTest {

    @Test
    public void testMaybeSetLearnMoreButton() {
        final UserManager userManager = RuntimeEnvironment.application.getSystemService(
                UserManager.class);
        final ShadowUserManager userManagerShadow = Shadow.extract(userManager);
        mHelper.prepareDialogBuilder(
                /* restriction= */ null, ENFORCED_ADMIN);

        UserManager userManager = RuntimeEnvironment.application
                .getSystemService(UserManager.class);
        ShadowUserManager userManagerShadow = Shadow.extract(userManager);
        // Set up for shadow call.
        userManagerShadow.getSameProfileGroupIds().put(USER_ID, 0);

        // Test that the button is shown when user IDs are in the same profile group
        AlertDialog.Builder builder = mock(AlertDialog.Builder.class);
        mHelper.maybeSetLearnMoreButton(builder);
        mHelper.prepareDialogBuilder(builder, /* restriction= */ null, ENFORCED_ADMIN);
        verify(builder).setNeutralButton(anyInt(), any());

        // Test that the button is not shown when user IDs are not in the same profile group
        userManagerShadow.getSameProfileGroupIds().clear();
        builder = mock(AlertDialog.Builder.class);
        mHelper.maybeSetLearnMoreButton(builder);
        mHelper.prepareDialogBuilder(builder, /* restriction= */ null, ENFORCED_ADMIN);
        verify(builder, never()).setNeutralButton(anyInt(), any());
    }

+50 −32
Original line number Diff line number Diff line
@@ -24,84 +24,102 @@ import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.UserHandle;
import android.os.UserManager;

import androidx.appcompat.app.AlertDialog;
import androidx.test.runner.AndroidJUnit4;

import com.android.settings.Settings;
import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@RunWith(AndroidJUnit4.class)
public class ActionDisabledLearnMoreButtonLauncherImplTest {

    private static final int ENFORCED_ADMIN_USER_ID = 123;
    private static final UserHandle ENFORCED_ADMIN_USER = UserHandle.of(ENFORCED_ADMIN_USER_ID);

    private static final int CONTEXT_USER_ID = -ENFORCED_ADMIN_USER_ID;
    private static final UserHandle CONTEXT_USER = UserHandle.of(CONTEXT_USER_ID);

    private static final ComponentName ADMIN_COMPONENT =
            new ComponentName("some.package.name", "some.package.name.SomeClass");
    private static final String URL = "https://testexample.com";
    private static final Uri URI = Uri.parse(URL);

    @Rule
    public final MockitoRule mMockitoRule = MockitoJUnit.rule();

    @Mock
    private Activity mActivity;

    @Captor
    private ArgumentCaptor<Intent> mIntentCaptor;

    @Mock
    private AlertDialog.Builder mBuilder;

    private ActionDisabledLearnMoreButtonLauncherImpl mImpl;

    @Mock
    private UserManager mUserManager;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        // Can't mock getSystemService(Class) directly because it's final
        when(mActivity.getSystemServiceName(UserManager.class)).thenReturn(Context.USER_SERVICE);
        when(mActivity.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);

        when(mActivity.getUserId()).thenReturn(CONTEXT_USER_ID);
        when(mUserManager.getUserHandle()).thenReturn(CONTEXT_USER_ID);

        mImpl = new ActionDisabledLearnMoreButtonLauncherImpl(mActivity, mBuilder);
    }

    @Test
    public void showAdminPolicies_noComponent_works() {
        final EnforcedAdmin enforcedAdmin = createEnforcedAdmin(/* component= */ null);

        ActionDisabledLearnMoreButtonLauncherImpl.SHOW_ADMIN_POLICIES
                .accept(mActivity, enforcedAdmin);
    public void launchShowAdminSettings_works() {
        mImpl.launchShowAdminSettings(mActivity);

        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
        verify(mActivity).startActivity(captor.capture());
        assertThat(captor.getValue().getComponent().getClassName())
                .isEqualTo(Settings.DeviceAdminSettingsActivity.class.getName());
        verify(mActivity).startActivity(mIntentCaptor.capture());
        assertDeviceAdminSettingsActivity(mIntentCaptor.getValue());
    }

    @Test
    public void showAdminPolicies_withComponent_works() {
        final EnforcedAdmin enforcedAdmin = createEnforcedAdmin(ADMIN_COMPONENT);

        ActionDisabledLearnMoreButtonLauncherImpl.SHOW_ADMIN_POLICIES
                .accept(mActivity, enforcedAdmin);
    public void launchShowAdminPolicies_works() {
        mImpl.launchShowAdminPolicies(mActivity, ENFORCED_ADMIN_USER, ADMIN_COMPONENT);

        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
        verify(mActivity).startActivityAsUser(
                captor.capture(),
                eq(UserHandle.of(ENFORCED_ADMIN_USER_ID)));
        assertDeviceAdminAddIntent(captor.getValue());
        verify(mActivity).startActivityAsUser(mIntentCaptor.capture(), eq(ENFORCED_ADMIN_USER));
        assertDeviceAdminAddIntent(mIntentCaptor.getValue());
    }

    @Test
    public void launchHelpPage_works() {
        ActionDisabledLearnMoreButtonLauncherImpl.LAUNCH_HELP_PAGE.accept(mActivity, URL);
    public void showHelpPage_works() {
        mImpl.showHelpPage(mActivity, URL);

        final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
        verify(mActivity).startActivityAsUser(captor.capture(), eq(UserHandle.SYSTEM));
        assertActionViewIntent(captor.getValue());
        verify(mActivity).startActivityAsUser(mIntentCaptor.capture(), eq(CONTEXT_USER));
        assertActionViewIntent(mIntentCaptor.getValue());
    }

    private EnforcedAdmin createEnforcedAdmin(ComponentName component) {
        return new RestrictedLockUtils.EnforcedAdmin(
                component, UserHandle.of(ENFORCED_ADMIN_USER_ID));
    private void assertDeviceAdminSettingsActivity(Intent intent) {
        assertThat(intent.getComponent().getClassName())
                .isEqualTo(Settings.DeviceAdminSettingsActivity.class.getName());
    }

    private void assertDeviceAdminAddIntent(Intent intent) {