Update Action Not Allowed Dialog text for a financed device

Bug: 173826319
Bug: 158157476
Test: Used a test device that is registered via ZT
Test: m RunSettingsRoboTests ROBOTEST_FILTER=ActionDisabledByAdminDialogHelperTest

Change-Id: Iefeb0b653764952e409dfd862d9cc54c4f5e7fc9
This commit is contained in:
Salud Lemus
2021-03-02 01:01:00 +00:00
parent 5e57390696
commit b45d87715a
5 changed files with 167 additions and 35 deletions

View File

@@ -49,7 +49,6 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.HeadLineFontFamily.Subhead" android:textAppearance="@style/TextAppearance.HeadLineFontFamily.Subhead"
android:text="@string/default_admin_support_msg"
android:maxLength="200" android:maxLength="200"
android:autoLink="email|phone|web" android:autoLink="email|phone|web"
android:textColor="?android:attr/textColorSecondary"/> android:textColor="?android:attr/textColorSecondary"/>

View File

@@ -10442,6 +10442,8 @@
<string name="disabled_by_policy_title_screen_capture">Screenshot not allowed</string> <string name="disabled_by_policy_title_screen_capture">Screenshot not allowed</string>
<!-- Title for dialog displayed to tell user that the app was suspended by an admin [CHAR LIMIT=50] --> <!-- Title for dialog displayed to tell user that the app was suspended by an admin [CHAR LIMIT=50] -->
<string name="disabled_by_policy_title_suspend_packages">Cant open this app</string> <string name="disabled_by_policy_title_suspend_packages">Cant open this app</string>
<!-- Dialog title. This dialog lets a user know that a specific setting is blocked by their credit provider. Since the user purchased the device from the credit provider, the credit provider controls what they can access. [CHAR LIMIT=50] -->
<string name="disabled_by_policy_title_financed_device">Blocked by your credit provider</string>
<!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] --> <!-- Shown when the user tries to change a settings locked by an admin [CHAR LIMIT=200] -->
<string name="default_admin_support_msg">If you have questions, contact your IT admin</string> <string name="default_admin_support_msg">If you have questions, contact your IT admin</string>
<!-- Shown in dialog to allow user to see more information about the device admin [CHAR LIMIT=30] --> <!-- Shown in dialog to allow user to see more information about the device admin [CHAR LIMIT=30] -->

View File

