Merge "Update personal apps suspension strings." into rvc-dev am: 3b8aa15911

Change-Id: I5914bc2391a5f73caaced1052b08f7ceb76951ba
This commit is contained in:
Pavel Grafov
2020-04-28 13:54:03 +00:00
committed by Automerger Merge Worker
4 changed files with 75 additions and 47 deletions

View File

@@ -442,19 +442,19 @@
<string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string> <string name="printing_disabled_by">Printing disabled by <xliff:g id="owner_app">%s</xliff:g>.</string>
<!-- Notification title. This notification lets a user know that their personal apps are <!-- Notification title. This notification lets a user know that their personal apps are
blocked due to a work policy from their IT admin, and tells them what they need to do either blocked or will be blocked soon due to a work policy from their IT admin, and that
to unblock their apps.[CHAR LIMIT=29] --> they need to turn on their work profile to unblock their apps.[CHAR LIMIT=29] -->
<string name="personal_apps_suspended_title">Unblock your personal apps</string> <string name="personal_apps_suspension_title">Turn on your work profile</string>
<!-- Notification title. This notification lets a user know that their apps will be blocked <!-- Notification text. This notification lets a user know that their personal apps are
tomorrow due to a work policy from their IT admin, and tells them what they need to do to blocked due to a work policy from their IT admin, and that they need to turn on their work
prevent the apps from being blocked. [CHAR LIMIT=29] --> profile to unblock their apps.[CHAR LIMIT=NONE] -->
<string name="personal_apps_suspended_tomorrow_title">Apps will be blocked tomorrow</string> <string name="personal_apps_suspension_text">
<!-- Notification text. This notification lets a user know that they need to turn on their Your personal apps are blocked until you turn on your work profile</string>
work profile due to a work policy from their IT admin. The number of days is at least 3. <!-- Notification text. This notification lets a user know that their apps will be blocked
[CHAR LIMIT=NONE] --> tomorrow due to a work policy from their IT admin, and that they need to turn on their work
<string name="personal_apps_suspended_text">Your IT admin doesn\u2019t allow your profile to prevent the apps from being blocked. [CHAR LIMIT=NONE] -->
work profile to be paused for more than <xliff:g id="days" example="3">%1$d</xliff:g> <string name="personal_apps_suspension_tomorrow_text">
days</string> Your personal apps will be blocked tomorrow</string>
<!-- Title for the button that turns work profile on. To be used in a notification <!-- Title for the button that turns work profile on. To be used in a notification
[CHAR LIMIT=NONE] --> [CHAR LIMIT=NONE] -->
<string name="personal_apps_suspended_turn_profile_on">Turn on work profile</string> <string name="personal_apps_suspended_turn_profile_on">Turn on work profile</string>

View File

@@ -1197,9 +1197,9 @@
<java-symbol type="string" name="network_logging_notification_text" /> <java-symbol type="string" name="network_logging_notification_text" />
<java-symbol type="string" name="location_changed_notification_title" /> <java-symbol type="string" name="location_changed_notification_title" />
<java-symbol type="string" name="location_changed_notification_text" /> <java-symbol type="string" name="location_changed_notification_text" />
<java-symbol type="string" name="personal_apps_suspended_title" /> <java-symbol type="string" name="personal_apps_suspension_title" />
<java-symbol type="string" name="personal_apps_suspended_tomorrow_title" /> <java-symbol type="string" name="personal_apps_suspension_tomorrow_text" />
<java-symbol type="string" name="personal_apps_suspended_text" /> <java-symbol type="string" name="personal_apps_suspension_text" />
<java-symbol type="string" name="factory_reset_warning" /> <java-symbol type="string" name="factory_reset_warning" />
<java-symbol type="string" name="factory_reset_message" /> <java-symbol type="string" name="factory_reset_message" />
<java-symbol type="string" name="lockscreen_transport_play_description" /> <java-symbol type="string" name="lockscreen_transport_play_description" />

View File

