diff --git a/res/layout/admin_support_details_dialog.xml b/res/layout/admin_support_details_dialog.xml index 2e126cc9d33..298cf24e196 100644 --- a/res/layout/admin_support_details_dialog.xml +++ b/res/layout/admin_support_details_dialog.xml @@ -49,7 +49,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.HeadLineFontFamily.Subhead" - android:text="@string/default_admin_support_msg" android:maxLength="200" android:autoLink="email|phone|web" android:textColor="?android:attr/textColorSecondary"/> diff --git a/res/values/strings.xml b/res/values/strings.xml index 5abba1faabd..4eb8491a7ff 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10442,6 +10442,8 @@ Screenshot not allowed Can’t open this app + + Blocked by your credit provider If you have questions, contact your IT admin diff --git a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java index 5599a94a212..685da03499c 100644 --- a/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java +++ b/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelper.java @@ -16,6 +16,8 @@ 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; @@ -119,24 +121,11 @@ public class ActionDisabledByAdminDialogHelper { if (admin == null) { return; } - ImageView supportIconView = root.requireViewById(R.id.admin_support_icon); - if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin) - || !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) { + + setAdminSupportIcon(root, admin, userId); + + if (isNotCurrentUserOrProfile(admin, userId)) { admin = null; - - supportIconView.setImageDrawable( - mActivity.getDrawable(com.android.internal.R.drawable.ic_info)); - - TypedArray ta = mActivity.obtainStyledAttributes(new int[]{android.R.attr.colorAccent}); - supportIconView.setImageTintList(ColorStateList.valueOf(ta.getColor(0, 0))); - ta.recycle(); - } else { - final Drawable badgedIcon = Utils.getBadgedIcon( - IconDrawableFactory.newInstance(mActivity), - mActivity.getPackageManager(), - admin.getPackageName(), - userId); - supportIconView.setImageDrawable(badgedIcon); } setAdminSupportTitle(root, restriction); @@ -151,12 +140,44 @@ public class ActionDisabledByAdminDialogHelper { setAdminSupportDetails(mActivity, root, new EnforcedAdmin(admin, user)); } + private boolean isNotCurrentUserOrProfile(ComponentName admin, int userId) { + return !isFinancedDevice() + && (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin) + || !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)); + } + + @VisibleForTesting + void setAdminSupportIcon(View root, ComponentName admin, int userId) { + ImageView supportIconView = root.requireViewById(R.id.admin_support_icon); + if (isFinancedDevice()) { + supportIconView.setVisibility(View.GONE); + } else if (isNotCurrentUserOrProfile(admin, userId)) { + supportIconView.setImageDrawable( + mActivity.getDrawable(com.android.internal.R.drawable.ic_info)); + + TypedArray ta = mActivity.obtainStyledAttributes(new int[]{android.R.attr.colorAccent}); + supportIconView.setImageTintList(ColorStateList.valueOf(ta.getColor(0, 0))); + ta.recycle(); + } else { + final Drawable badgedIcon = Utils.getBadgedIcon( + IconDrawableFactory.newInstance(mActivity), + mActivity.getPackageManager(), + admin.getPackageName(), + userId); + supportIconView.setImageDrawable(badgedIcon); + } + } + @VisibleForTesting void setAdminSupportTitle(View root, String restriction) { final TextView titleView = root.findViewById(R.id.admin_support_dialog_title); 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; @@ -195,6 +216,7 @@ public class ActionDisabledByAdminDialogHelper { final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( Context.DEVICE_POLICY_SERVICE); + CharSequence supportMessage = null; if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity, enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( activity, getEnforcementAdminUserId(enforcedAdmin))) { @@ -203,15 +225,16 @@ public class ActionDisabledByAdminDialogHelper { if (enforcedAdmin.user == null) { enforcedAdmin.user = UserHandle.of(UserHandle.myUserId()); } - CharSequence supportMessage = null; if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { supportMessage = dpm.getShortSupportMessageForUser(enforcedAdmin.component, getEnforcementAdminUserId(enforcedAdmin)); } - if (supportMessage != null) { - final TextView textView = root.findViewById(R.id.admin_support_msg); - textView.setText(supportMessage); - } + } + final TextView textView = root.findViewById(R.id.admin_support_msg); + if (supportMessage != null) { + textView.setText(supportMessage); + } else if (!isFinancedDevice()) { + textView.setText(R.string.default_admin_support_msg); } } @@ -233,4 +256,10 @@ public class ActionDisabledByAdminDialogHelper { 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/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java index ff3a36f2574..1ff1d79b815 100644 --- a/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java +++ b/tests/robotests/src/com/android/settings/enterprise/ActionDisabledByAdminDialogHelperTest.java @@ -16,6 +16,8 @@ package com.android.settings.enterprise; +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; @@ -34,8 +36,10 @@ import android.content.pm.UserInfo; import android.os.Process; import android.os.UserHandle; import android.os.UserManager; +import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; +import android.widget.ImageView; import android.widget.TextView; import androidx.appcompat.app.AlertDialog; @@ -104,12 +108,24 @@ public class ActionDisabledByAdminDialogHelperTest { Settings.DeviceAdminSettingsActivity.class.getName())); } + @Test + public void testSetAdminSupportIconForFinancedDevice_adminSupportIconIsGone() { + final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow(); + final ViewGroup view = new FrameLayout(mActivity); + final ImageView supportIconImageView = createAdminSupportIconImageView(view, mActivity); + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + setupFinancedDevice(dpmShadow); + + mHelper.setAdminSupportIcon(view, component, 123); + + assertEquals(View.GONE, supportIconImageView.getVisibility()); + } + @Test public void testSetAdminSupportTitle() { final ViewGroup view = new FrameLayout(mActivity); - final TextView textView = new TextView(mActivity); - textView.setId(R.id.admin_support_dialog_title); - view.addView(textView); + final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity); mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_ADJUST_VOLUME); assertEquals(Shadows.shadowOf(textView).innerText(), @@ -144,6 +160,19 @@ public class ActionDisabledByAdminDialogHelperTest { mActivity.getString(R.string.disabled_by_policy_title)); } + @Test + public void testSetAdminSupportTitleForFinancedDevice() { + final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow(); + final ViewGroup view = new FrameLayout(mActivity); + final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity); + setupFinancedDevice(dpmShadow); + + mHelper.setAdminSupportTitle(view, null); + + assertEquals(Shadows.shadowOf(textView).innerText(), + mActivity.getString(R.string.disabled_by_policy_title_financed_device)); + } + @Test public void testSetAdminSupportDetails() { final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow(); @@ -154,17 +183,13 @@ public class ActionDisabledByAdminDialogHelperTest { final ComponentName component = new ComponentName("some.package.name", "some.package.name.SomeClass"); final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123)); - final TextView textView = new TextView(mActivity); - - textView.setId(R.id.admin_support_msg); - view.addView(textView); + final TextView textView = createAdminSupportTextView(view, mActivity); dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); dpmShadow.setIsAdminActiveAsUser(true); - userManagerShadow.addProfile(new UserInfo(123, null, 0)); - userManagerShadow.addUserProfile(new UserHandle(123)); - ShadowProcess.setUid(Process.SYSTEM_UID); + createShadowWorkProfile(userManagerShadow); mHelper.setAdminSupportDetails(mActivity, view, admin); + assertNotNull(admin.component); assertEquals("some message", Shadows.shadowOf(textView).innerText()); } @@ -175,16 +200,40 @@ public class ActionDisabledByAdminDialogHelperTest { final UserManager userManager = RuntimeEnvironment.application.getSystemService( UserManager.class); final ShadowUserManager userManagerShadow = Shadow.extract(userManager); + final ViewGroup view = new FrameLayout(mActivity); final ComponentName component = new ComponentName("some.package.name", "some.package.name.SomeClass"); final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123)); - + final TextView textView = createAdminSupportTextView(view, mActivity); dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); dpmShadow.setIsAdminActiveAsUser(false); userManagerShadow.addProfile(new UserInfo(123, null, 0)); - mHelper.setAdminSupportDetails(mActivity, null, admin); + mHelper.setAdminSupportDetails(mActivity, textView, admin); + assertNull(admin.component); + assertEquals(mActivity.getString(R.string.default_admin_support_msg), + Shadows.shadowOf(textView).innerText()); + } + + @Test + public void testSetAdminSupportDetailsForFinancedDevice_shortSupportMessageIsNull() { + final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow(); + final UserManager userManager = RuntimeEnvironment.application.getSystemService( + UserManager.class); + final ShadowUserManager userManagerShadow = Shadow.extract(userManager); + final ViewGroup view = new FrameLayout(mActivity); + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123)); + final TextView textView = createAdminSupportTextView(view, mActivity); + setupFinancedDevice(dpmShadow); + createShadowWorkProfile(userManagerShadow); + + mHelper.setAdminSupportDetails(mActivity, view, admin); + + assertNotNull(admin.component); + assertEquals("", Shadows.shadowOf(textView).innerText()); } @Test @@ -210,4 +259,44 @@ public class ActionDisabledByAdminDialogHelperTest { mHelper.maybeSetLearnMoreButton(builder); verify(builder, never()).setNeutralButton(anyInt(), any()); } + + private static ImageView createAdminSupportIconImageView(final ViewGroup view, + final Activity activity) { + final ImageView supportIconView = new ImageView(activity); + supportIconView.setId(R.id.admin_support_icon); + view.addView(supportIconView); + return supportIconView; + } + + private static TextView createAdminSupportDialogTitleTextView(final ViewGroup view, + final Activity activity) { + final TextView textView = new TextView(activity); + textView.setId(R.id.admin_support_dialog_title); + view.addView(textView); + return textView; + } + + private static TextView createAdminSupportTextView(final ViewGroup view, + final Activity activity) { + final TextView textView = new TextView(activity); + textView.setId(R.id.admin_support_msg); + view.addView(textView); + return textView; + } + + private static void createShadowWorkProfile(final ShadowUserManager userManagerShadow) { + userManagerShadow.addProfile(new UserInfo(123, null, 0)); + userManagerShadow.addUserProfile(new UserHandle(123)); + ShadowProcess.setUid(Process.SYSTEM_UID); + } + + private static void setupFinancedDevice(final ShadowDevicePolicyManager dpmShadow) { + final ComponentName component = new ComponentName("some.package.name", + "some.package.name.SomeClass"); + dpmShadow.setDeviceOwner(component); + dpmShadow.setDeviceOwnerComponentOnAnyUser(component); + dpmShadow.setDeviceOwnerType(component, DEVICE_OWNER_TYPE_FINANCED); + dpmShadow.setShortSupportMessageForUser(component, 123, null); + dpmShadow.setIsAdminActiveAsUser(true); + } } diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java index b8fdf89cd17..a2e4430a455 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDevicePolicyManager.java @@ -1,11 +1,13 @@ package com.android.settings.testutils.shadow; +import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT; import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.admin.DevicePolicyManager; +import android.app.admin.DevicePolicyManager.DeviceOwnerType; import android.app.admin.PasswordMetrics; import android.app.admin.PasswordPolicy; import android.content.ComponentName; @@ -23,6 +25,7 @@ import java.util.Objects; public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager { private final Map mProfileTimeouts = new HashMap<>(); + private final Map mDeviceOwnerTypes = new HashMap<>(); private Map mSupportMessagesMap = new HashMap<>(); private boolean mIsAdminActiveAsUser = false; private ComponentName mDeviceOwnerComponentName; @@ -77,6 +80,16 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev mDeviceOwnerComponentName = admin; } + public void setDeviceOwnerType(@NonNull ComponentName admin, + @DeviceOwnerType int deviceOwnerType) { + mDeviceOwnerTypes.put(admin.getPackageName(), deviceOwnerType); + } + + @DeviceOwnerType + public int getDeviceOwnerType(@NonNull ComponentName admin) { + return mDeviceOwnerTypes.getOrDefault(admin.getPackageName(), DEVICE_OWNER_TYPE_DEFAULT); + } + @Implementation public PasswordMetrics getPasswordMinimumMetrics(int userHandle) { PasswordPolicy policy = new PasswordPolicy();