From e89c2fd4b8f6faadfe92e2acdf6b46c48fb11127 Mon Sep 17 00:00:00 2001 From: Felipe Leme Date: Mon, 24 May 2021 19:06:53 -0700 Subject: [PATCH] Further refactoring on ActionDisabledByAdminDialog classes. Bug: 184107103 Bug: 188836559 Test: m -j RunSettingsRoboTests ROBOTEST_FILTER=ActionDisabledByAdminDialogHelperTest Test: atest ActionDisabledLearnMoreButtonLauncherImplTest Test: adb shell am start -e android.app.extra.RESTRICTION no_install_unknown-sources -a android.settings.SHOW_ADMIN_SUPPORT_DETAILS Test: manual verification with CtsVerifier Change-Id: I3c4056d82834b5e2a4afbd958be7c9d0b9af543e --- .../ActionDisabledByAdminDialogHelper.java | 55 ++++----- ...onDisabledLearnMoreButtonLauncherImpl.java | 111 ++++++------------ ...ActionDisabledByAdminDialogHelperTest.java | 13 +- ...sabledLearnMoreButtonLauncherImplTest.java | 98 +++++++++------- 4 files changed, 126 insertions(+), 151 deletions(-) diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java index 2a5eda217a6..b6ffc5f719c 100644 --- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -45,30 +45,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() { @@ -77,21 +72,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) { @@ -101,17 +99,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)) { @@ -148,8 +146,7 @@ public class ActionDisabledByAdminDialogHelper { if (titleView == null) { return; } - titleView.setText( - mActionDisabledByAdminController.getAdminSupportTitle(restriction)); + titleView.setText(mActionDisabledByAdminController.getAdminSupportTitle(restriction)); } @VisibleForTesting diff --git a/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java b/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java index 98cad65b5d8..09337993d86 100644 --- a/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java +++ b/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java @@ -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 { +public final class ActionDisabledLearnMoreButtonLauncherImpl + extends ActionDisabledLearnMoreButtonLauncher { - static final BiConsumer SHOW_ADMIN_POLICIES = - (activity, enforcedAdmin) -> { - showAdminPolicies(enforcedAdmin, activity); - activity.finish(); - }; + private final Activity mActivity; + private final AlertDialog.Builder mBuilder; - static final BiConsumer LAUNCH_HELP_PAGE = (activity, url) -> { - launchLearnMoreHelpPage(activity, url); - activity.finish(); - }; - - @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"); + + mBuilder.setNeutralButton(R.string.learn_more, (dialog, which) -> action.run()); } - private void setupLearnMoreButton(AlertDialog.Builder builder, Runnable runnable) { - builder.setNeutralButton(R.string.learn_more, (dialog, which) -> { - runnable.run(); - }); + @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"); + + 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 launchLearnMoreHelpPage(Activity activity, String url) { - activity.startActivityAsUser(createLearnMoreIntent(url), UserHandle.SYSTEM); + @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. + mActivity.startActivity(intent); } - 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; - } - - 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); - // Activity merges both managed profile and parent users - // admins so show as same user as this activity. - activity.startActivity(intent); - } + @Override + protected void finishSelf() { + mActivity.finish(); } } diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index 6acc72fcf79..908864166f8 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -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()); } diff --git a/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java b/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java index 68468ed4162..4f7ecc8904e 100644 --- a/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java +++ b/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java @@ -24,86 +24,104 @@ 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 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); + public void launchShowAdminSettings_works() { + mImpl.launchShowAdminSettings(mActivity); - ActionDisabledLearnMoreButtonLauncherImpl.SHOW_ADMIN_POLICIES - .accept(mActivity, enforcedAdmin); + verify(mActivity).startActivity(mIntentCaptor.capture()); + assertDeviceAdminSettingsActivity(mIntentCaptor.getValue()); + } - final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mActivity).startActivity(captor.capture()); - assertThat(captor.getValue().getComponent().getClassName()) + @Test + public void launchShowAdminPolicies_works() { + mImpl.launchShowAdminPolicies(mActivity, ENFORCED_ADMIN_USER, ADMIN_COMPONENT); + + verify(mActivity).startActivityAsUser(mIntentCaptor.capture(), eq(ENFORCED_ADMIN_USER)); + assertDeviceAdminAddIntent(mIntentCaptor.getValue()); + } + + @Test + public void showHelpPage_works() { + mImpl.showHelpPage(mActivity, URL); + + verify(mActivity).startActivityAsUser(mIntentCaptor.capture(), eq(CONTEXT_USER)); + assertActionViewIntent(mIntentCaptor.getValue()); + } + + private void assertDeviceAdminSettingsActivity(Intent intent) { + assertThat(intent.getComponent().getClassName()) .isEqualTo(Settings.DeviceAdminSettingsActivity.class.getName()); } - @Test - public void showAdminPolicies_withComponent_works() { - final EnforcedAdmin enforcedAdmin = createEnforcedAdmin(ADMIN_COMPONENT); - - ActionDisabledLearnMoreButtonLauncherImpl.SHOW_ADMIN_POLICIES - .accept(mActivity, enforcedAdmin); - - final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mActivity).startActivityAsUser( - captor.capture(), - eq(UserHandle.of(ENFORCED_ADMIN_USER_ID))); - assertDeviceAdminAddIntent(captor.getValue()); - } - - @Test - public void launchHelpPage_works() { - ActionDisabledLearnMoreButtonLauncherImpl.LAUNCH_HELP_PAGE.accept(mActivity, URL); - - final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); - verify(mActivity).startActivityAsUser(captor.capture(), eq(UserHandle.SYSTEM)); - assertActionViewIntent(captor.getValue()); - } - - private EnforcedAdmin createEnforcedAdmin(ComponentName component) { - return new RestrictedLockUtils.EnforcedAdmin( - component, UserHandle.of(ENFORCED_ADMIN_USER_ID)); - } - private void assertDeviceAdminAddIntent(Intent intent) { assertThat(intent.getComponent().getClassName()) .isEqualTo(DeviceAdminAdd.class.getName());