@@ -15948,22 +15948,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
*/ */
private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) { private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) {
final boolean suspended; final boolean suspended;
final int deadlineState;
final String poPackage;
synchronized (getLockObject()) { synchronized (getLockObject()) {
final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId);
if (profileOwner != null) { if (profileOwner != null) {
final int deadlineState = deadlineState =
updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked);
suspended = profileOwner.mSuspendPersonalApps suspended = profileOwner.mSuspendPersonalApps
|| deadlineState == PROFILE_OFF_DEADLINE_REACHED; || deadlineState == PROFILE_OFF_DEADLINE_REACHED;
Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d", poPackage = profileOwner.info.getPackageName();
suspended, deadlineState));
updateProfileOffDeadlineNotificationLocked(profileUserId, profileOwner,
unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState);
} else { } else {
poPackage = null;
suspended = false; suspended = false;
deadlineState = PROFILE_OFF_DEADLINE_DEFAULT;
} }
} }
Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d",
suspended, deadlineState));
if (poPackage != null) {
final int notificationState = unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState;
updateProfileOffDeadlineNotification(profileUserId, poPackage, notificationState);
}
final int parentUserId = getProfileParentId(profileUserId); final int parentUserId = getProfileParentId(profileUserId);
suspendPersonalAppsInternal(parentUserId, suspended); suspendPersonalAppsInternal(parentUserId, suspended);
} }
@@ -16067,38 +16076,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
} }
} }
private void updateProfileOffDeadlineNotificationLocked(int profileUserId, private void updateProfileOffDeadlineNotification(
@Nullable ActiveAdmin profileOwner, int notificationState) { int profileUserId, String profileOwnerPackage, int notificationState) {
if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) { if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) {
mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED); mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED);
return; return;
} }
final String profileOwnerPackageName = profileOwner.info.getPackageName();
final long maxTimeOffDays =
TimeUnit.MILLISECONDS.toDays(profileOwner.mProfileMaximumTimeOffMillis);
final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE); final Intent intent = new Intent(DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE);
intent.setPackage(profileOwnerPackageName); intent.setPackage(profileOwnerPackage);
final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext, final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext,
0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT,
null /* options */, UserHandle.of(profileUserId)); null /* options */, UserHandle.of(profileUserId));
// TODO(b/149075510): Only the first of the notifications should be dismissible. // TODO(b/149075510): Only the first of the notifications should be dismissible.
final String title = mContext.getString( final String text = mContext.getString(
notificationState == PROFILE_OFF_DEADLINE_WARNING notificationState == PROFILE_OFF_DEADLINE_WARNING
? R.string.personal_apps_suspended_tomorrow_title ? R.string.personal_apps_suspension_tomorrow_text
: R.string.personal_apps_suspended_title); : R.string.personal_apps_suspension_text);
final Notification notification = final Notification notification =
new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN)
.setSmallIcon(android.R.drawable.stat_sys_warning) .setSmallIcon(android.R.drawable.stat_sys_warning)
.setOngoing(true) .setOngoing(true)
.setContentTitle(title) .setContentTitle(mContext.getString(
.setContentText(mContext.getString( R.string.personal_apps_suspension_title))
R.string.personal_apps_suspended_text, maxTimeOffDays)) .setContentText(text)
.setColor(mContext.getColor(R.color.system_notification_accent_color)) .setColor(mContext.getColor(R.color.system_notification_accent_color))
.setContentIntent(pendingIntent) .setContentIntent(pendingIntent)
.build(); .build();

View File

