diff --git a/res/values/strings.xml b/res/values/strings.xml index 6398943e1a6..738e40e709c 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -7730,6 +7730,8 @@ + + Account for content @@ -10803,22 +10805,24 @@ Update available - - Action not allowed - + + Blocked by your IT admin + Can’t change volume - - Calling not allowed - - SMS not allowed - - Camera not allowed - - Screenshot not allowed + + Can’t make calls + + Can’t send SMS messages + + Can’t use camera + + Can’t take screenshots Can’t open this app Blocked by your credit provider + + If you have questions, contact your IT admin More details diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java index 1140291a2a1..86ffa47fa54 100644 --- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -16,21 +16,17 @@ package com.android.settings.enterprise; -import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; - import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.os.Process; import android.os.UserHandle; -import android.os.UserManager; import android.util.IconDrawableFactory; import android.view.LayoutInflater; import android.view.View; @@ -42,12 +38,12 @@ import androidx.annotation.VisibleForTesting; import androidx.appcompat.app.AlertDialog; import com.android.settings.R; -import com.android.settings.Settings; import com.android.settings.Utils; -import com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd; import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import com.android.settingslib.RestrictedLockUtilsInternal; +import com.android.settingslib.enterprise.ActionDisabledByAdminController; +import com.android.settingslib.enterprise.ActionDisabledByAdminControllerFactory; import java.util.Objects; @@ -60,10 +56,16 @@ public class ActionDisabledByAdminDialogHelper { @VisibleForTesting EnforcedAdmin mEnforcedAdmin; private ViewGroup mDialogView; private String mRestriction = null; - private Activity mActivity; + private final Activity mActivity; + private final ActionDisabledByAdminController mActionDisabledByAdminController; public ActionDisabledByAdminDialogHelper(Activity activity) { mActivity = activity; + mActionDisabledByAdminController = + ActionDisabledByAdminControllerFactory.createInstance( + mActivity.getSystemService(DevicePolicyManager.class), + new ActionDisabledLearnMoreButtonLauncherImpl(), + new DeviceAdminStringProviderImpl(mActivity)); } private @UserIdInt int getEnforcementAdminUserId(@NonNull EnforcedAdmin admin) { @@ -83,10 +85,10 @@ public class ActionDisabledByAdminDialogHelper { mEnforcedAdmin = enforcedAdmin; mRestriction = restriction; final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); - mDialogView = (ViewGroup) LayoutInflater.from(builder.getContext()).inflate( + mDialogView = (ViewGroup) LayoutInflater.from(mActivity).inflate( R.layout.admin_support_details_dialog, null); - initializeDialogViews(mDialogView, mEnforcedAdmin.component, getEnforcementAdminUserId(), - mRestriction); + initializeDialogViews(mDialogView, mEnforcedAdmin, getEnforcementAdminUserId(), + mRestriction, mActionDisabledByAdminController); builder.setPositiveButton(R.string.okay, null).setView(mDialogView); maybeSetLearnMoreButton(builder); return builder; @@ -94,16 +96,7 @@ public class ActionDisabledByAdminDialogHelper { @VisibleForTesting void maybeSetLearnMoreButton(AlertDialog.Builder builder) { - // 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(mActivity.getApplicationContext()); - if (um.isSameProfileGroup(getEnforcementAdminUserId(mEnforcedAdmin), um.getUserHandle())) { - builder.setNeutralButton(R.string.learn_more, (dialog, which) -> { - showAdminPolicies(mEnforcedAdmin, mActivity); - mActivity.finish(); - }); - } + mActionDisabledByAdminController.setupLearnMoreButton(mActivity, builder); } public void updateDialog(String restriction, EnforcedAdmin admin) { @@ -112,16 +105,18 @@ public class ActionDisabledByAdminDialogHelper { } mEnforcedAdmin = admin; mRestriction = restriction; - initializeDialogViews(mDialogView, mEnforcedAdmin.component, getEnforcementAdminUserId(), - mRestriction); + initializeDialogViews(mDialogView, mEnforcedAdmin, getEnforcementAdminUserId(), + mRestriction, mActionDisabledByAdminController); } - private void initializeDialogViews(View root, ComponentName admin, int userId, - String restriction) { + private void initializeDialogViews(View root, EnforcedAdmin enforcedAdmin, int userId, + String restriction, ActionDisabledByAdminController controller) { + ComponentName admin = enforcedAdmin.component; if (admin == null) { return; } + controller.updateEnforcedAdmin(enforcedAdmin, userId); setAdminSupportIcon(root, admin, userId); if (isNotCurrentUserOrProfile(admin, userId)) { @@ -171,37 +166,8 @@ public class ActionDisabledByAdminDialogHelper { if (titleView == null) { return; } - if (isFinancedDevice()) { - titleView.setText(R.string.disabled_by_policy_title_financed_device); - return; - } - if (restriction == null) { - titleView.setText(R.string.disabled_by_policy_title); - return; - } - switch (restriction) { - case UserManager.DISALLOW_ADJUST_VOLUME: - titleView.setText(R.string.disabled_by_policy_title_adjust_volume); - break; - case UserManager.DISALLOW_OUTGOING_CALLS: - titleView.setText(R.string.disabled_by_policy_title_outgoing_calls); - break; - case UserManager.DISALLOW_SMS: - titleView.setText(R.string.disabled_by_policy_title_sms); - break; - case DevicePolicyManager.POLICY_DISABLE_CAMERA: - titleView.setText(R.string.disabled_by_policy_title_camera); - break; - case DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE: - titleView.setText(R.string.disabled_by_policy_title_screen_capture); - break; - case DevicePolicyManager.POLICY_SUSPEND_PACKAGES: - titleView.setText(R.string.disabled_by_policy_title_suspend_packages); - break; - default: - // Use general text if no specialized title applies - titleView.setText(R.string.disabled_by_policy_title); - } + titleView.setText( + mActionDisabledByAdminController.getAdminSupportTitle(restriction)); } @VisibleForTesting @@ -227,34 +193,12 @@ public class ActionDisabledByAdminDialogHelper { getEnforcementAdminUserId(enforcedAdmin)); } } + final CharSequence supportContentString = + mActionDisabledByAdminController.getAdminSupportContentString( + mActivity, supportMessage); final TextView textView = root.findViewById(R.id.admin_support_msg); - if (supportMessage != null) { - textView.setText(supportMessage); + if (supportContentString != null) { + textView.setText(supportContentString); } } - - @VisibleForTesting - void showAdminPolicies(final EnforcedAdmin enforcedAdmin, final 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); - } - } - - private boolean isFinancedDevice() { - final DevicePolicyManager dpm = mActivity.getSystemService(DevicePolicyManager.class); - return dpm.isDeviceManaged() && dpm.getDeviceOwnerType( - dpm.getDeviceOwnerComponentOnAnyUser()) == DEVICE_OWNER_TYPE_FINANCED; - } } diff --git a/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java b/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java new file mode 100644 index 00000000000..b4d97e4093c --- /dev/null +++ b/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImpl.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.enterprise; + +import static java.util.Objects.requireNonNull; + +import android.app.Activity; +import android.app.admin.DevicePolicyManager; +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 SHOW_ADMIN_POLICIES = + (activity, enforcedAdmin) -> { + showAdminPolicies(enforcedAdmin, activity); + activity.finish(); + }; + + static final BiConsumer LAUNCH_HELP_PAGE = (activity, url) -> { + launchLearnMoreHelpPage(activity, url); + activity.finish(); + }; + + @Override + public void setupLearnMoreButtonToShowAdminPolicies( + Activity activity, + AlertDialog.Builder builder, + int enforcementAdminUserId, + EnforcedAdmin enforcedAdmin) { + requireNonNull(activity); + requireNonNull(builder); + 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(activity); + if (um.isSameProfileGroup(enforcementAdminUserId, um.getUserHandle())) { + setupLearnMoreButton(builder, () -> + SHOW_ADMIN_POLICIES.accept(activity, enforcedAdmin)); + } + } + + @Override + public void setupLearnMoreButtonToLaunchHelpPage( + Activity activity, + AlertDialog.Builder builder, + String url) { + requireNonNull(activity); + requireNonNull(builder); + requireNonNull(url); + setupLearnMoreButton(builder, () -> LAUNCH_HELP_PAGE.accept(activity, url)); + } + + private void setupLearnMoreButton(AlertDialog.Builder builder, Runnable runnable) { + builder.setNeutralButton(R.string.learn_more, (dialog, which) -> { + runnable.run(); + }); + } + + private static void launchLearnMoreHelpPage(Activity activity, String url) { + activity.startActivityAsUser(createLearnMoreIntent(url), UserHandle.SYSTEM); + } + + 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); + } + } +} diff --git a/src/com/android/settings/enterprise/DeviceAdminStringProviderImpl.java b/src/com/android/settings/enterprise/DeviceAdminStringProviderImpl.java new file mode 100644 index 00000000000..68b202108b6 --- /dev/null +++ b/src/com/android/settings/enterprise/DeviceAdminStringProviderImpl.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.enterprise; + +import static java.util.Objects.requireNonNull; + +import android.content.Context; + +import com.android.settings.R; +import com.android.settingslib.enterprise.DeviceAdminStringProvider; + +class DeviceAdminStringProviderImpl implements DeviceAdminStringProvider { + private final Context mContext; + + DeviceAdminStringProviderImpl(Context context) { + mContext = requireNonNull(context); + } + + @Override + public String getDefaultDisabledByPolicyTitle() { + return mContext.getString(R.string.disabled_by_policy_title); + } + + @Override + public String getDisallowAdjustVolumeTitle() { + return mContext.getString(R.string.disabled_by_policy_title_adjust_volume); + } + + @Override + public String getDisallowOutgoingCallsTitle() { + return mContext.getString(R.string.disabled_by_policy_title_outgoing_calls); + } + + @Override + public String getDisallowSmsTitle() { + return mContext.getString(R.string.disabled_by_policy_title_sms); + } + + @Override + public String getDisableCameraTitle() { + return mContext.getString(R.string.disabled_by_policy_title_camera); + } + + @Override + public String getDisableScreenCaptureTitle() { + return mContext.getString(R.string.disabled_by_policy_title_screen_capture); + } + + @Override + public String getSuspendPackagesTitle() { + return mContext.getString(R.string.disabled_by_policy_title_suspend_packages); + } + + @Override + public String getDefaultDisabledByPolicyContent() { + return mContext.getString(R.string.default_admin_support_msg); + } + + @Override + public String getLearnMoreHelpPageUrl() { + return mContext.getString(R.string.help_url_action_disabled_by_it_admin); + } + + @Override + public String getDisabledByPolicyTitleForFinancedDevice() { + return mContext.getString(R.string.disabled_by_policy_title_financed_device); + } +} diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp index 337bad73057..9b2e97f48aa 100644 --- a/tests/robotests/Android.bp +++ b/tests/robotests/Android.bp @@ -72,10 +72,11 @@ android_robolectric_test { static_libs: [ "SettingsLib-robo-testutils", - "android-support-annotations", + "android-support-annotations", "androidx.test.core", "androidx.test.runner", "androidx.test.ext.junit", + "androidx.test.espresso.core", ], libs: [ diff --git a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index 5c3dacd46de..6acc72fcf79 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -21,7 +21,6 @@ import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; @@ -31,7 +30,6 @@ import static org.mockito.Mockito.verify; import android.app.Activity; import android.app.admin.DevicePolicyManager; import android.content.ComponentName; -import android.content.Intent; import android.content.pm.UserInfo; import android.os.Process; import android.os.UserHandle; @@ -43,8 +41,6 @@ import android.widget.TextView; 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.settings.testutils.CustomActivity; import com.android.settings.testutils.shadow.ShadowActivity; import com.android.settings.testutils.shadow.ShadowDevicePolicyManager; @@ -69,6 +65,11 @@ import org.robolectric.shadows.ShadowProcess; ShadowActivity.class }) public class ActionDisabledByAdminDialogHelperTest { + private static final ComponentName ADMIN_COMPONENT = + new ComponentName("some.package.name", "some.package.name.SomeClass"); + private static final int USER_ID = 123; + private static final EnforcedAdmin ENFORCED_ADMIN = + new EnforcedAdmin(ADMIN_COMPONENT, UserHandle.of(USER_ID)); private ActionDisabledByAdminDialogHelper mHelper; private Activity mActivity; private org.robolectric.shadows.ShadowActivity mActivityShadow; @@ -80,32 +81,6 @@ public class ActionDisabledByAdminDialogHelperTest { mHelper = new ActionDisabledByAdminDialogHelper(mActivity); } - @Test - public void testShowAdminPoliciesWithComponent() { - final int userId = 123; - final ComponentName component = new ComponentName("some.package.name", - "some.package.name.SomeClass"); - final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(userId)); - - mHelper.showAdminPolicies(admin, mActivity); - - final Intent intent = mActivityShadow.getNextStartedActivity(); - assertTrue( - intent.getBooleanExtra(DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG, false)); - assertEquals(component, - intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN)); - } - - @Test - public void testShowAdminPoliciesWithoutComponent() { - final int userId = 123; - final EnforcedAdmin admin = new EnforcedAdmin(null, UserHandle.of(userId)); - mHelper.showAdminPolicies(admin, mActivity); - final Intent intent = mActivityShadow.getNextStartedActivity(); - assertEquals(intent.getComponent(), new ComponentName(mActivity, - Settings.DeviceAdminSettingsActivity.class.getName())); - } - @Test public void testSetAdminSupportTitle() { final ViewGroup view = new FrameLayout(mActivity); @@ -150,6 +125,7 @@ public class ActionDisabledByAdminDialogHelperTest { final ViewGroup view = new FrameLayout(mActivity); final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity); setupFinancedDevice(dpmShadow); + mHelper = new ActionDisabledByAdminDialogHelper(mActivity); mHelper.setAdminSupportTitle(view, null); @@ -196,7 +172,8 @@ public class ActionDisabledByAdminDialogHelperTest { mHelper.setAdminSupportDetails(mActivity, view, admin); assertNotNull(admin.component); - assertEquals("", Shadows.shadowOf(textView).innerText()); + assertEquals(mActivity.getString(R.string.default_admin_support_msg), + Shadows.shadowOf(textView).innerText()); } @Test @@ -217,7 +194,8 @@ public class ActionDisabledByAdminDialogHelperTest { mHelper.setAdminSupportDetails(mActivity, textView, admin); assertNull(admin.component); - assertEquals("", Shadows.shadowOf(textView).innerText()); + assertEquals(mActivity.getString(R.string.default_admin_support_msg), + Shadows.shadowOf(textView).innerText()); } @Test @@ -225,12 +203,11 @@ public class ActionDisabledByAdminDialogHelperTest { final UserManager userManager = RuntimeEnvironment.application.getSystemService( UserManager.class); final ShadowUserManager userManagerShadow = Shadow.extract(userManager); - final ComponentName component = new ComponentName("some.package.name", - "some.package.name.SomeClass"); - mHelper.mEnforcedAdmin = new EnforcedAdmin(component, UserHandle.of(123)); + mHelper.prepareDialogBuilder( + /* restriction= */ null, ENFORCED_ADMIN); // Set up for shadow call. - userManagerShadow.getSameProfileGroupIds().put(123, 0); + 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); diff --git a/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java b/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java new file mode 100644 index 00000000000..68468ed4162 --- /dev/null +++ b/tests/unit/src/com/android/settings/enterprise/ActionDisabledLearnMoreButtonLauncherImplTest.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.enterprise; + +import static android.app.admin.DevicePolicyManager.EXTRA_DEVICE_ADMIN; + +import static com.android.settings.applications.specialaccess.deviceadmin.DeviceAdminAdd.EXTRA_CALLED_FROM_SUPPORT_DIALOG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import android.app.Activity; +import android.content.ComponentName; +import android.content.Intent; +import android.net.Uri; +import android.os.UserHandle; + +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.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + + +@RunWith(AndroidJUnit4.class) +public class ActionDisabledLearnMoreButtonLauncherImplTest { + + private static final int ENFORCED_ADMIN_USER_ID = 123; + 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); + + @Mock + private Activity mActivity; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void showAdminPolicies_noComponent_works() { + final EnforcedAdmin enforcedAdmin = createEnforcedAdmin(/* component= */ null); + + ActionDisabledLearnMoreButtonLauncherImpl.SHOW_ADMIN_POLICIES + .accept(mActivity, enforcedAdmin); + + final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); + verify(mActivity).startActivity(captor.capture()); + assertThat(captor.getValue().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()); + assertThat((ComponentName) intent.getParcelableExtra(EXTRA_DEVICE_ADMIN)) + .isEqualTo(ADMIN_COMPONENT); + assertThat(intent.getBooleanExtra( + EXTRA_CALLED_FROM_SUPPORT_DIALOG, + /* defaultValue= */ false)) + .isTrue(); + } + + private void assertActionViewIntent(Intent intent) { + assertThat(intent.getAction()) + .isEqualTo(Intent.ACTION_VIEW); + assertThat(intent.getData()) + .isEqualTo(URI); + } +}