Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0e7d1c49 authored by Pavel Grafov's avatar Pavel Grafov
Browse files

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
parent db87672d
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -442,19 +442,19 @@
    <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
        blocked due to a work policy from their IT admin, and tells them what they need to do
        to unblock their apps.[CHAR LIMIT=29] -->
    <string name="personal_apps_suspended_title">Unblock your personal apps</string>
    <!-- Notification title. This notification lets a user know that their apps will be blocked
        tomorrow due to a work policy from their IT admin, and tells them what they need to do to
        prevent the apps from being blocked. [CHAR LIMIT=29] -->
    <string name="personal_apps_suspended_tomorrow_title">Apps will be blocked tomorrow</string>
    <!-- Notification text. This notification lets a user know that they need to turn on their
        work profile due to a work policy from their IT admin. The number of days is at least 3.
        [CHAR LIMIT=NONE] -->
    <string name="personal_apps_suspended_text">Your IT admin doesn\u2019t allow your
        work profile to be paused for more than <xliff:g id="days" example="3">%1$d</xliff:g>
        days</string>
        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] -->
    <string name="personal_apps_suspension_title">Turn on your work profile</string>
    <!-- Notification text. This notification lets a user know that their personal apps are
        blocked 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=NONE] -->
    <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>
    <!-- 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>
+3 −3
Original line number Diff line number Diff line
@@ -1197,9 +1197,9 @@
  <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_text" />
  <java-symbol type="string" name="personal_apps_suspended_title" />
  <java-symbol type="string" name="personal_apps_suspended_tomorrow_title" />
  <java-symbol type="string" name="personal_apps_suspended_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_text" />
  <java-symbol type="string" name="factory_reset_warning" />
  <java-symbol type="string" name="factory_reset_message" />
  <java-symbol type="string" name="lockscreen_transport_play_description" />
+23 −18
Original line number Diff line number Diff line
@@ -15938,20 +15938,29 @@ 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);
@@ -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();
+36 −13
Original line number Diff line number Diff line
@@ -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<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>() {
            @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("}");
            }
        };
    }