@@ -15,6 +15,8 @@
*/ */
package com.android.server.devicepolicy; package com.android.server.devicepolicy;
import static android.app.Notification.EXTRA_TEXT;
import static android.app.Notification.EXTRA_TITLE;
import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS; import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL; import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO; import static android.app.admin.DevicePolicyManager.ID_TYPE_BASE_INFO;
@@ -195,9 +197,10 @@ public class DevicePolicyManagerTest extends DpmTestBase {
PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1); PROFILE_OFF_START + PROFILE_OFF_TIMEOUT - TimeUnit.DAYS.toMillis(1);
// Time when the apps should be suspended // Time when the apps should be suspended
private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT; private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT;
// Notification titles for setManagedProfileMaximumTimeOff tests: // Notification title and text for setManagedProfileMaximumTimeOff tests:
private static final String PROFILE_OFF_WARNING_TITLE = "suspended_tomorrow"; private static final String PROFILE_OFF_SUSPENSION_TITLE = "suspension_title";
private static final String PROFILE_OFF_SUSPENDED_TITLE = "suspended"; private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text";
private static final String PROFILE_OFF_SUSPENSION_TOMORROW_TEXT = "suspension_tomorrow_text";
@Override @Override
protected void setUp() throws Exception { protected void setUp() throws Exception {
@@ -1576,7 +1579,9 @@ public class DevicePolicyManagerTest extends DpmTestBase {
dpms.approveCaCert(fourCerts.getList().get(1), userId, true); dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
// a notification should be shown saying that there are two certificates left to approve. // a notification should be shown saying that there are two certificates left to approve.
verify(getServices().notificationManager, timeout(1000)) verify(getServices().notificationManager, timeout(1000))
.notifyAsUser(anyString(), anyInt(), argThat(hasTitle(TEST_STRING)), eq(user)); .notifyAsUser(anyString(), anyInt(), argThat(hasExtra(EXTRA_TITLE,
TEST_STRING
)), eq(user));
} }
/** /**
@@ -6317,7 +6322,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any()); verify(getServices().alarmManager, times(1)).set(anyInt(), eq(PROFILE_OFF_DEADLINE), any());
// Now the user should see a warning notification. // Now the user should see a warning notification.
verify(getServices().notificationManager, times(1)) verify(getServices().notificationManager, times(1))
.notify(anyInt(), argThat(hasTitle(PROFILE_OFF_WARNING_TITLE))); .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE,
EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TOMORROW_TEXT)));
// Apps shouldn't be suspended yet. // Apps shouldn't be suspended yet.
verifyZeroInteractions(getServices().ipackageManager); verifyZeroInteractions(getServices().ipackageManager);
clearInvocations(getServices().alarmManager); clearInvocations(getServices().alarmManager);
@@ -6331,7 +6337,8 @@ public class DevicePolicyManagerTest extends DpmTestBase {
verifyZeroInteractions(getServices().alarmManager); verifyZeroInteractions(getServices().alarmManager);
// Now the user should see a notification about suspended apps. // Now the user should see a notification about suspended apps.
verify(getServices().notificationManager, times(1)) verify(getServices().notificationManager, times(1))
.notify(anyInt(), argThat(hasTitle(PROFILE_OFF_SUSPENDED_TITLE))); .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE,
EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TEXT)));
// Verify that the apps are suspended. // Verify that the apps are suspended.
verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser( verify(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser(
any(), eq(true), any(), any(), any(), any(), anyInt()); any(), eq(true), any(), any(), any(), any(), anyInt());
@@ -6461,25 +6468,41 @@ public class DevicePolicyManagerTest extends DpmTestBase {
// Setup notification titles. // Setup notification titles.
when(mServiceContext.resources when(mServiceContext.resources
.getString(R.string.personal_apps_suspended_tomorrow_title)) .getString(R.string.personal_apps_suspension_title))
.thenReturn(PROFILE_OFF_WARNING_TITLE); .thenReturn(PROFILE_OFF_SUSPENSION_TITLE);
when(mServiceContext.resources when(mServiceContext.resources
.getString(R.string.personal_apps_suspended_title)) .getString(R.string.personal_apps_suspension_text))
.thenReturn(PROFILE_OFF_SUSPENDED_TITLE); .thenReturn(PROFILE_OFF_SUSPENSION_TEXT);
when(mServiceContext.resources
.getString(R.string.personal_apps_suspension_tomorrow_text))
.thenReturn(PROFILE_OFF_SUSPENSION_TOMORROW_TEXT);
clearInvocations(getServices().ipackageManager); clearInvocations(getServices().ipackageManager);
} }
private static Matcher<Notification> hasTitle(String expected) { private static Matcher<Notification> hasExtra(String... extras) {
assertEquals("Odd numebr of extra key-values", 0, extras.length % 2);
return new BaseMatcher<Notification>() { return new BaseMatcher<Notification>() {
@Override @Override
public boolean matches(Object item) { public boolean matches(Object item) {
final Notification notification = (Notification) item; final Notification notification = (Notification) item;
return expected.equals(notification.extras.getString(Notification.EXTRA_TITLE)); for (int i = 0; i < extras.length / 2; i++) {
if (!extras[i * 2 + 1].equals(notification.extras.getString(extras[i * 2]))) {
return false;
}
}
return true;
} }
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText("Notification{title=\"" + expected + "\"}"); description.appendText("Notification{");
for (int i = 0; i < extras.length / 2; i++) {
if (i > 0) {
description.appendText(",");
}
description.appendText(extras[i * 2] + "=\"" + extras[i * 2 + 1] + "\"");
}
description.appendText("}");
} }
}; };
} }