From 0e7d1c49c10ccb945c0ff1b9ab19b83ffeddd4e6 Mon Sep 17 00:00:00 2001 From: Pavel Grafov Date: Mon, 27 Apr 2020 12:00:45 +0100 Subject: [PATCH] Update personal apps suspension strings. String resource names were renamed to differ from the old ones because the text used to require an integer argument. Also notification update moved out of synchronized block. Bug: 154912947 Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest Change-Id: I83997c2cf575f36bb2b53037ed9a68dfecc290a2 --- core/res/res/values/strings.xml | 26 +++++----- core/res/res/values/symbols.xml | 6 +-- .../DevicePolicyManagerService.java | 41 +++++++++------- .../devicepolicy/DevicePolicyManagerTest.java | 49 ++++++++++++++----- 4 files changed, 75 insertions(+), 47 deletions(-) diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 9c93c3e8cab1a..18a83736ca1d8 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 431549713f44d..12291b6e862c5 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 5d5e424db0179..ffd37b4911b99 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -15938,22 +15938,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); } @@ -16057,38 +16066,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("}"); } }; }