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

Commit 665ce344 authored by Yuri Lin's avatar Yuri Lin Committed by Android (Google) Code Review
Browse files

Merge "Add user-set boolean to notification permission values."

parents e55fb53e d6e679f4
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -5073,7 +5073,7 @@ public class NotificationManagerService extends SystemService {
            final DumpFilter filter = DumpFilter.parseFromArguments(args);
            final long token = Binder.clearCallingIdentity();
            try {
                final ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions =
                final ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions =
                        getAllUsersNotificationPermissions();
                if (filter.stats) {
                    dumpJson(pw, filter, pkgPermissions);
@@ -5911,17 +5911,18 @@ public class NotificationManagerService extends SystemService {
    // Returns a single map containing that info keyed by (uid, package name) for all users.
    // Because this calls into mPermissionHelper, this method must never be called with a lock held.
    @VisibleForTesting
    protected ArrayMap<Pair<Integer, String>, Boolean> getAllUsersNotificationPermissions() {
    protected ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>>
            getAllUsersNotificationPermissions() {
        // don't bother if migration is not enabled
        if (!mEnableAppSettingMigration) {
            return null;
        }
        ArrayMap<Pair<Integer, String>, Boolean> allPermissions = new ArrayMap<>();
        ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> allPermissions = new ArrayMap<>();
        final List<UserInfo> allUsers = mUm.getUsers();
        // for each of these, get the package notification permissions that are associated
        // with this user and add it to the map
        for (UserInfo ui : allUsers) {
            ArrayMap<Pair<Integer, String>, Boolean> userPermissions =
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> userPermissions =
                    mPermissionHelper.getNotificationPermissionValues(
                            ui.getUserHandle().getIdentifier());
            for (Pair<Integer, String> pair : userPermissions.keySet()) {
@@ -5932,7 +5933,7 @@ public class NotificationManagerService extends SystemService {
    }

    private void dumpJson(PrintWriter pw, @NonNull DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        JSONObject dump = new JSONObject();
        try {
            dump.put("service", "Notification Manager");
@@ -5956,7 +5957,7 @@ public class NotificationManagerService extends SystemService {
    }

    private void dumpProto(FileDescriptor fd, @NonNull DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);
        synchronized (mNotificationLock) {
            int N = mNotificationList.size();
@@ -6047,7 +6048,7 @@ public class NotificationManagerService extends SystemService {
    }

    void dumpImpl(PrintWriter pw, @NonNull DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        pw.print("Current Notification Manager state");
        if (filter.filtered) {
            pw.print(" (filtered to "); pw.print(filter); pw.print(")");
+18 −6
Original line number Diff line number Diff line
@@ -36,10 +36,8 @@ import android.util.Slog;
import com.android.server.pm.permission.PermissionManagerServiceInternal;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@@ -139,15 +137,17 @@ public final class PermissionHelper {
        return granted;
    }

    // Key: (uid, package name); Value: (granted, user set)
    public @NonNull
    ArrayMap<Pair<Integer, String>, Boolean> getNotificationPermissionValues(
            int userId) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>>
                    getNotificationPermissionValues(int userId) {
        assertFlag();
        ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>();
        ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>();
        Set<Pair<Integer, String>> allRequestingUids = getAppsRequestingPermission(userId);
        Set<Pair<Integer, String>> allApprovedUids = getAppsGrantedPermission(userId);
        for (Pair<Integer, String> pair : allRequestingUids) {
            notifPermissions.put(pair, allApprovedUids.contains(pair));
            notifPermissions.put(pair, new Pair(allApprovedUids.contains(pair),
                    isPermissionUserSet(pair.second /* package name */, userId)));
        }
        return notifPermissions;
    }
@@ -196,6 +196,18 @@ public final class PermissionHelper {
        return false;
    }

    boolean isPermissionUserSet(String packageName, @UserIdInt int userId) {
        assertFlag();
        try {
            int flags = mPermManager.getPermissionFlags(packageName, NOTIFICATION_PERMISSION,
                    userId);
            return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0;
        } catch (RemoteException e) {
            Slog.e(TAG, "Could not reach system server", e);
        }
        return false;
    }

    private void assertFlag() {
        if (!mMigrationEnabled) {
            throw new IllegalStateException("Method called without checking flag value");
+29 −22
Original line number Diff line number Diff line
@@ -557,7 +557,7 @@ public class PreferencesHelper implements RankingConfig {
            out.attributeBoolean(null, ATT_HIDE_SILENT, mHideSilentStatusBarIcons);
            out.endTag(null, TAG_STATUS_ICONS);
        }
        ArrayMap<Pair<Integer, String>, Boolean> notifPermissions = new ArrayMap<>();
        ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> notifPermissions = new ArrayMap<>();
        if (mPermissionHelper.isMigrationEnabled() && forBackup) {
            notifPermissions = mPermissionHelper.getNotificationPermissionValues(userId);
        }
@@ -573,9 +573,8 @@ public class PreferencesHelper implements RankingConfig {
                out.attribute(null, ATT_NAME, r.pkg);
                if (!notifPermissions.isEmpty()) {
                    Pair<Integer, String> app = new Pair(r.uid, r.pkg);
                    out.attributeInt(null, ATT_IMPORTANCE, notifPermissions.get(app)
                            ? IMPORTANCE_DEFAULT
                            : IMPORTANCE_NONE);
                    out.attributeInt(null, ATT_IMPORTANCE,
                            notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                    notifPermissions.remove(app);
                } else {
                    if (r.importance != DEFAULT_IMPORTANCE) {
@@ -642,7 +641,7 @@ public class PreferencesHelper implements RankingConfig {
                out.startTag(null, TAG_PACKAGE);
                out.attribute(null, ATT_NAME, app.second);
                out.attributeInt(null, ATT_IMPORTANCE,
                        notifPermissions.get(app) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                        notifPermissions.get(app).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                out.endTag(null, TAG_PACKAGE);
            }
        }
@@ -1932,7 +1931,7 @@ public class PreferencesHelper implements RankingConfig {

    public void dump(PrintWriter pw, String prefix,
            @NonNull NotificationManagerService.DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        pw.print(prefix);
        pw.println("per-package config version: " + XML_VERSION);

@@ -1946,7 +1945,7 @@ public class PreferencesHelper implements RankingConfig {

    public void dump(ProtoOutputStream proto,
            @NonNull NotificationManagerService.DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        synchronized (mPackagePreferences) {
            dumpPackagePreferencesLocked(proto, RankingHelperProto.RECORDS, filter,
                    mPackagePreferences, pkgPermissions);
@@ -1958,7 +1957,7 @@ public class PreferencesHelper implements RankingConfig {
    private void dumpPackagePreferencesLocked(PrintWriter pw, String prefix,
            @NonNull NotificationManagerService.DumpFilter filter,
            ArrayMap<String, PackagePreferences> packagePreferences,
            ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) {
        // Used for tracking which package preferences we've seen already for notification
        // permission reasons; after handling packages with local preferences, we'll want to dump
        // the ones with notification permissions set but not local prefs.
@@ -1987,8 +1986,10 @@ public class PreferencesHelper implements RankingConfig {
                    if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
                        pw.print(" importance=");
                        pw.print(NotificationListenerService.Ranking.importanceToString(
                                packagePermissions.get(key)
                                packagePermissions.get(key).first
                                        ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
                        pw.print(" userSet=");
                        pw.print(packagePermissions.get(key).second);
                        pkgsWithPermissionsToHandle.remove(key);
                    }
                }
@@ -2042,7 +2043,10 @@ public class PreferencesHelper implements RankingConfig {
                    pw.print(')');
                    pw.print(" importance=");
                    pw.print(NotificationListenerService.Ranking.importanceToString(
                            packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
                            packagePermissions.get(p).first
                                    ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
                    pw.print(" userSet=");
                    pw.print(packagePermissions.get(p).second);
                    pw.println();
                }
            }
@@ -2052,7 +2056,7 @@ public class PreferencesHelper implements RankingConfig {
    private void dumpPackagePreferencesLocked(ProtoOutputStream proto, long fieldId,
            @NonNull NotificationManagerService.DumpFilter filter,
            ArrayMap<String, PackagePreferences> packagePreferences,
            ArrayMap<Pair<Integer, String>, Boolean> packagePermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> packagePermissions) {
        Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null;
        if (packagePermissions != null) {
            pkgsWithPermissionsToHandle = packagePermissions.keySet();
@@ -2071,7 +2075,8 @@ public class PreferencesHelper implements RankingConfig {
                    Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
                    if (packagePermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
                        proto.write(RankingHelperProto.RecordProto.IMPORTANCE,
                                packagePermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                                packagePermissions.get(key).first
                                        ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                        pkgsWithPermissionsToHandle.remove(key);
                    }
                } else {
@@ -2099,7 +2104,8 @@ public class PreferencesHelper implements RankingConfig {
                    proto.write(RankingHelperProto.RecordProto.PACKAGE, p.second);
                    proto.write(RankingHelperProto.RecordProto.UID, p.first);
                    proto.write(RankingHelperProto.RecordProto.IMPORTANCE,
                            packagePermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                            packagePermissions.get(p).first
                                    ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                    proto.end(fToken);
                }
            }
@@ -2110,7 +2116,7 @@ public class PreferencesHelper implements RankingConfig {
     * Fills out {@link PackageNotificationPreferences} proto and wraps it in a {@link StatsEvent}.
     */
    public void pullPackagePreferencesStats(List<StatsEvent> events,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        Set<Pair<Integer, String>> pkgsWithPermissionsToHandle = null;
        if (pkgPermissions != null) {
            pkgsWithPermissionsToHandle = pkgPermissions.keySet();
@@ -2134,7 +2140,8 @@ public class PreferencesHelper implements RankingConfig {
                    int importance = IMPORTANCE_NONE;
                    Pair<Integer, String> key = new Pair<>(r.uid, r.pkg);
                    if (pkgPermissions != null && pkgsWithPermissionsToHandle.contains(key)) {
                        importance = pkgPermissions.get(key) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE;
                        importance = pkgPermissions.get(key).first
                                ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE;
                        pkgsWithPermissionsToHandle.remove(key);
                    }
                    event.writeInt(importance);
@@ -2158,7 +2165,7 @@ public class PreferencesHelper implements RankingConfig {
                        .setAtomId(PACKAGE_NOTIFICATION_PREFERENCES);
                event.writeInt(p.first);
                event.addBooleanAnnotation(ANNOTATION_ID_IS_UID, true);
                event.writeInt(pkgPermissions.get(p) ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);
                event.writeInt(pkgPermissions.get(p).first ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE);

                // fill out the rest of the fields with default values so as not to confuse the
                // builder
@@ -2236,7 +2243,7 @@ public class PreferencesHelper implements RankingConfig {
    }

    public JSONObject dumpJson(NotificationManagerService.DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        JSONObject ranking = new JSONObject();
        JSONArray PackagePreferencess = new JSONArray();
        try {
@@ -2266,7 +2273,7 @@ public class PreferencesHelper implements RankingConfig {
                                    && pkgsWithPermissionsToHandle.contains(key)) {
                                PackagePreferences.put("importance",
                                        NotificationListenerService.Ranking.importanceToString(
                                                pkgPermissions.get(key)
                                                pkgPermissions.get(key).first
                                                        ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
                                pkgsWithPermissionsToHandle.remove(key);
                            }
@@ -2316,7 +2323,7 @@ public class PreferencesHelper implements RankingConfig {
                        PackagePreferences.put("packageName", p.second);
                        PackagePreferences.put("importance",
                                NotificationListenerService.Ranking.importanceToString(
                                        pkgPermissions.get(p)
                                        pkgPermissions.get(p).first
                                                ? IMPORTANCE_DEFAULT : IMPORTANCE_NONE));
                    } catch (JSONException e) {
                        // pass
@@ -2344,7 +2351,7 @@ public class PreferencesHelper implements RankingConfig {
     * @return
     */
    public JSONArray dumpBansJson(NotificationManagerService.DumpFilter filter,
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        JSONArray bans = new JSONArray();
        Map<Integer, String> packageBans = mPermissionHelper.isMigrationEnabled()
                ? getPermissionBasedPackageBans(pkgPermissions) : getPackageBans();
@@ -2383,11 +2390,11 @@ public class PreferencesHelper implements RankingConfig {
    // Same functionality as getPackageBans by extracting the set of packages from the provided
    // map that are disallowed from sending notifications.
    protected Map<Integer, String> getPermissionBasedPackageBans(
            ArrayMap<Pair<Integer, String>, Boolean> pkgPermissions) {
            ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> pkgPermissions) {
        ArrayMap<Integer, String> packageBans = new ArrayMap<>();
        if (pkgPermissions != null) {
            for (Pair<Integer, String> p : pkgPermissions.keySet()) {
                if (!pkgPermissions.get(p)) {
                if (!pkgPermissions.get(p).first) {
                    packageBans.put(p.first, p.second);
                }
            }
+14 −10
Original line number Diff line number Diff line
@@ -840,21 +840,25 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase {
        when(mUm.getUsers()).thenReturn(userInfos);

        // construct the permissions for each of them
        ArrayMap<Pair<Integer, String>, Boolean> permissions0 = new ArrayMap<>(),
        ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> permissions0 = new ArrayMap<>(),
                permissions1 = new ArrayMap<>();
        permissions0.put(new Pair<>(10, "package1"), true);
        permissions0.put(new Pair<>(20, "package2"), false);
        permissions1.put(new Pair<>(11, "package1"), false);
        permissions1.put(new Pair<>(21, "package2"), true);
        permissions0.put(new Pair<>(10, "package1"), new Pair<>(true, false));
        permissions0.put(new Pair<>(20, "package2"), new Pair<>(false, true));
        permissions1.put(new Pair<>(11, "package1"), new Pair<>(false, false));
        permissions1.put(new Pair<>(21, "package2"), new Pair<>(true, true));
        when(mPermissionHelper.getNotificationPermissionValues(0)).thenReturn(permissions0);
        when(mPermissionHelper.getNotificationPermissionValues(1)).thenReturn(permissions1);
        when(mPermissionHelper.getNotificationPermissionValues(2)).thenReturn(new ArrayMap<>());

        ArrayMap<Pair<Integer, String>, Boolean> combinedPermissions =
        ArrayMap<Pair<Integer, String>, Pair<Boolean, Boolean>> combinedPermissions =
                mService.getAllUsersNotificationPermissions();
        assertTrue(combinedPermissions.get(new Pair<>(10, "package1")));
        assertFalse(combinedPermissions.get(new Pair<>(20, "package2")));
        assertFalse(combinedPermissions.get(new Pair<>(11, "package1")));
        assertTrue(combinedPermissions.get(new Pair<>(21, "package2")));
        assertTrue(combinedPermissions.get(new Pair<>(10, "package1")).first);
        assertFalse(combinedPermissions.get(new Pair<>(10, "package1")).second);
        assertFalse(combinedPermissions.get(new Pair<>(20, "package2")).first);
        assertTrue(combinedPermissions.get(new Pair<>(20, "package2")).second);
        assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).first);
        assertFalse(combinedPermissions.get(new Pair<>(11, "package1")).second);
        assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).first);
        assertTrue(combinedPermissions.get(new Pair<>(21, "package2")).second);
    }
}
+16 −5
Original line number Diff line number Diff line
@@ -313,11 +313,22 @@ public class PermissionHelperTest extends UiServiceTestCase {
        when(mPackageManager.getInstalledPackages(eq((long) GET_PERMISSIONS), anyInt()))
                .thenReturn(requesting);

        Map<Pair<Integer, String>, Boolean> expected = ImmutableMap.of(new Pair(1, "first"), true,
                new Pair(2, "second"), true,
                new Pair(3, "third"), false);

        Map<Pair<Integer, String>, Boolean> actual =
        // 2 and 3 are user-set permissions
        when(mPermManager.getPermissionFlags(
                "first", Manifest.permission.POST_NOTIFICATIONS, userId)).thenReturn(0);
        when(mPermManager.getPermissionFlags(
                "second", Manifest.permission.POST_NOTIFICATIONS, userId))
                .thenReturn(FLAG_PERMISSION_USER_SET);
        when(mPermManager.getPermissionFlags(
                "third", Manifest.permission.POST_NOTIFICATIONS, userId))
                .thenReturn(FLAG_PERMISSION_USER_SET);

        Map<Pair<Integer, String>, Pair<Boolean, Boolean>> expected =
                ImmutableMap.of(new Pair(1, "first"), new Pair(true, false),
                    new Pair(2, "second"), new Pair(true, true),
                    new Pair(3, "third"), new Pair(false, true));

        Map<Pair<Integer, String>, Pair<Boolean, Boolean>> actual =
                mPermissionHelper.getNotificationPermissionValues(userId);

        assertThat(actual).containsExactlyEntriesIn(expected);
Loading