diff options
4 files changed, 52 insertions, 34 deletions
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 54d14f892e25..233f72eaae1f 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -451,10 +451,14 @@ <string name="personal_apps_suspension_text"> Your personal apps are blocked until you turn on your work profile</string> <!-- Notification text. This notification lets a user know that their apps will be blocked - tomorrow due to a work policy from their IT admin, and that they need to turn on their work - profile to prevent the apps from being blocked. [CHAR LIMIT=NONE] --> - <string name="personal_apps_suspension_tomorrow_text"> - Your personal apps will be blocked tomorrow</string> + at a particular time due to a work policy from their IT admin, and that they need to turn on + their work profile to prevent the apps from being blocked. It also explains for how many + days the profile is allowed to be off and this number is at least 3. [CHAR LIMIT=NONE] --> + <string name="personal_apps_suspension_soon_text"> + Personal apps will be blocked on <xliff:g id="date" example="May 29">%1$s</xliff:g> at + <xliff:g id="time" example="5:20 PM">%2$s</xliff:g>. Your work profile can\u2019t stay off + for more than <xliff:g id="number" example="3">%3$d</xliff:g> days. + </string> <!-- Title for the button that turns work profile on. To be used in a notification [CHAR LIMIT=NONE] --> <string name="personal_apps_suspended_turn_profile_on">Turn on work profile</string> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 64905ec9db7a..b483ee04a7ec 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1200,7 +1200,7 @@ <java-symbol type="string" name="location_changed_notification_title" /> <java-symbol type="string" name="location_changed_notification_text" /> <java-symbol type="string" name="personal_apps_suspension_title" /> - <java-symbol type="string" name="personal_apps_suspension_tomorrow_text" /> + <java-symbol type="string" name="personal_apps_suspension_soon_text" /> <java-symbol type="string" name="personal_apps_suspension_text" /> <java-symbol type="string" name="personal_apps_suspended_turn_profile_on" /> <java-symbol type="string" name="notification_work_profile_content_description" /> diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 0815ee523555..18c25c142113 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -247,6 +247,7 @@ import android.stats.devicepolicy.DevicePolicyEnums; import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.text.TextUtils; +import android.text.format.DateUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; @@ -16005,31 +16006,27 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private @PersonalAppsSuspensionReason int updatePersonalAppsSuspension( int profileUserId, boolean unlocked) { final boolean suspendedExplicitly; - final int deadlineState; - final String poPackage; + final boolean suspendedByTimeout; synchronized (getLockObject()) { final ActiveAdmin profileOwner = getProfileOwnerAdminLocked(profileUserId); if (profileOwner != null) { - deadlineState = + final int deadlineState = updateProfileOffDeadlineLocked(profileUserId, profileOwner, unlocked); suspendedExplicitly = profileOwner.mSuspendPersonalApps; - poPackage = profileOwner.info.getPackageName(); + suspendedByTimeout = deadlineState == PROFILE_OFF_DEADLINE_REACHED; + Slog.d(LOG_TAG, String.format( + "Personal apps suspended explicitly: %b, deadline state: %d", + suspendedExplicitly, deadlineState)); + final int notificationState = + unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState; + updateProfileOffDeadlineNotificationLocked( + profileUserId, profileOwner, notificationState); } else { - poPackage = null; suspendedExplicitly = false; - deadlineState = PROFILE_OFF_DEADLINE_DEFAULT; + suspendedByTimeout = false; } } - Slog.d(LOG_TAG, String.format("Personal apps suspended explicitly: %b, deadline state: %d", - suspendedExplicitly, deadlineState)); - - if (poPackage != null) { - final int notificationState = unlocked ? PROFILE_OFF_DEADLINE_DEFAULT : deadlineState; - updateProfileOffDeadlineNotification(profileUserId, poPackage, notificationState); - } - - final boolean suspendedByTimeout = deadlineState == PROFILE_OFF_DEADLINE_REACHED; final int parentUserId = getProfileParentId(profileUserId); suspendPersonalAppsInternal(parentUserId, suspendedExplicitly || suspendedByTimeout); @@ -16141,9 +16138,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void updateProfileOffDeadlineNotification( - int profileUserId, String profileOwnerPackage, int notificationState) { - + @GuardedBy("getLockObject()") + private void updateProfileOffDeadlineNotificationLocked( + int profileUserId, ActiveAdmin profileOwner, int notificationState) { if (notificationState == PROFILE_OFF_DEADLINE_DEFAULT) { mInjector.getNotificationManager().cancel(SystemMessage.NOTE_PERSONAL_APPS_SUSPENDED); return; @@ -16161,11 +16158,23 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { final Notification.Action turnProfileOnButton = new Notification.Action.Builder(null /* icon */, buttonText, pendingIntent).build(); - final String text = mContext.getString( - notificationState == PROFILE_OFF_DEADLINE_WARNING - ? R.string.personal_apps_suspension_tomorrow_text - : R.string.personal_apps_suspension_text); - final boolean ongoing = notificationState == PROFILE_OFF_DEADLINE_REACHED; + final String text; + final boolean ongoing; + if (notificationState == PROFILE_OFF_DEADLINE_WARNING) { + // Round to the closest integer number of days. + final int maxDays = (int) + ((profileOwner.mProfileMaximumTimeOffMillis + MS_PER_DAY / 2) / MS_PER_DAY); + final String date = DateUtils.formatDateTime( + mContext, profileOwner.mProfileOffDeadline, DateUtils.FORMAT_SHOW_DATE); + final String time = DateUtils.formatDateTime( + mContext, profileOwner.mProfileOffDeadline, DateUtils.FORMAT_SHOW_TIME); + text = mContext.getString( + R.string.personal_apps_suspension_soon_text, date, time, maxDays); + ongoing = false; + } else { + text = mContext.getString(R.string.personal_apps_suspension_text); + ongoing = true; + } final int color = mContext.getColor(R.color.personal_apps_suspension_notification_color); final Bundle extras = new Bundle(); // TODO: Create a separate string for this. 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 17dd2868f4bc..724048b1b8ee 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -204,7 +204,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // 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"; + private static final String PROFILE_OFF_SUSPENSION_SOON_TEXT = "suspension_tomorrow_text"; @Override protected void setUp() throws Exception { @@ -6331,7 +6331,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // Now the user should see a warning notification. verify(getServices().notificationManager, times(1)) .notify(anyInt(), argThat(hasExtra(EXTRA_TITLE, PROFILE_OFF_SUSPENSION_TITLE, - EXTRA_TEXT, PROFILE_OFF_SUSPENSION_TOMORROW_TEXT))); + EXTRA_TEXT, PROFILE_OFF_SUSPENSION_SOON_TEXT))); // Apps shouldn't be suspended yet. verifyZeroInteractions(getServices().ipackageManager); clearInvocations(getServices().alarmManager); @@ -6482,7 +6482,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { // To allow creation of Notification via Notification.Builder mContext.applicationInfo = mRealTestContext.getApplicationInfo(); - // Setup notification titles. + // Setup resources to render notification titles and texts. when(mServiceContext.resources .getString(R.string.personal_apps_suspension_title)) .thenReturn(PROFILE_OFF_SUSPENSION_TITLE); @@ -6490,14 +6490,19 @@ public class DevicePolicyManagerTest extends DpmTestBase { .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); + .getString(eq(R.string.personal_apps_suspension_soon_text), + anyString(), anyString(), anyInt())) + .thenReturn(PROFILE_OFF_SUSPENSION_SOON_TEXT); + + // Make locale available for date formatting: + when(mServiceContext.resources.getConfiguration()) + .thenReturn(mRealTestContext.getResources().getConfiguration()); clearInvocations(getServices().ipackageManager); } private static Matcher<Notification> hasExtra(String... extras) { - assertEquals("Odd numebr of extra key-values", 0, extras.length % 2); + assertEquals("Odd number of extra key-values", 0, extras.length % 2); return new BaseMatcher<Notification>() { @Override public boolean matches(Object item) { |