diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index c2b8c2a419bf8..c388f751e6283 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -442,19 +442,19 @@ Printing disabled by %s. - Unblock your personal apps - - Apps will be blocked tomorrow - - Your IT admin doesn\u2019t allow your - work profile to be paused for more than %1$d - days + either blocked or will be blocked soon due to a work policy from their IT admin, and that + they need to turn on their work profile to unblock their apps.[CHAR LIMIT=29] --> + Turn on your work profile + + + Your personal apps are blocked until you turn on your work profile + + + Your personal apps will be blocked tomorrow Turn on work profile diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index da64e77641911..67a9df49c88b2 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1197,9 +1197,9 @@ - - - + + + diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7e4c8f3e48e58..a74706be89157 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -15948,22 +15948,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { */ private void updatePersonalAppsSuspension(int profileUserId, boolean unlocked) { final boolean suspended; + final int deadlineState; + final String poPackage; synchronized (getLockObject()) { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); if (profileOwner != null) { - final int deadlineState = + deadlineState = updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); suspended = profileOwner.mSuspendPersonalApps || deadlineState == PROFILE_OFF_DEADLINE_REACHED; - Slog.d(LOG_TAG, String.format("Personal apps suspended: %b, deadline state: %d", - suspended, deadlineState)); - updateProfileOffDeadlineNotificationLocked(profileUserId, profileOwner, - unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState); + poPackage = profileOwner.info.getPackageName(); } else { + poPackage = null; 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); suspendPersonalAppsInternal(parentUserId, suspended); } @@ -16067,38 +16076,34 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void updateProfileOffDeadlineNotificationLocked(int profileUserId, - @Nullable ActiveAdmin profileOwner, int notificationState) { + private void updateProfileOffDeadlineNotification( + int profileUserId, String profileOwnerPackage, int notificationState) { if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) { mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED); 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); - intent.setPackage(profileOwnerPackageName); + intent.setPackage(profileOwnerPackage); final PendingIntent pendingIntent = mInjector.pendingIntentGetActivityAsUser(mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_UPDATE_CURRENT, null /* options */, UserHandle.of(profileUserId)); // 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 - ? R.string.personal_apps_suspended_tomorrow_title - : R.string.personal_apps_suspended_title); + ? R.string.personal_apps_suspension_tomorrow_text + : R.string.personal_apps_suspension_text); final Notification notification = new Notification.Builder(mContext, SystemNotificationChannels.DEVICE_ADMIN) .setSmallIcon(android.R.drawable.stat_sys_warning) .setOngoing(true) - .setContentTitle(title) - .setContentText(mContext.getString( - R.string.personal_apps_suspended_text, maxTimeOffDays)) + .setContentTitle(mContext.getString( + R.string.personal_apps_suspension_title)) + .setContentText(text) .setColor(mContext.getColor(R.color.system_notification_accent_color)) .setContentIntent(pendingIntent) .build(); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index b042e77946669..c2285081770e4 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -15,6 +15,8 @@ */ 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_CERT_INSTALL; 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); // Time when the apps should be suspended private static final long PROFILE_OFF_DEADLINE = PROFILE_OFF_START + PROFILE_OFF_TIMEOUT; - // Notification titles for setManagedProfileMaximumTimeOff tests: - private static final String PROFILE_OFF_WARNING_TITLE = "suspended_tomorrow"; - private static final String PROFILE_OFF_SUSPENDED_TITLE = "suspended"; + // Notification title and text for setManagedProfileMaximumTimeOff tests: + private static final String PROFILE_OFF_SUSPENSION_TITLE = "suspension_title"; + private static final String PROFILE_OFF_SUSPENSION_TEXT = "suspension_text"; + private static final String PROFILE_OFF_SUSPENSION_TOMORROW_TEXT = "suspension_tomorrow_text"; @Override protected void setUp() throws Exception { @@ -1576,7 +1579,9 @@ public class DevicePolicyManagerTest extends DpmTestBase { dpms.approveCaCert(fourCerts.getList().get(1), userId, true); // a notification should be shown saying that there are two certificates left to approve. 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()); // Now the user should see a warning notification. 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. verifyZeroInteractions(getServices().ipackageManager); clearInvocations(getServices().alarmManager); @@ -6331,7 +6337,8 @@ public class DevicePolicyManagerTest extends DpmTestBase { verifyZeroInteractions(getServices().alarmManager); // Now the user should see a notification about suspended apps. 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(getServices().ipackageManager, times(1)).setPackagesSuspendedAsUser( any(), eq(true), any(), any(), any(), any(), anyInt()); @@ -6461,25 +6468,41 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Setup notification titles. when(mServiceContext.resources - .getString(R.string.personal_apps_suspended_tomorrow_title)) - .thenReturn(PROFILE_OFF_WARNING_TITLE); + .getString(R.string.personal_apps_suspension_title)) + .thenReturn(PROFILE_OFF_SUSPENSION_TITLE); when(mServiceContext.resources - .getString(R.string.personal_apps_suspended_title)) - .thenReturn(PROFILE_OFF_SUSPENDED_TITLE); + .getString(R.string.personal_apps_suspension_text)) + .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); } - private static Matcher hasTitle(String expected) { + private static Matcher hasExtra(String... extras) { + assertEquals("Odd numebr of extra key-values", 0, extras.length % 2); return new BaseMatcher() { @Override public boolean matches(Object 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 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("}"); } }; }