Merge "Lock relevant fields on channel update" into oc-dev
am: 6307ac52e5
Change-Id: I7f47872b2d166353365517e7407cda43666ae70c
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,60 +115,6 @@ public class RankingHelperTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
UserHandle user = UserHandle.ALL;
|
||||
|
||||
mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
|
||||
new String[] {ImportanceExtractor.class.getName()});
|
||||
|
||||
mNotiGroupGSortA = new Notification.Builder(getContext(), 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,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiGroupGSortB = new Notification.Builder(getContext(), 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,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroup = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.setContentTitle("C")
|
||||
.setWhen(1201)
|
||||
.build();
|
||||
mRecordNoGroup = new NotificationRecord(getContext(), new StatusBarNotification(
|
||||
"package", "package", 1, null, 0, 0, mNotiNoGroup, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroup2 = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.setContentTitle("D")
|
||||
.setWhen(1202)
|
||||
.build();
|
||||
mRecordNoGroup2 = new NotificationRecord(getContext(), new StatusBarNotification(
|
||||
"package", "package", 1, null, 0, 0, mNotiNoGroup2, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroupSortA = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.setContentTitle("E")
|
||||
.setWhen(1201)
|
||||
.setSortKey("A")
|
||||
.build();
|
||||
mRecordNoGroupSortA = new NotificationRecord(getContext(), new StatusBarNotification(
|
||||
"package", "package", 1, null, 0, 0, mNotiNoGroupSortA, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mAudioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.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();
|
||||
@@ -174,6 +122,64 @@ public class RankingHelperTest {
|
||||
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(mContext, TEST_CHANNEL_ID)
|
||||
.setContentTitle("A")
|
||||
.setGroup("G")
|
||||
.setSortKey("A")
|
||||
.setWhen(1205)
|
||||
.build();
|
||||
mRecordGroupGSortA = new NotificationRecord(mContext, new StatusBarNotification(
|
||||
PKG, PKG, 1, null, 0, 0, mNotiGroupGSortA, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiGroupGSortB = new Notification.Builder(mContext, TEST_CHANNEL_ID)
|
||||
.setContentTitle("B")
|
||||
.setGroup("G")
|
||||
.setSortKey("B")
|
||||
.setWhen(1200)
|
||||
.build();
|
||||
mRecordGroupGSortB = new NotificationRecord(mContext, new StatusBarNotification(
|
||||
PKG, PKG, 1, null, 0, 0, mNotiGroupGSortB, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroup = new Notification.Builder(mContext, TEST_CHANNEL_ID)
|
||||
.setContentTitle("C")
|
||||
.setWhen(1201)
|
||||
.build();
|
||||
mRecordNoGroup = new NotificationRecord(mContext, new StatusBarNotification(
|
||||
PKG, PKG, 1, null, 0, 0, mNotiNoGroup, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroup2 = new Notification.Builder(mContext, TEST_CHANNEL_ID)
|
||||
.setContentTitle("D")
|
||||
.setWhen(1202)
|
||||
.build();
|
||||
mRecordNoGroup2 = new NotificationRecord(mContext, new StatusBarNotification(
|
||||
PKG, PKG, 1, null, 0, 0, mNotiNoGroup2, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mNotiNoGroupSortA = new Notification.Builder(mContext, TEST_CHANNEL_ID)
|
||||
.setContentTitle("E")
|
||||
.setWhen(1201)
|
||||
.setSortKey("A")
|
||||
.build();
|
||||
mRecordNoGroupSortA = new NotificationRecord(mContext, new StatusBarNotification(
|
||||
PKG, PKG, 1, null, 0, 0, mNotiNoGroupSortA, user,
|
||||
null, System.currentTimeMillis()), getDefaultChannel());
|
||||
|
||||
mAudioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
|
||||
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
|
||||
.setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
|
||||
.build();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user