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

Commit 6307ac52 authored by Julia Reynolds's avatar Julia Reynolds Committed by Android (Google) Code Review
Browse files

Merge "Lock relevant fields on channel update" into oc-dev

parents a7af3852 e0b25746
Loading
Loading
Loading
Loading
+7 −12
Original line number Diff line number Diff line
@@ -98,21 +98,11 @@ public final class NotificationChannel implements Parcelable {
     */
    public static final int USER_LOCKED_SOUND = 0x00000020;

    /**
     * @hide
     */
    public static final int USER_LOCKED_ALLOWED = 0x00000040;

    /**
     * @hide
     */
    public static final int USER_LOCKED_SHOW_BADGE = 0x00000080;

    /**
     * @hide
     */
    public static final int USER_LOCKED_AUDIO_ATTRIBUTES = 0x00000100;

    /**
     * @hide
     */
@@ -123,9 +113,7 @@ public final class NotificationChannel implements Parcelable {
            USER_LOCKED_LIGHTS,
            USER_LOCKED_VIBRATION,
            USER_LOCKED_SOUND,
            USER_LOCKED_ALLOWED,
            USER_LOCKED_SHOW_BADGE,
            USER_LOCKED_AUDIO_ATTRIBUTES
    };

    private static final int DEFAULT_LIGHT_COLOR = 0;
@@ -270,6 +258,13 @@ public final class NotificationChannel implements Parcelable {
        mUserLockedFields |= field;
    }

    /**
     * @hide
     */
    public void unlockFields(int field) {
        mUserLockedFields &= ~field;
    }

    /**
     * @hide
     */
+34 −6
Original line number Diff line number Diff line
@@ -48,11 +48,13 @@ import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

public class RankingHelper implements RankingConfig {
    private static final String TAG = "RankingHelper";
@@ -574,12 +576,8 @@ public class RankingHelper implements RankingConfig {
        updateConfig();
    }

    private void clearLockedFields(NotificationChannel channel) {
        int clearMask = 0;
        for (int i = 0; i < NotificationChannel.LOCKABLE_FIELDS.length; i++) {
            clearMask |= NotificationChannel.LOCKABLE_FIELDS[i];
        }
        channel.lockFields(~clearMask);
    void clearLockedFields(NotificationChannel channel) {
        channel.unlockFields(channel.getUserLockedFields());
    }

    @Override
@@ -597,6 +595,7 @@ public class RankingHelper implements RankingConfig {
        if (updatedChannel.getLockscreenVisibility() == Notification.VISIBILITY_PUBLIC) {
            updatedChannel.setLockscreenVisibility(Ranking.VISIBILITY_NO_OVERRIDE);
        }
        lockFieldsForUpdate(channel, updatedChannel);
        r.channels.put(updatedChannel.getId(), updatedChannel);

        if (NotificationChannel.DEFAULT_CHANNEL_ID.equals(updatedChannel.getId())) {
@@ -805,6 +804,35 @@ public class RankingHelper implements RankingConfig {
                enabled ? DEFAULT_IMPORTANCE : NotificationManager.IMPORTANCE_NONE);
    }

    @VisibleForTesting
    void lockFieldsForUpdate(NotificationChannel original, NotificationChannel update) {
        update.unlockFields(update.getUserLockedFields());
        update.lockFields(original.getUserLockedFields());
        if (original.canBypassDnd() != update.canBypassDnd()) {
            update.lockFields(NotificationChannel.USER_LOCKED_PRIORITY);
        }
        if (original.getLockscreenVisibility() != update.getLockscreenVisibility()) {
            update.lockFields(NotificationChannel.USER_LOCKED_VISIBILITY);
        }
        if (original.getImportance() != update.getImportance()) {
            update.lockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
        }
        if (original.shouldShowLights() != update.shouldShowLights()
                || original.getLightColor() != update.getLightColor()) {
            update.lockFields(NotificationChannel.USER_LOCKED_LIGHTS);
        }
        if (!Objects.equals(original.getSound(), update.getSound())) {
            update.lockFields(NotificationChannel.USER_LOCKED_SOUND);
        }
        if (!Arrays.equals(original.getVibrationPattern(), update.getVibrationPattern())
                || original.shouldVibrate() != update.shouldVibrate()) {
            update.lockFields(NotificationChannel.USER_LOCKED_VIBRATION);
        }
        if (original.canShowBadge() != update.canShowBadge()) {
            update.lockFields(NotificationChannel.USER_LOCKED_SHOW_BADGE);
        }
    }

    public void dump(PrintWriter pw, String prefix, NotificationManagerService.DumpFilter filter) {
        if (filter == null) {
            final int N = mSignalExtractors.length;
+140 −25
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.ArrayMap;
import android.util.Slog;
import android.util.Xml;

import java.io.BufferedInputStream;
@@ -90,6 +91,7 @@ public class RankingHelperTest {
    @Mock NotificationUsageStats mUsageStats;
    @Mock RankingHandler mHandler;
    @Mock PackageManager mPm;
    @Mock Context mContext;

    private Notification mNotiGroupGSortA;
    private Notification mNotiGroupGSortB;
@@ -113,52 +115,64 @@ public class RankingHelperTest {
        MockitoAnnotations.initMocks(this);
        UserHandle user = UserHandle.ALL;

        final ApplicationInfo legacy = new ApplicationInfo();
        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
        final ApplicationInfo upgrade = new ApplicationInfo();
        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
        when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
        when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
        when(mContext.getResources()).thenReturn(
                InstrumentationRegistry.getContext().getResources());
        when(mContext.getPackageManager()).thenReturn(mPm);
        when(mContext.getApplicationInfo()).thenReturn(legacy);

        mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
                new String[] {ImportanceExtractor.class.getName()});

        mNotiGroupGSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
        mNotiGroupGSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setContentTitle("A")
                .setGroup("G")
                .setSortKey("A")
                .setWhen(1205)
                .build();
        mRecordGroupGSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                "package", "package", 1, null, 0, 0, mNotiGroupGSortA, user,
        mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
                PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
                null, System.currentTimeMillis()), getDefaultChannel());

        mNotiGroupGSortB = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
        mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setContentTitle("B")
                .setGroup("G")
                .setSortKey("B")
                .setWhen(1200)
                .build();
        mRecordGroupGSortB = new NotificationRecord(getContext(), new StatusBarNotification(
                "package", "package", 1, null, 0, 0, mNotiGroupGSortB, user,
        mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
                PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
                null, System.currentTimeMillis()), getDefaultChannel());

        mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
        mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setContentTitle("C")
                .setWhen(1201)
                .build();
        mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
                "package", "package", 1, null, 0, 0, mNotiNoGroup, user,
        mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
                PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
                null, System.currentTimeMillis()), getDefaultChannel());

        mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
        mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setContentTitle("D")
                .setWhen(1202)
                .build();
        mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
                "package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
        mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
                PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
                null, System.currentTimeMillis()), getDefaultChannel());

        mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
        mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
                .setContentTitle("E")
                .setWhen(1201)
                .setSortKey("A")
                .build();
        mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
                "package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user,
        mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
                PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
                null, System.currentTimeMillis()), getDefaultChannel());

        mAudioAttributes = new AudioAttributes.Builder()
