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

Commit cf69683d authored by Annie Meng's avatar Annie Meng Committed by Android (Google) Code Review
Browse files

Merge "Support B&R of notifications in non-system users"

parents de626e05 8b646fdf
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -18,9 +18,7 @@ package com.android.server.backup;

import android.app.INotificationManager;
import android.app.backup.BlobBackupHelper;
import android.content.Context;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;

@@ -34,9 +32,11 @@ public class NotificationBackupHelper extends BlobBackupHelper {
    // Key under which the payload blob is stored
    static final String KEY_NOTIFICATIONS = "notifications";

    public NotificationBackupHelper(Context context) {
    private final int mUserId;

    public NotificationBackupHelper(int userId) {
        super(BLOB_VERSION, KEY_NOTIFICATIONS);
        // context is currently unused
        mUserId = userId;
    }

    @Override
@@ -46,8 +46,7 @@ public class NotificationBackupHelper extends BlobBackupHelper {
            try {
                INotificationManager nm = INotificationManager.Stub.asInterface(
                        ServiceManager.getService("notification"));
                // TODO: http://b/22388012
                newPayload = nm.getBackupPayload(UserHandle.USER_SYSTEM);
                newPayload = nm.getBackupPayload(mUserId);
            } catch (Exception e) {
                // Treat as no data
                Slog.e(TAG, "Couldn't communicate with notification manager");
@@ -67,8 +66,7 @@ public class NotificationBackupHelper extends BlobBackupHelper {
            try {
                INotificationManager nm = INotificationManager.Stub.asInterface(
                        ServiceManager.getService("notification"));
                // TODO: http://b/22388012
                nm.applyRestore(payload, UserHandle.USER_SYSTEM);
                nm.applyRestore(payload, mUserId);
            } catch (Exception e) {
                Slog.e(TAG, "Couldn't communicate with notification manager");
            }
+2 −2
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ public class SystemBackupAgent extends BackupAgentHelper {
    private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY;

    private static final Set<String> sEligibleForMultiUser = Sets.newArraySet(
            PERMISSION_HELPER);
            PERMISSION_HELPER, NOTIFICATION_HELPER);

    private int mUserId = UserHandle.USER_SYSTEM;

@@ -93,7 +93,7 @@ public class SystemBackupAgent extends BackupAgentHelper {

        addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this));
        addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper());
        addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this));
        addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(mUserId));
        addHelper(PERMISSION_HELPER, new PermissionBackupHelper(mUserId));
        addHelper(USAGE_STATS_HELPER, new UsageStatsBackupHelper(this));
        addHelper(SHORTCUT_MANAGER_HELPER, new ShortcutBackupHelper());
+35 −38
Original line number Diff line number Diff line
@@ -306,18 +306,21 @@ abstract public class ManagedServices {
        }
    }

    public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
    public void writeXml(XmlSerializer out, boolean forBackup, int userId) throws IOException {
        out.startTag(null, getConfig().xmlTag);

        out.attribute(null, ATT_VERSION, String.valueOf(DB_VERSION));

        if (forBackup) {
            trimApprovedListsAccordingToInstalledServices();
            trimApprovedListsAccordingToInstalledServices(userId);
        }

        final int N = mApproved.size();
        for (int i = 0 ; i < N; i++) {
            final int userId = mApproved.keyAt(i);
            final int approvedUserId = mApproved.keyAt(i);
            if (forBackup && approvedUserId != userId) {
                continue;
            }
            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
            if (approvedByType != null) {
                final int M = approvedByType.size();
@@ -328,14 +331,14 @@ abstract public class ManagedServices {
                        String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
                        out.startTag(null, TAG_MANAGED_SERVICES);
                        out.attribute(null, ATT_APPROVED_LIST, allowedItems);
                        out.attribute(null, ATT_USER_ID, Integer.toString(userId));
                        out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId));
                        out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
                        out.endTag(null, TAG_MANAGED_SERVICES);

                        if (!forBackup && isPrimary) {
                            // Also write values to settings, for observers who haven't migrated yet
                            Settings.Secure.putStringForUser(mContext.getContentResolver(),
                                    getConfig().secureSettingName, allowedItems, userId);
                                    getConfig().secureSettingName, allowedItems, approvedUserId);
                        }

                    }
