Merge "Apps that hold SAW perm on restore get bubble all by default" into rvc-dev am: 06e3609a12 am: e485d3dd2a

Change-Id: I0163e74e1b4b0f36efe934a7760b8b3e4608248b
This commit is contained in:
Mady Mellor
2020-04-15 21:02:47 +00:00
committed by Automerger Merge Worker
3 changed files with 129 additions and 23 deletions

View File

@@ -1992,7 +1992,8 @@ public class NotificationManagerService extends SystemService {
mPackageManagerClient,
mRankingHandler,
mZenModeHelper,
new NotificationChannelLoggerImpl());
new NotificationChannelLoggerImpl(),
mAppOps);
mRankingHelper = new RankingHelper(getContext(),
mRankingHandler,
mPreferencesHelper,

View File

@@ -16,7 +16,9 @@
package com.android.server.notification;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.NotificationChannel.PLACEHOLDER_CONVERSATION_ID;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
@@ -30,6 +32,7 @@ import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -79,7 +82,9 @@ import java.util.concurrent.ConcurrentHashMap;
public class PreferencesHelper implements RankingConfig {
private static final String TAG = "NotificationPrefHelper";
private static final int XML_VERSION = 1;
private static final int XML_VERSION = 2;
/** What version to check to do the upgrade for bubbles. */
private static final int XML_VERSION_BUBBLES_UPGRADE = 1;
private static final int UNKNOWN_UID = UserHandle.USER_NULL;
private static final String NON_BLOCKABLE_CHANNEL_DELIM = ":";
@@ -151,6 +156,7 @@ public class PreferencesHelper implements RankingConfig {
private final RankingHandler mRankingHandler;
private final ZenModeHelper mZenModeHelper;
private final NotificationChannelLogger mNotificationChannelLogger;
private final AppOpsManager mAppOps;
private SparseBooleanArray mBadgingEnabled;
private boolean mBubblesEnabledGlobally = DEFAULT_GLOBAL_ALLOW_BUBBLE;
@@ -167,12 +173,14 @@ public class PreferencesHelper implements RankingConfig {
}
public PreferencesHelper(Context context, PackageManager pm, RankingHandler rankingHandler,
ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger) {
ZenModeHelper zenHelper, NotificationChannelLogger notificationChannelLogger,
AppOpsManager appOpsManager) {
mContext = context;
mZenModeHelper = zenHelper;
mRankingHandler = rankingHandler;
mPm = pm;
mNotificationChannelLogger = notificationChannelLogger;
mAppOps = appOpsManager;
// STOPSHIP (b/142218092) this should be removed before ship
if (!wasBadgingForcedTrue(context)) {
@@ -195,6 +203,15 @@ public class PreferencesHelper implements RankingConfig {
if (type != XmlPullParser.START_TAG) return;
String tag = parser.getName();
if (!TAG_RANKING.equals(tag)) return;
boolean upgradeForBubbles = false;
if (parser.getAttributeCount() > 0) {
String attribute = parser.getAttributeName(0);
if (ATT_VERSION.equals(attribute)) {
int xmlVersion = Integer.parseInt(parser.getAttributeValue(0));
upgradeForBubbles = xmlVersion == XML_VERSION_BUBBLES_UPGRADE;
}
}
synchronized (mPackagePreferences) {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
@@ -220,6 +237,16 @@ public class PreferencesHelper implements RankingConfig {
}
}
boolean skipWarningLogged = false;
boolean hasSAWPermission = false;
if (upgradeForBubbles) {
hasSAWPermission = mAppOps.noteOpNoThrow(
OP_SYSTEM_ALERT_WINDOW, uid, name, null,
"check-notif-bubble") == AppOpsManager.MODE_ALLOWED;
}
int bubblePref = hasSAWPermission
? BUBBLE_PREFERENCE_ALL
: XmlUtils.readIntAttribute(parser, ATT_ALLOW_BUBBLE,
DEFAULT_BUBBLE_PREFERENCE);
PackagePreferences r = getOrCreatePackagePreferencesLocked(
name, userId, uid,
@@ -231,8 +258,7 @@ public class PreferencesHelper implements RankingConfig {
parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
XmlUtils.readBooleanAttribute(
parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE),
XmlUtils.readIntAttribute(
parser, ATT_ALLOW_BUBBLE, DEFAULT_BUBBLE_PREFERENCE));
bubblePref);
r.importance = XmlUtils.readIntAttribute(
parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
r.priority = XmlUtils.readIntAttribute(

View File

@@ -15,6 +15,9 @@
*/
package com.android.server.notification;
import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.NotificationChannel.CONVERSATION_CHANNEL_ID_FORMAT;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_ALL;
import static android.app.NotificationManager.BUBBLE_PREFERENCE_NONE;
@@ -50,6 +53,7 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
@@ -132,6 +136,7 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Spy IContentProvider mTestIContentProvider = new MockIContentProvider();
@Mock Context mContext;
@Mock ZenModeHelper mMockZenModeHelper;
@Mock AppOpsManager mAppOpsManager;
private NotificationManager.Policy mTestNotificationPolicy;
@@ -187,7 +192,10 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
when(mAppOpsManager.noteOpNoThrow(anyInt(), anyInt(),
anyString(), eq(null), anyString())).thenReturn(MODE_DEFAULT);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
resetZenModeHelper();
mAudioAttributes = new AudioAttributes.Builder()
@@ -1464,7 +1472,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0,
NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any());
resetZenModeHelper();
@@ -1475,7 +1484,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
// start notification policy off with mAreChannelsBypassingDnd = false
mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
assertFalse(mHelper.areChannelsBypassingDnd());
verify(mMockZenModeHelper, never()).setNotificationPolicy(any());
resetZenModeHelper();
@@ -2241,7 +2251,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
+ "content_type=\"4\" flags=\"0\" show_badge=\"true\" />\n"
+ "</package>\n"
+ "</ranking>\n";
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadByteArrayXml(preQXml.getBytes(), true, UserHandle.USER_SYSTEM);
assertEquals(PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2253,7 +2264,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.setHideSilentStatusIcons(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(!PreferencesHelper.DEFAULT_HIDE_SILENT_STATUS_BAR_ICONS,
@@ -2349,7 +2361,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.setImportance(PKG_O, UID_O, IMPORTANCE_UNSPECIFIED);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2360,7 +2373,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.setNotificationDelegate(PKG_O, UID_O, "other", 53);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals("other", mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2372,7 +2386,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertNull(mHelper.getNotificationDelegate(PKG_O, UID_O));
@@ -2384,7 +2399,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.toggleNotificationDelegate(PKG_O, UID_O, false);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
@@ -2402,7 +2418,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.revokeNotificationDelegate(PKG_O, UID_O);
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
// appears disabled
@@ -2417,16 +2434,73 @@ public class PreferencesHelperTest extends UiServiceTestCase {
@Test
public void testBubblePreference_defaults() throws Exception {
assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
assertEquals(BUBBLE_PREFERENCE_NONE, mHelper.getBubblePreference(PKG_O, UID_O));
assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
}
@Test
public void testBubblePreference_upgradeWithSAWPermission() throws Exception {
when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
+ "<channel id=\"someId\" name=\"hi\""
+ " importance=\"3\"/>"
+ "</package>"
+ "</ranking>";
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
null);
parser.nextTag();
mHelper.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
}
@Test
public void testBubblePreference_upgradeWithSAWThenUserOverride() throws Exception {
when(mAppOpsManager.noteOpNoThrow(eq(OP_SYSTEM_ALERT_WINDOW), anyInt(),
anyString(), eq(null), anyString())).thenReturn(MODE_ALLOWED);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\">\n"
+ "<channel id=\"someId\" name=\"hi\""
+ " importance=\"3\"/>"
+ "</package>"
+ "</ranking>";
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(xml.getBytes())),
null);
parser.nextTag();
mHelper.readXml(parser, false, UserHandle.USER_ALL);
assertEquals(BUBBLE_PREFERENCE_ALL, mHelper.getBubblePreference(PKG_O, UID_O));
assertEquals(0, mHelper.getAppLockedFields(PKG_O, UID_O));
mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_SELECTED);
assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
mHelper.getAppLockedFields(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(BUBBLE_PREFERENCE_SELECTED, mHelper.getBubblePreference(PKG_O, UID_O));
assertEquals(PreferencesHelper.LockableAppFields.USER_LOCKED_BUBBLE,
mHelper.getAppLockedFields(PKG_O, UID_O));
}
@Test
public void testBubblePreference_xml() throws Exception {
mHelper.setBubblesAllowed(PKG_O, UID_O, BUBBLE_PREFERENCE_NONE);
@@ -2435,7 +2509,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
mHelper.getAppLockedFields(PKG_O, UID_O));
ByteArrayOutputStream baos = writeXmlAndPurge(PKG_O, UID_O, false, UserHandle.USER_ALL);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
loadStreamXml(baos, false, UserHandle.USER_ALL);
assertEquals(mHelper.getBubblePreference(PKG_O, UID_O), BUBBLE_PREFERENCE_NONE);
@@ -2949,7 +3024,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 0);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -2969,7 +3045,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testPlaceholderConversationId_shortcutRequired() throws Exception {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -2989,7 +3066,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testNormalConversationId_shortcutRequired() throws Exception {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"
@@ -3009,7 +3087,8 @@ public class PreferencesHelperTest extends UiServiceTestCase {
public void testNoConversationId_shortcutRequired() throws Exception {
Settings.Global.putInt(mContext.getContentResolver(),
Settings.Global.REQUIRE_SHORTCUTS_FOR_CONVERSATIONS, 1);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger);
mHelper = new PreferencesHelper(getContext(), mPm, mHandler, mMockZenModeHelper, mLogger,
mAppOpsManager);
final String xml = "<ranking version=\"1\">\n"
+ "<package name=\"" + PKG_O + "\" uid=\"" + UID_O + "\" >\n"