Merge changes from topic 'b/36021111' into oc-dev
am: 69ab8e1d56
Change-Id: I4bf9b7425c86a8725e9d7c055ab4c4f389fe3a2b
This commit is contained in:
@@ -6945,6 +6945,13 @@ public final class Settings {
|
||||
*/
|
||||
public static final String CMAS_ADDITIONAL_BROADCAST_PKG = "cmas_additional_broadcast_pkg";
|
||||
|
||||
/**
|
||||
* Whether the launcher should show any notification badges.
|
||||
* The value is boolean (1 or 0).
|
||||
* @hide
|
||||
*/
|
||||
public static final String NOTIFICATION_BADGING = "notification_badging";
|
||||
|
||||
/**
|
||||
* This are the settings to be backed up.
|
||||
*
|
||||
@@ -7040,7 +7047,8 @@ public final class Settings {
|
||||
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
|
||||
ASSIST_GESTURE_ENABLED,
|
||||
ASSIST_GESTURE_SENSITIVITY,
|
||||
VR_DISPLAY_MODE
|
||||
VR_DISPLAY_MODE,
|
||||
NOTIFICATION_BADGING
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -503,6 +503,7 @@ message SecureSettingsProto {
|
||||
SettingProto demo_user_setup_complete = 165;
|
||||
SettingProto instant_apps_enabled = 166;
|
||||
SettingProto device_paired = 167;
|
||||
SettingProto notification_badging = 168;
|
||||
}
|
||||
|
||||
message SystemSettingsProto {
|
||||
|
||||
@@ -1013,6 +1013,9 @@
|
||||
<!-- Is the notification LED intrusive? Used to decide if there should be a disable option -->
|
||||
<bool name="config_intrusiveNotificationLed">false</bool>
|
||||
|
||||
<!-- De we do icon badges? Used to decide if there should be a disable option-->
|
||||
<bool name="config_notificationBadging">true</bool>
|
||||
|
||||
<!-- Default value for LED off time when the battery is low on charge in miliseconds -->
|
||||
<integer name="config_notificationsBatteryLedOff">2875</integer>
|
||||
|
||||
|
||||
@@ -2093,6 +2093,7 @@
|
||||
<java-symbol type="string" name="config_wifi_tether_enable" />
|
||||
<java-symbol type="integer" name="config_wifi_wakeup_available" />
|
||||
<java-symbol type="bool" name="config_intrusiveNotificationLed" />
|
||||
<java-symbol type="bool" name="config_notificationBadging" />
|
||||
<java-symbol type="dimen" name="preference_fragment_padding_bottom" />
|
||||
<java-symbol type="dimen" name="preference_fragment_padding_side" />
|
||||
<java-symbol type="drawable" name="expander_ic_maximized" />
|
||||
|
||||
@@ -1434,6 +1434,9 @@ class SettingsProtoDumpUtil {
|
||||
dumpSetting(s, p,
|
||||
Settings.Secure.DEVICE_PAIRED,
|
||||
SecureSettingsProto.DEVICE_PAIRED);
|
||||
dumpSetting(s, p,
|
||||
Settings.Secure.NOTIFICATION_BADGING,
|
||||
SecureSettingsProto.NOTIFICATION_BADGING);
|
||||
}
|
||||
|
||||
private static void dumpProtoSystemSettingsLocked(
|
||||
|
||||
@@ -41,9 +41,10 @@ public class BadgeExtractor implements NotificationSignalExtractor {
|
||||
if (DBG) Slog.d(TAG, "missing config");
|
||||
return null;
|
||||
}
|
||||
boolean userWantsBadges = mConfig.badgingEnabled(record.sbn.getUser());
|
||||
boolean appCanShowBadge =
|
||||
mConfig.canShowBadge(record.sbn.getPackageName(), record.sbn.getUid());
|
||||
if (!appCanShowBadge) {
|
||||
if (!userWantsBadges || !appCanShowBadge) {
|
||||
record.setShowBadge(false);
|
||||
} else {
|
||||
record.setShowBadge(mConfig.getNotificationChannel(record.sbn.getPackageName(),
|
||||
|
||||
@@ -927,6 +927,8 @@ public class NotificationManagerService extends SystemService {
|
||||
};
|
||||
|
||||
private final class SettingsObserver extends ContentObserver {
|
||||
private final Uri NOTIFICATION_BADGING_URI
|
||||
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
|
||||
private final Uri NOTIFICATION_LIGHT_PULSE_URI
|
||||
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
|
||||
private final Uri NOTIFICATION_RATE_LIMIT_URI
|
||||
@@ -938,6 +940,8 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
void observe() {
|
||||
ContentResolver resolver = getContext().getContentResolver();
|
||||
resolver.registerContentObserver(NOTIFICATION_BADGING_URI,
|
||||
false, this, UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
|
||||
false, this, UserHandle.USER_ALL);
|
||||
resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
|
||||
@@ -963,6 +967,9 @@ public class NotificationManagerService extends SystemService {
|
||||
mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver,
|
||||
Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate);
|
||||
}
|
||||
if (uri == null || NOTIFICATION_BADGING_URI.equals(uri)) {
|
||||
mRankingHelper.updateBadgingEnabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4022,6 +4029,7 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
private void handleRankingSort(Message msg) {
|
||||
if (!(msg.obj instanceof Boolean)) return;
|
||||
if (mRankingHelper == null) return;
|
||||
boolean forceUpdate = ((Boolean) msg.obj == null) ? false : (boolean) msg.obj;
|
||||
synchronized (mNotificationLock) {
|
||||
final int N = mNotificationList.size();
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.os.UserHandle;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -27,6 +28,7 @@ public interface RankingConfig {
|
||||
int getImportance(String packageName, int uid);
|
||||
void setShowBadge(String packageName, int uid, boolean showBadge);
|
||||
boolean canShowBadge(String packageName, int uid);
|
||||
boolean badgingEnabled(UserHandle userHandle);
|
||||
|
||||
Collection<NotificationChannelGroup> getNotificationChannelGroups(String pkg,
|
||||
int uid);
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.util.Preconditions;
|
||||
|
||||
import android.annotation.UserIdInt;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationChannelGroup;
|
||||
@@ -33,10 +35,14 @@ import android.content.pm.ParceledListSlice;
|
||||
import android.metrics.LogMaker;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.service.notification.NotificationListenerService.Ranking;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
@@ -91,6 +97,7 @@ public class RankingHelper implements RankingConfig {
|
||||
private final Context mContext;
|
||||
private final RankingHandler mRankingHandler;
|
||||
private final PackageManager mPm;
|
||||
private SparseBooleanArray mBadgingEnabled;
|
||||
|
||||
public RankingHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
|
||||
NotificationUsageStats usageStats, String[] extractorNames) {
|
||||
@@ -100,6 +107,8 @@ public class RankingHelper implements RankingConfig {
|
||||
|
||||
mPreliminaryComparator = new NotificationComparator(mContext);
|
||||
|
||||
updateBadgingEnabled();
|
||||
|
||||
final int N = extractorNames.length;
|
||||
mSignalExtractors = new NotificationSignalExtractor[N];
|
||||
for (int i = 0; i < N; i++) {
|
||||
@@ -1111,6 +1120,38 @@ public class RankingHelper implements RankingConfig {
|
||||
channel.getImportance());
|
||||
}
|
||||
|
||||
public void updateBadgingEnabled() {
|
||||
if (mBadgingEnabled == null) {
|
||||
mBadgingEnabled = new SparseBooleanArray();
|
||||
}
|
||||
boolean changed = false;
|
||||
// update the cached values
|
||||
for (int index = 0; index < mBadgingEnabled.size(); index++) {
|
||||
int userId = mBadgingEnabled.keyAt(index);
|
||||
final boolean oldValue = mBadgingEnabled.get(userId);
|
||||
final boolean newValue = Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING,
|
||||
DEFAULT_SHOW_BADGE ? 1 : 0, userId) != 0;
|
||||
mBadgingEnabled.put(userId, newValue);
|
||||
changed |= oldValue != newValue;
|
||||
}
|
||||
if (changed) {
|
||||
mRankingHandler.requestSort(false);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean badgingEnabled(UserHandle userHandle) {
|
||||
int userId = userHandle.getIdentifier();
|
||||
if (mBadgingEnabled.indexOfKey(userId) < 0) {
|
||||
mBadgingEnabled.put(userId,
|
||||
Secure.getIntForUser(mContext.getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING,
|
||||
DEFAULT_SHOW_BADGE ? 1 : 0, userId) != 0);
|
||||
}
|
||||
return mBadgingEnabled.get(userId, DEFAULT_SHOW_BADGE);
|
||||
}
|
||||
|
||||
|
||||
private static class Record {
|
||||
static int UNKNOWN_UID = UserHandle.USER_NULL;
|
||||
|
||||
|
||||
@@ -18,20 +18,19 @@ package com.android.server.notification;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Notification;
|
||||
import android.app.Notification.Builder;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -43,7 +42,7 @@ import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BadgeExtractorTest {
|
||||
public class BadgeExtractorTest extends NotificationTestCase {
|
||||
|
||||
@Mock RankingConfig mConfig;
|
||||
|
||||
@@ -59,7 +58,11 @@ public class BadgeExtractorTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
private NotificationRecord getNotificationRecord(NotificationChannel channel) {
|
||||
private NotificationRecord getNotificationRecord(boolean showBadge, int importanceHigh) {
|
||||
NotificationChannel channel = new NotificationChannel("a", "a", importanceHigh);
|
||||
channel.setShowBadge(showBadge);
|
||||
when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
|
||||
|
||||
final Builder builder = new Builder(getContext())
|
||||
.setContentTitle("foo")
|
||||
.setSmallIcon(android.R.drawable.sym_def_app_icon)
|
||||
@@ -73,10 +76,6 @@ public class BadgeExtractorTest {
|
||||
return r;
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
//
|
||||
// Tests
|
||||
//
|
||||
@@ -86,13 +85,9 @@ public class BadgeExtractorTest {
|
||||
BadgeExtractor extractor = new BadgeExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
when(mConfig.badgingEnabled(mUser)).thenReturn(true);
|
||||
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
|
||||
when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
|
||||
channel.setShowBadge(false);
|
||||
|
||||
NotificationRecord r = getNotificationRecord(channel);
|
||||
NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
|
||||
|
||||
extractor.process(r);
|
||||
|
||||
@@ -104,13 +99,9 @@ public class BadgeExtractorTest {
|
||||
BadgeExtractor extractor = new BadgeExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
when(mConfig.badgingEnabled(mUser)).thenReturn(true);
|
||||
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(false);
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_HIGH);
|
||||
channel.setShowBadge(true);
|
||||
when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
|
||||
|
||||
NotificationRecord r = getNotificationRecord(channel);
|
||||
NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
|
||||
|
||||
extractor.process(r);
|
||||
|
||||
@@ -122,13 +113,9 @@ public class BadgeExtractorTest {
|
||||
BadgeExtractor extractor = new BadgeExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
when(mConfig.badgingEnabled(mUser)).thenReturn(true);
|
||||
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
|
||||
channel.setShowBadge(true);
|
||||
when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
|
||||
|
||||
NotificationRecord r = getNotificationRecord(channel);
|
||||
NotificationRecord r = getNotificationRecord(true, IMPORTANCE_UNSPECIFIED);
|
||||
|
||||
extractor.process(r);
|
||||
|
||||
@@ -140,13 +127,23 @@ public class BadgeExtractorTest {
|
||||
BadgeExtractor extractor = new BadgeExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
when(mConfig.badgingEnabled(mUser)).thenReturn(true);
|
||||
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(false);
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel("a", "a", NotificationManager.IMPORTANCE_UNSPECIFIED);
|
||||
channel.setShowBadge(false);
|
||||
when(mConfig.getNotificationChannel(mPkg, mUid, "a", false)).thenReturn(channel);
|
||||
NotificationRecord r = getNotificationRecord(false, IMPORTANCE_UNSPECIFIED);
|
||||
|
||||
NotificationRecord r = getNotificationRecord(channel);
|
||||
extractor.process(r);
|
||||
|
||||
assertFalse(r.canShowBadge());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAppYesChannelYesUserNo() throws Exception {
|
||||
BadgeExtractor extractor = new BadgeExtractor();
|
||||
extractor.setConfig(mConfig);
|
||||
|
||||
when(mConfig.badgingEnabled(mUser)).thenReturn(false);
|
||||
when(mConfig.canShowBadge(mPkg, mUid)).thenReturn(true);
|
||||
NotificationRecord r = getNotificationRecord(true, IMPORTANCE_HIGH);
|
||||
|
||||
extractor.process(r);
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ import android.app.ActivityManager;
|
||||
import android.app.Notification;
|
||||
import android.app.Notification.Builder;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.app.NotificationChannel;
|
||||
import android.graphics.Color;
|
||||
import android.media.AudioAttributes;
|
||||
@@ -47,7 +46,6 @@ import android.os.Vibrator;
|
||||
import android.os.VibrationEffect;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -69,7 +67,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class BuzzBeepBlinkTest {
|
||||
public class BuzzBeepBlinkTest extends NotificationTestCase {
|
||||
|
||||
@Mock AudioManager mAudioManager;
|
||||
@Mock Vibrator mVibrator;
|
||||
@@ -328,10 +326,6 @@ public class BuzzBeepBlinkTest {
|
||||
eq(CUSTOM_LIGHT_COLOR), anyInt(), eq(CUSTOM_LIGHT_ON), eq(CUSTOM_LIGHT_OFF));
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
//
|
||||
// Tests
|
||||
//
|
||||
|
||||
@@ -25,7 +25,6 @@ import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -38,7 +37,7 @@ import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class GlobalSortKeyComparatorTest {
|
||||
public class GlobalSortKeyComparatorTest extends NotificationTestCase {
|
||||
|
||||
private final String PKG = "PKG";
|
||||
private final int UID = 1111111;
|
||||
@@ -46,24 +45,23 @@ public class GlobalSortKeyComparatorTest {
|
||||
|
||||
@Test
|
||||
public void testComparator() throws Exception {
|
||||
Notification n = new Notification.Builder(
|
||||
InstrumentationRegistry.getContext(), TEST_CHANNEL_ID)
|
||||
Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.build();
|
||||
NotificationRecord left = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord left = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
"", 1499), getDefaultChannel());
|
||||
left.setGlobalSortKey("first");
|
||||
|
||||
NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord right = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
"", 1499), getDefaultChannel());
|
||||
right.setGlobalSortKey("second");
|
||||
|
||||
NotificationRecord last = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord last = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
@@ -86,16 +84,15 @@ public class GlobalSortKeyComparatorTest {
|
||||
|
||||
@Test
|
||||
public void testNoCrash_leftNull() throws Exception {
|
||||
Notification n = new Notification.Builder(
|
||||
InstrumentationRegistry.getContext(), TEST_CHANNEL_ID)
|
||||
Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.build();
|
||||
NotificationRecord left = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord left = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
"", 1499), getDefaultChannel());
|
||||
|
||||
NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord right = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
@@ -117,17 +114,16 @@ public class GlobalSortKeyComparatorTest {
|
||||
|
||||
@Test
|
||||
public void testNoCrash_rightNull() throws Exception {
|
||||
Notification n = new Notification.Builder(
|
||||
InstrumentationRegistry.getContext(), TEST_CHANNEL_ID)
|
||||
Notification n = new Notification.Builder(getContext(), TEST_CHANNEL_ID)
|
||||
.build();
|
||||
NotificationRecord left = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord left = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
"", 1499), getDefaultChannel());
|
||||
left.setGlobalSortKey("not null");
|
||||
|
||||
NotificationRecord right = new NotificationRecord(InstrumentationRegistry.getContext(),
|
||||
NotificationRecord right = new NotificationRecord(getContext(),
|
||||
new StatusBarNotification(PKG,
|
||||
PKG, 1, "media", UID, UID, n,
|
||||
new UserHandle(UserHandle.myUserId()),
|
||||
|
||||
@@ -34,10 +34,8 @@ import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -46,15 +44,11 @@ import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class GroupHelperTest {
|
||||
public class GroupHelperTest extends NotificationTestCase {
|
||||
private @Mock GroupHelper.Callback mCallback;
|
||||
|
||||
private GroupHelper mGroupHelper;
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
@@ -24,10 +24,8 @@ import android.app.Notification;
|
||||
import android.app.Notification.Builder;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.NotificationChannel;
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -43,7 +41,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ImportanceExtractorTest {
|
||||
public class ImportanceExtractorTest extends NotificationTestCase {
|
||||
|
||||
@Mock RankingConfig mConfig;
|
||||
|
||||
@@ -75,10 +73,6 @@ public class ImportanceExtractorTest {
|
||||
return r;
|
||||
}
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
//
|
||||
// Tests
|
||||
//
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -51,7 +50,7 @@ import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationComparatorTest {
|
||||
public class NotificationComparatorTest extends NotificationTestCase {
|
||||
@Mock Context mContext;
|
||||
@Mock TelecomManager mTm;
|
||||
@Mock RankingHandler handler;
|
||||
@@ -83,10 +82,8 @@ public class NotificationComparatorTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
int userId = UserHandle.myUserId();
|
||||
|
||||
when(mContext.getResources()).thenReturn(
|
||||
InstrumentationRegistry.getTargetContext().getResources());
|
||||
when(mContext.getContentResolver()).thenReturn(
|
||||
InstrumentationRegistry.getTargetContext().getContentResolver());
|
||||
when(mContext.getResources()).thenReturn(getContext().getResources());
|
||||
when(mContext.getContentResolver()).thenReturn(getContext().getContentResolver());
|
||||
when(mContext.getPackageManager()).thenReturn(mPm);
|
||||
when(mContext.getSystemService(eq(Context.TELECOM_SERVICE))).thenReturn(mTm);
|
||||
when(mTm.getDefaultDialerPackage()).thenReturn(callPkg);
|
||||
|
||||
@@ -38,7 +38,7 @@ import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationListenerServiceTest {
|
||||
public class NotificationListenerServiceTest extends NotificationTestCase {
|
||||
|
||||
private String[] mKeys = new String[] { "key", "key1", "key2", "key3"};
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ import android.graphics.Color;
|
||||
import android.os.Binder;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
@@ -75,7 +75,7 @@ import com.android.server.lights.LightsManager;
|
||||
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@RunWithLooper
|
||||
public class NotificationManagerServiceTest {
|
||||
public class NotificationManagerServiceTest extends NotificationTestCase {
|
||||
private static final long WAIT_FOR_IDLE_TIMEOUT = 2;
|
||||
private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
|
||||
private final int uid = Binder.getCallingUid();
|
||||
@@ -86,7 +86,7 @@ public class NotificationManagerServiceTest {
|
||||
private IPackageManager mPackageManager;
|
||||
@Mock
|
||||
private PackageManager mPackageManagerClient;
|
||||
private Context mContext = InstrumentationRegistry.getTargetContext();
|
||||
private Context mContext = getContext();
|
||||
private final String PKG = mContext.getPackageName();
|
||||
private TestableLooper mTestableLooper;
|
||||
@Mock
|
||||
@@ -122,6 +122,12 @@ public class NotificationManagerServiceTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
// most tests assume badging is enabled
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 1,
|
||||
UserHandle.getUserHandleForUid(uid).getIdentifier());
|
||||
|
||||
mNotificationManagerService = new TestableNotificationManagerService(mContext);
|
||||
|
||||
// MockPackageManager - default returns ApplicationInfo with matching calling UID
|
||||
|
||||
@@ -40,7 +40,6 @@ import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
|
||||
@@ -56,7 +55,7 @@ import java.util.Objects;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationRecordTest {
|
||||
public class NotificationRecordTest extends NotificationTestCase {
|
||||
|
||||
private final Context mMockContext = Mockito.mock(Context.class);
|
||||
@Mock PackageManager mPm;
|
||||
@@ -96,8 +95,7 @@ public class NotificationRecordTest {
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
when(mMockContext.getResources()).thenReturn(
|
||||
InstrumentationRegistry.getContext().getResources());
|
||||
when(mMockContext.getResources()).thenReturn(getContext().getResources());
|
||||
when(mMockContext.getPackageManager()).thenReturn(mPm);
|
||||
|
||||
legacy.targetSdkVersion = Build.VERSION_CODES.N_MR1;
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.server.notification;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import org.junit.Rule;
|
||||
|
||||
|
||||
public class NotificationTestCase {
|
||||
@Rule
|
||||
public final TestableContext mContext =
|
||||
new TestableContext(InstrumentationRegistry.getContext(), null);
|
||||
|
||||
protected Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
}
|
||||
@@ -49,11 +49,14 @@ import android.media.AudioAttributes;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.TestableContext;
|
||||
import android.testing.TestableSettingsProvider;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
import android.util.Xml;
|
||||
@@ -81,11 +84,13 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RankingHelperTest {
|
||||
public class RankingHelperTest extends NotificationTestCase {
|
||||
private static final String PKG = "com.android.server.notification";
|
||||
private static final int UID = 0;
|
||||
private static final UserHandle USER = UserHandle.getUserHandleForUid(UID);
|
||||
private static final String UPDATED_PKG = "updatedPkg";
|
||||
private static final int UID2 = 1111111;
|
||||
private static final UserHandle USER2 = UserHandle.getUserHandleForUid(UID2);
|
||||
private static final String TEST_CHANNEL_ID = "test_channel_id";
|
||||
|
||||
@Mock NotificationUsageStats mUsageStats;
|
||||
@@ -106,10 +111,6 @@ public class RankingHelperTest {
|
||||
private RankingHelper mHelper;
|
||||
private AudioAttributes mAudioAttributes;
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
@@ -126,6 +127,9 @@ public class RankingHelperTest {
|
||||
InstrumentationRegistry.getContext().getResources());
|
||||
when(mContext.getPackageManager()).thenReturn(mPm);
|
||||
when(mContext.getApplicationInfo()).thenReturn(legacy);
|
||||
// most tests assume badging is enabled
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 1, UserHandle.getUserId(UID));
|
||||
|
||||
mHelper = new RankingHelper(getContext(), mPm, mHandler, mUsageStats,
|
||||
new String[] {ImportanceExtractor.class.getName()});
|
||||
@@ -1199,4 +1203,36 @@ public class RankingHelperTest {
|
||||
object.getInt("channelCount"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadgingOverrideTrue() throws Exception {
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 1,
|
||||
USER.getIdentifier());
|
||||
mHelper.updateBadgingEnabled(); // would be called by settings observer
|
||||
assertTrue(mHelper.badgingEnabled(USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadgingOverrideFalse() throws Exception {
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 0,
|
||||
USER.getIdentifier());
|
||||
mHelper.updateBadgingEnabled(); // would be called by settings observer
|
||||
assertFalse(mHelper.badgingEnabled(USER));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBadgingOverrideUserIsolation() throws Exception {
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 0,
|
||||
USER.getIdentifier());
|
||||
Secure.putIntForUser(getContext().getContentResolver(),
|
||||
Secure.NOTIFICATION_BADGING, 1,
|
||||
USER2.getIdentifier());
|
||||
mHelper.updateBadgingEnabled(); // would be called by settings observer
|
||||
assertFalse(mHelper.badgingEnabled(USER));
|
||||
assertTrue(mHelper.badgingEnabled(USER2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import static org.junit.Assert.assertFalse;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class RateEstimatorTest {
|
||||
public class RateEstimatorTest extends NotificationTestCase {
|
||||
private long mTestStartTime;
|
||||
private RateEstimator mEstimator;
|
||||
|
||||
|
||||
@@ -27,11 +27,9 @@ import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.util.Slog;
|
||||
@@ -51,7 +49,7 @@ import static org.mockito.Mockito.when;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class SnoozeHelperTest {
|
||||
public class SnoozeHelperTest extends NotificationTestCase {
|
||||
private static final String TEST_CHANNEL_ID = "test_channel_id";
|
||||
|
||||
@Mock SnoozeHelper.Callback mCallback;
|
||||
@@ -60,10 +58,6 @@ public class SnoozeHelperTest {
|
||||
|
||||
private SnoozeHelper mSnoozeHelper;
|
||||
|
||||
private Context getContext() {
|
||||
return InstrumentationRegistry.getTargetContext();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
@@ -32,7 +32,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ValidateNotificationPeopleTest {
|
||||
public class ValidateNotificationPeopleTest extends NotificationTestCase {
|
||||
|
||||
@Test
|
||||
public void testNoExtra() throws Exception {
|
||||
|
||||
@@ -18,6 +18,7 @@ import android.content.ContentProviderClient;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.test.mock.MockContentProvider;
|
||||
import android.util.Log;
|
||||
@@ -48,9 +49,10 @@ public class TestableSettingsProvider extends MockContentProvider {
|
||||
}
|
||||
|
||||
void clearValuesAndCheck(Context context) {
|
||||
mValues.put(key("global", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
|
||||
mValues.put(key("secure", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
|
||||
mValues.put(key("system", MY_UNIQUE_KEY), MY_UNIQUE_KEY);
|
||||
int userId = UserHandle.myUserId();
|
||||
mValues.put(key("global", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
|
||||
mValues.put(key("secure", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
|
||||
mValues.put(key("system", MY_UNIQUE_KEY, userId), MY_UNIQUE_KEY);
|
||||
|
||||
// Verify that if any test is using TestableContext, they all have the correct settings
|
||||
// provider.
|
||||
@@ -66,11 +68,12 @@ public class TestableSettingsProvider extends MockContentProvider {
|
||||
|
||||
public Bundle call(String method, String arg, Bundle extras) {
|
||||
// Methods are "GET_system", "GET_global", "PUT_secure", etc.
|
||||
final int userId = extras.getInt(Settings.CALL_METHOD_USER_KEY, 0);
|
||||
final String[] commands = method.split("_", 2);
|
||||
final String op = commands[0];
|
||||
final String table = commands[1];
|
||||
|
||||
String k = key(table, arg);
|
||||
String k = key(table, arg, userId);
|
||||
String value;
|
||||
Bundle out = new Bundle();
|
||||
switch (op) {
|
||||
@@ -103,8 +106,13 @@ public class TestableSettingsProvider extends MockContentProvider {
|
||||
return out;
|
||||
}
|
||||
|
||||
private static String key(String table, String key) {
|
||||
return table + "_" + key;
|
||||
private static String key(String table, String key, int userId) {
|
||||
if ("global".equals(table)) {
|
||||
return table + "_" + key;
|
||||
} else {
|
||||
return table + "_" + userId + "_" + key;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -65,6 +65,16 @@ public class TestableSettingsProviderTest {
|
||||
assertEquals("else", Global.getString(mContentResolver, NONEXISTENT_SETTING));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeparateUsers() {
|
||||
Secure.putStringForUser(mContentResolver, NONEXISTENT_SETTING, "something", 0);
|
||||
Secure.putStringForUser(mContentResolver, NONEXISTENT_SETTING, "else", 1);
|
||||
assertEquals("something",
|
||||
Secure.getStringForUser(mContentResolver, NONEXISTENT_SETTING, 0));
|
||||
assertEquals("else",
|
||||
Secure.getStringForUser(mContentResolver, NONEXISTENT_SETTING, 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPassThrough() {
|
||||
// Grab the value of a setting that is not overridden.
|
||||
|
||||
Reference in New Issue
Block a user