@@ -16,6 +16,8 @@
package com.android.settings.enterprise; package com.android.settings.enterprise;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_FINANCED;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.Activity; import android.app.Activity;
@@ -119,24 +121,11 @@ public class ActionDisabledByAdminDialogHelper {
if (admin == null) { if (admin == null) {
return; return;
} }
ImageView supportIconView = root.requireViewById(R.id.admin_support_icon);
if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(mActivity, admin) setAdminSupportIcon(root, admin, userId);
|| !RestrictedLockUtils.isCurrentUserOrProfile(mActivity, userId)) {
if (isNotCurrentUserOrProfile(admin, userId)) {
admin = null; 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); setAdminSupportTitle(root, restriction);
@@ -151,12 +140,44 @@ public class ActionDisabledByAdminDialogHelper {
setAdminSupportDetails(mActivity, root, new EnforcedAdmin(admin, user)); 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 @VisibleForTesting
void setAdminSupportTitle(View root, String restriction) { void setAdminSupportTitle(View root, String restriction) {
final TextView titleView = root.findViewById(R.id.admin_support_dialog_title); final TextView titleView = root.findViewById(R.id.admin_support_dialog_title);
if (titleView == null) { if (titleView == null) {
return; return;
} }
if (isFinancedDevice()) {
titleView.setText(R.string.disabled_by_policy_title_financed_device);
return;
}
if (restriction == null) { if (restriction == null) {
titleView.setText(R.string.disabled_by_policy_title); titleView.setText(R.string.disabled_by_policy_title);
return; return;
@@ -195,6 +216,7 @@ public class ActionDisabledByAdminDialogHelper {
final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService( final DevicePolicyManager dpm = (DevicePolicyManager) activity.getSystemService(
Context.DEVICE_POLICY_SERVICE); Context.DEVICE_POLICY_SERVICE);
CharSequence supportMessage = null;
if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity, if (!RestrictedLockUtilsInternal.isAdminInCurrentUserOrProfile(activity,
enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile( enforcedAdmin.component) || !RestrictedLockUtils.isCurrentUserOrProfile(
activity, getEnforcementAdminUserId(enforcedAdmin))) { activity, getEnforcementAdminUserId(enforcedAdmin))) {
@@ -203,15 +225,16 @@ public class ActionDisabledByAdminDialogHelper {
if (enforcedAdmin.user == null) { if (enforcedAdmin.user == null) {
enforcedAdmin.user = UserHandle.of(UserHandle.myUserId()); enforcedAdmin.user = UserHandle.of(UserHandle.myUserId());
} }
CharSequence supportMessage = null;
if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) { if (UserHandle.isSameApp(Process.myUid(), Process.SYSTEM_UID)) {
supportMessage = dpm.getShortSupportMessageForUser(enforcedAdmin.component, supportMessage = dpm.getShortSupportMessageForUser(enforcedAdmin.component,
getEnforcementAdminUserId(enforcedAdmin)); 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); activity.startActivity(intent);
} }
} }
private boolean isFinancedDevice() {
final DevicePolicyManager dpm = mActivity.getSystemService(DevicePolicyManager.class);
return dpm.isDeviceManaged() && dpm.getDeviceOwnerType(
dpm.getDeviceOwnerComponentOnAnyUser()) == DEVICE_OWNER_TYPE_FINANCED;
}
} }

View File

@@ -16,6 +16,8 @@
package com.android.settings.enterprise; 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.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
@@ -34,8 +36,10 @@ import android.content.pm.UserInfo;
import android.os.Process; import android.os.Process;
import android.os.UserHandle; import android.os.UserHandle;
import android.os.UserManager; import android.os.UserManager;
import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
@@ -104,12 +108,24 @@ public class ActionDisabledByAdminDialogHelperTest {
Settings.DeviceAdminSettingsActivity.class.getName())); 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 @Test
public void testSetAdminSupportTitle() { public void testSetAdminSupportTitle() {
final ViewGroup view = new FrameLayout(mActivity); final ViewGroup view = new FrameLayout(mActivity);
final TextView textView = new TextView(mActivity); final TextView textView = createAdminSupportDialogTitleTextView(view, mActivity);
textView.setId(R.id.admin_support_dialog_title);
view.addView(textView);
mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_ADJUST_VOLUME); mHelper.setAdminSupportTitle(view, UserManager.DISALLOW_ADJUST_VOLUME);
assertEquals(Shadows.shadowOf(textView).innerText(), assertEquals(Shadows.shadowOf(textView).innerText(),
@@ -144,6 +160,19 @@ public class ActionDisabledByAdminDialogHelperTest {
mActivity.getString(R.string.disabled_by_policy_title)); 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 @Test
public void testSetAdminSupportDetails() { public void testSetAdminSupportDetails() {
final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow(); final ShadowDevicePolicyManager dpmShadow = ShadowDevicePolicyManager.getShadow();
@@ -154,17 +183,13 @@ public class ActionDisabledByAdminDialogHelperTest {
final ComponentName component = new ComponentName("some.package.name", final ComponentName component = new ComponentName("some.package.name",
"some.package.name.SomeClass"); "some.package.name.SomeClass");
final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123)); final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123));
final TextView textView = new TextView(mActivity); final TextView textView = createAdminSupportTextView(view, mActivity);
textView.setId(R.id.admin_support_msg);
view.addView(textView);
dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); dpmShadow.setShortSupportMessageForUser(component, 123, "some message");
dpmShadow.setIsAdminActiveAsUser(true); dpmShadow.setIsAdminActiveAsUser(true);
userManagerShadow.addProfile(new UserInfo(123, null, 0)); createShadowWorkProfile(userManagerShadow);
userManagerShadow.addUserProfile(new UserHandle(123));
ShadowProcess.setUid(Process.SYSTEM_UID);
mHelper.setAdminSupportDetails(mActivity, view, admin); mHelper.setAdminSupportDetails(mActivity, view, admin);
assertNotNull(admin.component); assertNotNull(admin.component);
assertEquals("some message", Shadows.shadowOf(textView).innerText()); assertEquals("some message", Shadows.shadowOf(textView).innerText());
} }
@@ -175,16 +200,40 @@ public class ActionDisabledByAdminDialogHelperTest {
final UserManager userManager = RuntimeEnvironment.application.getSystemService( final UserManager userManager = RuntimeEnvironment.application.getSystemService(
UserManager.class); UserManager.class);
final ShadowUserManager userManagerShadow = Shadow.extract(userManager); final ShadowUserManager userManagerShadow = Shadow.extract(userManager);
final ViewGroup view = new FrameLayout(mActivity);
final ComponentName component = new ComponentName("some.package.name", final ComponentName component = new ComponentName("some.package.name",
"some.package.name.SomeClass"); "some.package.name.SomeClass");
final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123)); final EnforcedAdmin admin = new EnforcedAdmin(component, UserHandle.of(123));
final TextView textView = createAdminSupportTextView(view, mActivity);
dpmShadow.setShortSupportMessageForUser(component, 123, "some message"); dpmShadow.setShortSupportMessageForUser(component, 123, "some message");
dpmShadow.setIsAdminActiveAsUser(false); dpmShadow.setIsAdminActiveAsUser(false);
userManagerShadow.addProfile(new UserInfo(123, null, 0)); userManagerShadow.addProfile(new UserInfo(123, null, 0));
mHelper.setAdminSupportDetails(mActivity, null, admin); mHelper.setAdminSupportDetails(mActivity, textView, admin);
assertNull(admin.component); 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 @Test
@@ -210,4 +259,44 @@ public class ActionDisabledByAdminDialogHelperTest {
mHelper.maybeSetLearnMoreButton(builder); mHelper.maybeSetLearnMoreButton(builder);
verify(builder, never()).setNeutralButton(anyInt(), any()); 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);
}
} }

