Merge "Update personal apps suspension strings." into rvc-dev am: 3b8aa15911
Change-Id: I5914bc2391a5f73caaced1052b08f7ceb76951ba
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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("}");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user