@@ -350,15 +353,12 @@ abstract public class ManagedServices {
        loadAllowedComponentsFromSettings();
    }

    public void readXml(XmlPullParser parser, Predicate<String> allowedManagedServicePackages)
    public void readXml(
            XmlPullParser parser,
            Predicate<String> allowedManagedServicePackages,
            boolean forRestore,
            int userId)
            throws XmlPullParserException, IOException {
        // upgrade xml
        int xmlVersion = XmlUtils.readIntAttribute(parser, ATT_VERSION, 0);
        final List<UserInfo> activeUsers = mUm.getUsers(true);
        for (UserInfo userInfo : activeUsers) {
            upgradeXml(xmlVersion, userInfo.getUserHandle().getIdentifier());
        }

        // read grants
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -372,14 +372,16 @@ abstract public class ManagedServices {
                    Slog.i(TAG, "Read " + mConfig.caption + " permissions from xml");

                    final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
                    final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
                    // Ignore parser's user id for restore.
                    final int resolvedUserId = forRestore
                            ? userId : XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
                    final boolean isPrimary =
                            XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);

                    if (allowedManagedServicePackages == null ||
                            allowedManagedServicePackages.test(getPackageName(approved))) {
                        if (mUm.getUserInfo(userId) != null) {
                            addApprovedList(approved, userId, isPrimary);
                        if (mUm.getUserInfo(resolvedUserId) != null) {
                            addApprovedList(approved, resolvedUserId, isPrimary);
                        }
                        mUseXml = true;
                    }
@@ -389,8 +391,6 @@ abstract public class ManagedServices {
        rebindServices(false, USER_ALL);
    }

    protected void upgradeXml(final int xmlVersion, final int userId) {}

    private void loadAllowedComponentsFromSettings() {
        for (UserInfo user : mUm.getUsers()) {
            final ContentResolver cr = mContext.getContentResolver();
@@ -784,19 +784,17 @@ abstract public class ManagedServices {
        return allowedPackages;
    }

    private void trimApprovedListsAccordingToInstalledServices() {
        int N = mApproved.size();
        for (int i = 0 ; i < N; i++) {
            final int userId = mApproved.keyAt(i);
            final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
            int M = approvedByType.size();
            for (int j = 0; j < M; j++) {
                final ArraySet<String> approved = approvedByType.valueAt(j);
                int P = approved.size();
                for (int k = P - 1; k >= 0; k--) {
                    final String approvedPackageOrComponent = approved.valueAt(k);
    private void trimApprovedListsAccordingToInstalledServices(int userId) {
        final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
        if (approvedByType == null) {
            return;
        }
        for (int i = 0; i < approvedByType.size(); i++) {
            final ArraySet<String> approved = approvedByType.valueAt(i);
            for (int j = approved.size() - 1; j >= 0; j--) {
                final String approvedPackageOrComponent = approved.valueAt(j);
                if (!isValidEntry(approvedPackageOrComponent, userId)){
                        approved.removeAt(k);
                    approved.removeAt(j);
                    Slog.v(TAG, "Removing " + approvedPackageOrComponent
                            + " from approved list; no matching services found");
                } else {
@@ -808,7 +806,6 @@ abstract public class ManagedServices {
            }
        }
    }
    }

    private boolean removeUninstalledItemsFromApprovedLists(int uninstalledUserId, String pkg) {
        boolean removed = false;
+40 −27
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ import com.android.server.lights.LightsManager;
import com.android.server.notification.ManagedServices.ManagedServiceInfo;
import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.UserManagerService;
import com.android.server.policy.PhoneWindowManager;
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.uri.UriGrantsManagerInternal;
@@ -538,30 +539,49 @@ public class NotificationManagerService extends SystemService {
        }
    }

    void readPolicyXml(InputStream stream, boolean forRestore)
    UserManagerService getUserManagerService() {
        return UserManagerService.getInstance();
    }

    void readPolicyXml(InputStream stream, boolean forRestore, int userId)
            throws XmlPullParserException, NumberFormatException, IOException {
        final XmlPullParser parser = Xml.newPullParser();
        parser.setInput(stream, StandardCharsets.UTF_8.name());
        XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
        boolean migratedManagedServices = false;
        boolean ineligibleForManagedServices = forRestore
                && getUserManagerService().isManagedProfile(userId);
        int outerDepth = parser.getDepth();
        while (XmlUtils.nextElementWithin(parser, outerDepth)) {
            if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
                mZenModeHelper.readXml(parser, forRestore);
                mZenModeHelper.readXml(parser, forRestore, userId);
            } else if (PreferencesHelper.TAG_RANKING.equals(parser.getName())){
                mPreferencesHelper.readXml(parser, forRestore);
                mPreferencesHelper.readXml(parser, forRestore, userId);
            }
            if (mListeners.getConfig().xmlTag.equals(parser.getName())) {
                mListeners.readXml(parser, mAllowedManagedServicePackages);
                if (ineligibleForManagedServices) {
                    continue;
                }
                mListeners.readXml(parser, mAllowedManagedServicePackages, forRestore, userId);
                migratedManagedServices = true;
            } else if (mAssistants.getConfig().xmlTag.equals(parser.getName())) {
                mAssistants.readXml(parser, mAllowedManagedServicePackages);
                if (ineligibleForManagedServices) {
                    continue;
                }
                mAssistants.readXml(parser, mAllowedManagedServicePackages, forRestore, userId);
                migratedManagedServices = true;
            } else if (mConditionProviders.getConfig().xmlTag.equals(parser.getName())) {
                mConditionProviders.readXml(parser, mAllowedManagedServicePackages);
                if (ineligibleForManagedServices) {
                    continue;
                }
                mConditionProviders.readXml(
                        parser, mAllowedManagedServicePackages, forRestore, userId);
                migratedManagedServices = true;
            }
            if (LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_TAG.equals(parser.getName())) {
                if (forRestore && userId != UserHandle.USER_SYSTEM) {
                    continue;
                }
                mLockScreenAllowSecureNotifications =
                        safeBoolean(parser.getAttributeValue(null,
                                        LOCKSCREEN_ALLOW_SECURE_NOTIFICATIONS_VALUE), true);
@@ -584,7 +604,7 @@ public class NotificationManagerService extends SystemService {
            InputStream infile = null;
            try {
                infile = mPolicyFile.openRead();
                readPolicyXml(infile, false /*forRestore*/);
                readPolicyXml(infile, false /*forRestore*/, UserHandle.USER_ALL);
            } catch (FileNotFoundException e) {
                // No data yet
                // Load default managed services approvals
@@ -615,7 +635,7 @@ public class NotificationManagerService extends SystemService {
                }

                try {
                    writePolicyXml(stream, false /*forBackup*/);
                    writePolicyXml(stream, false /*forBackup*/, UserHandle.USER_ALL);
                    mPolicyFile.finishWrite(stream);
                } catch (IOException e) {
                    Slog.w(TAG, "Failed to save policy file, restoring backup", e);
@@ -626,18 +646,21 @@ public class NotificationManagerService extends SystemService {
        });
    }

    private void writePolicyXml(OutputStream stream, boolean forBackup) throws IOException {
    private void writePolicyXml(OutputStream stream, boolean forBackup, int userId)
            throws IOException {
        final XmlSerializer out = new FastXmlSerializer();
        out.setOutput(stream, StandardCharsets.UTF_8.name());
        out.startDocument(null, true);
        out.startTag(null, TAG_NOTIFICATION_POLICY);
        out.attribute(null, ATTR_VERSION, Integer.toString(DB_VERSION));
        mZenModeHelper.writeXml(out, forBackup, null);
        mPreferencesHelper.writeXml(out, forBackup);
        mListeners.writeXml(out, forBackup);
        mAssistants.writeXml(out, forBackup);
        mConditionProviders.writeXml(out, forBackup);
        mZenModeHelper.writeXml(out, forBackup, null, userId);
        mPreferencesHelper.writeXml(out, forBackup, userId);
        mListeners.writeXml(out, forBackup, userId);
        mAssistants.writeXml(out, forBackup, userId);
        mConditionProviders.writeXml(out, forBackup, userId);
        if (!forBackup || userId == UserHandle.USER_SYSTEM) {
            writeSecureNotificationsPolicy(out);
        }
        out.endTag(null, TAG_NOTIFICATION_POLICY);
        out.endDocument();
    }
@@ -3507,14 +3530,9 @@ public class NotificationManagerService extends SystemService {
        public byte[] getBackupPayload(int user) {
            checkCallerIsSystem();
            if (DBG) Slog.d(TAG, "getBackupPayload u=" + user);
            //TODO: http://b/22388012
            if (user != USER_SYSTEM) {
                Slog.w(TAG, "getBackupPayload: cannot backup policy for user " + user);
                return null;
            }
            final ByteArrayOutputStream baos = new ByteArrayOutputStream();
            try {
                writePolicyXml(baos, true /*forBackup*/);
                writePolicyXml(baos, true /*forBackup*/, user);
                return baos.toByteArray();
            } catch (IOException e) {
                Slog.w(TAG, "getBackupPayload: error writing payload for user " + user, e);
@@ -3531,14 +3549,9 @@ public class NotificationManagerService extends SystemService {
                Slog.w(TAG, "applyRestore: no payload to restore for user " + user);
                return;
            }
            //TODO: http://b/22388012
            if (user != USER_SYSTEM) {
                Slog.w(TAG, "applyRestore: cannot restore policy for user " + user);
                return;
            }
            final ByteArrayInputStream bais = new ByteArrayInputStream(payload);
            try {
                readPolicyXml(bais, true /*forRestore*/);
                readPolicyXml(bais, true /*forRestore*/, user);
                handleSavePolicyFile();
            } catch (NumberFormatException | XmlPullParserException | IOException e) {
                Slog.w(TAG, "applyRestore: error reading payload", e);
+9 −8
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ public class PreferencesHelper implements RankingConfig {
        syncChannelsBypassingDnd(mContext.getUserId());
    }

    public void readXml(XmlPullParser parser, boolean forRestore)
    public void readXml(XmlPullParser parser, boolean forRestore, int userId)
            throws XmlPullParserException, IOException {
        int type = parser.getEventType();
        if (type != XmlPullParser.START_TAG) return;
@@ -158,6 +158,9 @@ public class PreferencesHelper implements RankingConfig {
                }
                if (type == XmlPullParser.START_TAG) {
                    if (TAG_STATUS_ICONS.equals(tag)) {
                        if (forRestore && userId != UserHandle.USER_SYSTEM) {
                            continue;
                        }
                        mHideSilentStatusBarIcons = XmlUtils.readBooleanAttribute(
                                parser, ATT_HIDE_SILENT, DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
                    } else if (TAG_PACKAGE.equals(tag)) {
@@ -166,9 +169,7 @@ public class PreferencesHelper implements RankingConfig {
                        if (!TextUtils.isEmpty(name)) {
                            if (forRestore) {
                                try {
                                    //TODO: http://b/22388012
                                    uid = mPm.getPackageUidAsUser(name,
                                            UserHandle.USER_SYSTEM);
                                    uid = mPm.getPackageUidAsUser(name, userId);
                                } catch (PackageManager.NameNotFoundException e) {
                                    // noop
                                }
@@ -379,10 +380,11 @@ public class PreferencesHelper implements RankingConfig {
        r.channels.put(channel.getId(), channel);
    }

    public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
    public void writeXml(XmlSerializer out, boolean forBackup, int userId) throws IOException {
        out.startTag(null, TAG_RANKING);
        out.attribute(null, ATT_VERSION, Integer.toString(XML_VERSION));
        if (mHideSilentStatusBarIcons != DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS) {
        if (mHideSilentStatusBarIcons != DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS
                && (!forBackup || userId == UserHandle.USER_SYSTEM)) {
            out.startTag(null, TAG_STATUS_ICONS);
            out.attribute(null, ATT_HIDE_SILENT, String.valueOf(mHideSilentStatusBarIcons));
            out.endTag(null, TAG_STATUS_ICONS);
@@ -392,8 +394,7 @@ public class PreferencesHelper implements RankingConfig {
            final int N = mPackagePreferences.size();
            for (int i = 0; i < N; i++) {
                final PackagePreferences r = mPackagePreferences.valueAt(i);
                //TODO: http://b/22388012
                if (forBackup && UserHandle.getUserId(r.uid) != UserHandle.USER_SYSTEM) {
                if (forBackup && UserHandle.getUserId(r.uid) != userId) {
                    continue;
                }
                final boolean hasNonDefaultSettings =
Loading