View File

@@ -1,11 +1,13 @@
package com.android.settings.testutils.shadow; 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 static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.admin.DevicePolicyManager; import android.app.admin.DevicePolicyManager;
import android.app.admin.DevicePolicyManager.DeviceOwnerType;
import android.app.admin.PasswordMetrics; import android.app.admin.PasswordMetrics;
import android.app.admin.PasswordPolicy; import android.app.admin.PasswordPolicy;
import android.content.ComponentName; import android.content.ComponentName;
@@ -23,6 +25,7 @@ import java.util.Objects;
public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager { public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDevicePolicyManager {
private final Map<Integer, Long> mProfileTimeouts = new HashMap<>(); private final Map<Integer, Long> mProfileTimeouts = new HashMap<>();
private final Map<String, Integer> mDeviceOwnerTypes = new HashMap<>();
private Map<Integer, CharSequence> mSupportMessagesMap = new HashMap<>(); private Map<Integer, CharSequence> mSupportMessagesMap = new HashMap<>();
private boolean mIsAdminActiveAsUser = false; private boolean mIsAdminActiveAsUser = false;
private ComponentName mDeviceOwnerComponentName; private ComponentName mDeviceOwnerComponentName;
@@ -77,6 +80,16 @@ public class ShadowDevicePolicyManager extends org.robolectric.shadows.ShadowDev
mDeviceOwnerComponentName = admin; 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 @Implementation
public PasswordMetrics getPasswordMinimumMetrics(int userHandle) { public PasswordMetrics getPasswordMinimumMetrics(int userHandle) {
PasswordPolicy policy = new PasswordPolicy(); PasswordPolicy policy = new PasswordPolicy();