@@ -166,14 +180,6 @@ public class RankingHelperTest {
                .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .build();

        final ApplicationInfo legacy = new ApplicationInfo();
        legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
        final ApplicationInfo upgrade = new ApplicationInfo();
        upgrade.targetSdkVersion = Build.VERSION_CODES.N_MR1 + 1;
        when(mPm.getApplicationInfoAsUser(eq(PKG), anyInt(), anyInt())).thenReturn(legacy);
        when(mPm.getApplicationInfoAsUser(eq(UPDATED_PKG), anyInt(), anyInt())).thenReturn(upgrade);
        when(mPm.getPackageUidAsUser(eq(PKG), anyInt())).thenReturn(UID);
    }

    private NotificationChannel getDefaultChannel() {
@@ -229,6 +235,10 @@ public class RankingHelperTest {
        assertEquals(expected.getName(), actual.getName());
    }

    private NotificationChannel getChannel() {
        return new NotificationChannel("id", "name", IMPORTANCE_LOW);
    }

    @Test
    public void testFindAfterRankingWithASplitGroup() throws Exception {
        ArrayList<NotificationRecord> notificationList = new ArrayList<NotificationRecord>(3);
@@ -643,6 +653,112 @@ public class RankingHelperTest {
        assertEquals(channel.canShowBadge(), savedChannel.canShowBadge());
    }

    @Test
    public void testClearLockedFields() throws Exception {
        final NotificationChannel channel = getChannel();
        mHelper.clearLockedFields(channel);
        assertEquals(0, channel.getUserLockedFields());

        channel.lockFields(NotificationChannel.USER_LOCKED_PRIORITY
                | NotificationChannel.USER_LOCKED_IMPORTANCE);
        mHelper.clearLockedFields(channel);
        assertEquals(0, channel.getUserLockedFields());
    }

    @Test
    public void testLockFields_soundAndVibration() throws Exception {
        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);

        final NotificationChannel update1 = getChannel();
        update1.setSound(new Uri.Builder().scheme("test").build(),
                new AudioAttributes.Builder().build());
        update1.lockFields(NotificationChannel.USER_LOCKED_PRIORITY); // should be ignored
        mHelper.updateNotificationChannel(PKG, UID, update1);
        assertEquals(NotificationChannel.USER_LOCKED_SOUND,
                mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
                        .getUserLockedFields());

        NotificationChannel update2 = getChannel();
        update2.enableVibration(true);
        mHelper.updateNotificationChannel(PKG, UID, update2);
        assertEquals(NotificationChannel.USER_LOCKED_SOUND
                        | NotificationChannel.USER_LOCKED_VIBRATION,
                mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
                        .getUserLockedFields());
    }

    @Test
    public void testLockFields_vibrationAndLights() throws Exception {
        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);

        final NotificationChannel update1 = getChannel();
        update1.setVibrationPattern(new long[]{7945, 46 ,246});
        mHelper.updateNotificationChannel(PKG, UID, update1);
        assertEquals(NotificationChannel.USER_LOCKED_VIBRATION,
                mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
                        .getUserLockedFields());

        final NotificationChannel update2 = getChannel();
        update2.enableLights(true);
        mHelper.updateNotificationChannel(PKG, UID, update2);
        assertEquals(NotificationChannel.USER_LOCKED_VIBRATION
                        | NotificationChannel.USER_LOCKED_LIGHTS,
                mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
                        .getUserLockedFields());
    }

    @Test
    public void testLockFields_lightsAndImportance() throws Exception {
        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);

        final NotificationChannel update1 = getChannel();
        update1.setLightColor(Color.GREEN);
        mHelper.updateNotificationChannel(PKG, UID, update1);
        assertEquals(NotificationChannel.USER_LOCKED_LIGHTS,
                mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
                        .getUserLockedFields());

        final NotificationChannel update2 = getChannel();
        update2.setImportance(IMPORTANCE_DEFAULT);
        mHelper.updateNotificationChannel(PKG, UID, update2);
        assertEquals(NotificationChannel.USER_LOCKED_LIGHTS
                        | NotificationChannel.USER_LOCKED_IMPORTANCE,
                mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
                        .getUserLockedFields());
    }

    @Test
    public void testLockFields_visibilityAndDndAndBadge() throws Exception {
        mHelper.createNotificationChannel(PKG, UID, getChannel(), true);
        assertEquals(0,
                mHelper.getNotificationChannel(PKG, UID, getChannel().getId(), false)
                        .getUserLockedFields());

        final NotificationChannel update1 = getChannel();
        update1.setBypassDnd(true);
        mHelper.updateNotificationChannel(PKG, UID, update1);
        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY,
                mHelper.getNotificationChannel(PKG, UID, update1.getId(), false)
                        .getUserLockedFields());

        final NotificationChannel update2 = getChannel();
        update2.setLockscreenVisibility(Notification.VISIBILITY_SECRET);
        mHelper.updateNotificationChannel(PKG, UID, update2);
        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                        | NotificationChannel.USER_LOCKED_VISIBILITY,
                mHelper.getNotificationChannel(PKG, UID, update2.getId(), false)
                        .getUserLockedFields());

        final NotificationChannel update3 = getChannel();
        update3.setShowBadge(false);
        mHelper.updateNotificationChannel(PKG, UID, update3);
        assertEquals(NotificationChannel.USER_LOCKED_PRIORITY
                        | NotificationChannel.USER_LOCKED_VISIBILITY
                        | NotificationChannel.USER_LOCKED_SHOW_BADGE,
                mHelper.getNotificationChannel(PKG, UID, update3.getId(), false)
                        .getUserLockedFields());
    }

    @Test
    public void testDeleteNonExistentChannel() throws Exception {
        mHelper.deleteNotificationChannelGroup(PKG, UID, "does not exist");
@@ -650,8 +766,7 @@ public class RankingHelperTest {

    @Test
    public void testGetDeletedChannel() throws Exception {
        NotificationChannel channel =
                new NotificationChannel("id2", "name2", IMPORTANCE_LOW);
        NotificationChannel channel = getChannel();
        channel.setSound(new Uri.Builder().scheme("test").build(), mAudioAttributes);
        channel.enableLights(true);
        channel.setBypassDnd(true);