Fix xml loading for managed services

Noticed while adding a shell cmd to toggle notification assistants,
which is also included

Test: runtest systemui-notification
Change-Id: I9bc0ee857abb8b9f60ab18ad740ca0a3b7d754ff
This commit is contained in:
Julia Reynolds
2017-07-11 10:39:58 -04:00
parent 3698fc8ea6
commit 88facd4d9a
8 changed files with 211 additions and 199 deletions

View File

@@ -85,7 +85,7 @@ public class ZenModeConfig implements Parcelable {
private static final boolean DEFAULT_ALLOW_SCREEN_ON = true;
private static final int XML_VERSION = 2;
private static final String ZEN_TAG = "zen";
public static final String ZEN_TAG = "zen";
private static final String ZEN_ATT_VERSION = "version";
private static final String ZEN_ATT_USER = "user";
private static final String ALLOW_TAG = "allow";

View File

@@ -35,6 +35,7 @@ import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.notification.NotificationManagerService.DumpFilter;
import java.io.PrintWriter;
@@ -43,7 +44,8 @@ import java.util.Arrays;
public class ConditionProviders extends ManagedServices {
private static final String TAG_ENABLED_DND_APPS = "dnd_apps";
@VisibleForTesting
static final String TAG_ENABLED_DND_APPS = "dnd_apps";
private final ArrayList<ConditionRecord> mRecords = new ArrayList<>();
private final ArraySet<String> mSystemConditionProviderNames;
@@ -84,7 +86,7 @@ public class ConditionProviders extends ManagedServices {
c.caption = "condition provider";
c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES;
c.managedServiceTypeTag = TAG_ENABLED_DND_APPS;
c.xmlTag = TAG_ENABLED_DND_APPS;
c.secondarySettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS;

View File

@@ -52,6 +52,7 @@ import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.util.XmlUtils;
import com.android.server.notification.NotificationManagerService.DumpFilter;
import org.xmlpull.v1.XmlPullParser;
@@ -226,7 +227,7 @@ abstract public class ManagedServices {
}
public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
out.startTag(null, getConfig().managedServiceTypeTag);
out.startTag(null, getConfig().xmlTag);
if (forBackup) {
trimApprovedListsAccordingToInstalledServices();
@@ -241,7 +242,7 @@ abstract public class ManagedServices {
for (int j = 0; j < M; j++) {
final boolean isPrimary = approvedByType.keyAt(j);
final Set<String> approved = approvedByType.valueAt(j);
if (approved != null && approved.size() > 0) {
if (approved != null) {
String allowedItems = String.join(ENABLED_SERVICES_SEPARATOR, approved);
out.startTag(null, TAG_MANAGED_SERVICES);
out.attribute(null, ATT_APPROVED_LIST, allowedItems);
@@ -260,43 +261,34 @@ abstract public class ManagedServices {
}
}
out.endTag(null, getConfig().managedServiceTypeTag);
out.endTag(null, getConfig().xmlTag);
}
/**
* @return false if modifications were made to the data on load that requires the xml file
* to be re-written
*/
public boolean readXml(XmlPullParser parser)
protected void migrateToXml() {
loadAllowedComponentsFromSettings();
}
public void readXml(XmlPullParser parser)
throws XmlPullParserException, IOException {
boolean rewriteXml = false;
int type = parser.getEventType();
String tag = parser.getName();
if (type != XmlPullParser.START_TAG || !getConfig().managedServiceTypeTag.equals(tag)) {
// xml empty/invalid - read from setting instead
loadAllowedComponentsFromSettings();
rewriteXml = true;
} else {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
if (type == XmlPullParser.END_TAG
&& getConfig().managedServiceTypeTag.equals(tag)) {
break;
}
if (type == XmlPullParser.START_TAG) {
if (TAG_MANAGED_SERVICES.equals(tag)) {
final String approved = XmlUtils.safeString(parser, ATT_APPROVED_LIST, "");
final int userId = XmlUtils.safeInt(parser, ATT_USER_ID, 0);
final boolean isPrimary = XmlUtils.safeBool(parser, ATT_IS_PRIMARY, true);
addApprovedList(approved, userId, isPrimary);
}
int type;
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
String tag = parser.getName();
if (type == XmlPullParser.END_TAG
&& getConfig().xmlTag.equals(tag)) {
break;
}
if (type == XmlPullParser.START_TAG) {
if (TAG_MANAGED_SERVICES.equals(tag)) {
final String approved = XmlUtils.readStringAttribute(parser, ATT_APPROVED_LIST);
final int userId = XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
final boolean isPrimary =
XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);
addApprovedList(approved, userId, isPrimary);
mUseXml = true;
}
}
mUseXml = true;
}
rebindServices(false);
return rewriteXml;
}
private void loadAllowedComponentsFromSettings() {
@@ -1119,7 +1111,7 @@ abstract public class ManagedServices {
public String serviceInterface;
public String secureSettingName;
public String secondarySettingName;
public String managedServiceTypeTag;
public String xmlTag;
public String bindPermission;
public String settingsAction;
public int clientLabel;

View File

@@ -55,7 +55,6 @@ import static android.service.notification.NotificationListenerService.TRIM_LIGH
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import android.Manifest;
import android.annotation.NonNull;
@@ -162,6 +161,7 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
@@ -342,7 +342,7 @@ public class NotificationManagerService extends SystemService {
private final UserProfiles mUserProfiles = new UserProfiles();
private NotificationListeners mListeners;
private NotificationAssistants mNotificationAssistants;
private NotificationAssistants mAssistants;
private ConditionProviders mConditionProviders;
private NotificationUsageStats mUsageStats;
@@ -441,24 +441,38 @@ public class NotificationManagerService extends SystemService {
}
}
private void readPolicyXml(InputStream stream, boolean forRestore)
void readPolicyXml(InputStream stream, boolean forRestore)
throws XmlPullParserException, NumberFormatException, IOException {
final XmlPullParser parser = Xml.newPullParser();
parser.setInput(stream, StandardCharsets.UTF_8.name());
boolean saveXml = false;
while (parser.next() != END_DOCUMENT) {
mZenModeHelper.readXml(parser, forRestore);
mRankingHelper.readXml(parser, forRestore);
XmlUtils.beginDocument(parser, TAG_NOTIFICATION_POLICY);
boolean migratedManagedServices = false;
int outerDepth = parser.getDepth();
while (XmlUtils.nextElementWithin(parser, outerDepth)) {
if (ZenModeConfig.ZEN_TAG.equals(parser.getName())) {
mZenModeHelper.readXml(parser, forRestore);
} else if (RankingHelper.TAG_RANKING.equals(parser.getName())){
mRankingHelper.readXml(parser, forRestore);
}
// No non-system managed services are allowed on low ram devices
if (!ActivityManager.isLowRamDeviceStatic()) {
saveXml |= mListeners.readXml(parser);
saveXml |= mNotificationAssistants.readXml(parser);
saveXml |= mConditionProviders.readXml(parser);
if (mListeners.getConfig().xmlTag.equals(parser.getName())) {
mListeners.readXml(parser);
migratedManagedServices = true;
} else if (mAssistants.getConfig().xmlTag.equals(parser.getName())) {
mAssistants.readXml(parser);
migratedManagedServices = true;
} else if (mConditionProviders.getConfig().xmlTag.equals(parser.getName())) {
mConditionProviders.readXml(parser);
migratedManagedServices = true;
}
}
}
if (saveXml) {
if (!migratedManagedServices) {
mListeners.migrateToXml();
mAssistants.migrateToXml();
mConditionProviders.migrateToXml();
savePolicyFile();
}
}
@@ -467,7 +481,7 @@ public class NotificationManagerService extends SystemService {
if (DBG) Slog.d(TAG, "loadPolicyFile");
synchronized (mPolicyFile) {
FileInputStream infile = null;
InputStream infile = null;
try {
infile = mPolicyFile.openRead();
readPolicyXml(infile, false /*forRestore*/);
@@ -523,7 +537,7 @@ public class NotificationManagerService extends SystemService {
mZenModeHelper.writeXml(out, forBackup);
mRankingHelper.writeXml(out, forBackup);
mListeners.writeXml(out, forBackup);
mNotificationAssistants.writeXml(out, forBackup);
mAssistants.writeXml(out, forBackup);
mConditionProviders.writeXml(out, forBackup);
out.endTag(null, TAG_NOTIFICATION_POLICY);
out.endDocument();
@@ -898,7 +912,7 @@ public class NotificationManagerService extends SystemService {
}
}
mListeners.onPackagesChanged(removingPackage, pkgList, uidList);
mNotificationAssistants.onPackagesChanged(removingPackage, pkgList, uidList);
mAssistants.onPackagesChanged(removingPackage, pkgList, uidList);
mConditionProviders.onPackagesChanged(removingPackage, pkgList, uidList);
mRankingHelper.onPackagesChanged(removingPackage, changeUserId, pkgList, uidList);
savePolicyFile();
@@ -970,7 +984,7 @@ public class NotificationManagerService extends SystemService {
// Refresh managed services
mConditionProviders.onUserSwitched(user);
mListeners.onUserSwitched(user);
mNotificationAssistants.onUserSwitched(user);
mAssistants.onUserSwitched(user);
mZenModeHelper.onUserSwitched(user);
} else if (action.equals(Intent.ACTION_USER_ADDED)) {
mUserProfiles.updateCache(context);
@@ -983,7 +997,7 @@ public class NotificationManagerService extends SystemService {
final int user = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
mConditionProviders.onUserUnlocked(user);
mListeners.onUserUnlocked(user);
mNotificationAssistants.onUserUnlocked(user);
mAssistants.onUserUnlocked(user);
mZenModeHelper.onUserUnlocked(user);
}
}
@@ -1231,7 +1245,7 @@ public class NotificationManagerService extends SystemService {
mListeners = notificationListeners;
// This is a MangedServices object that keeps track of the assistant.
mNotificationAssistants = notificationAssistants;
mAssistants = notificationAssistants;
mPolicyFile = policyFile;
loadPolicyFile();
@@ -1399,7 +1413,7 @@ public class NotificationManagerService extends SystemService {
// bind to listener services.
mSettingsObserver.observe();
mListeners.onBootPhaseAppsCanStart();
mNotificationAssistants.onBootPhaseAppsCanStart();
mAssistants.onBootPhaseAppsCanStart();
mConditionProviders.onBootPhaseAppsCanStart();
}
}
@@ -1568,7 +1582,6 @@ public class NotificationManagerService extends SystemService {
Slog.e(TAG, "Not doing toast. pkg=" + pkg + " callback=" + callback);
return ;
}
final boolean isSystemToast = isCallerSystemOrPhone() || ("android".equals(pkg));
final boolean isPackageSuspended =
isPackageSuspendedForUser(pkg, Binder.getCallingUid());
@@ -1927,7 +1940,7 @@ public class NotificationManagerService extends SystemService {
// Listener & assistant
mListeners.onPackagesChanged(true, packages, uids);
mNotificationAssistants.onPackagesChanged(true, packages, uids);
mAssistants.onPackagesChanged(true, packages, uids);
// Zen
mConditionProviders.onPackagesChanged(true, packages, uids);
@@ -2133,8 +2146,8 @@ public class NotificationManagerService extends SystemService {
long identity = Binder.clearCallingIdentity();
try {
ManagedServices manager =
mNotificationAssistants.isComponentEnabledForCurrentProfiles(component)
? mNotificationAssistants
mAssistants.isComponentEnabledForCurrentProfiles(component)
? mAssistants
: mListeners;
manager.setComponentState(component, true);
} finally {
@@ -2254,7 +2267,7 @@ public class NotificationManagerService extends SystemService {
try {
synchronized (mNotificationLock) {
final ManagedServiceInfo info =
mNotificationAssistants.checkServiceTokenLocked(token);
mAssistants.checkServiceTokenLocked(token);
unsnoozeNotificationInt(key, info);
}
} finally {
@@ -2787,7 +2800,7 @@ public class NotificationManagerService extends SystemService {
public boolean isNotificationAssistantAccessGranted(ComponentName assistant) {
Preconditions.checkNotNull(assistant);
checkCallerIsSystemOrSameApp(assistant.getPackageName());
return mNotificationAssistants.isPackageOrComponentAllowed(assistant.flattenToString(),
return mAssistants.isPackageOrComponentAllowed(assistant.flattenToString(),
getCallingUserHandle().getIdentifier());
}
@@ -2834,7 +2847,7 @@ public class NotificationManagerService extends SystemService {
if (!mActivityManager.isLowRamDevice()) {
mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
userId, false, granted);
mNotificationAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
userId, true, granted);
getContext().sendBroadcastAsUser(new Intent(
@@ -2853,7 +2866,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
mNotificationAssistants.checkServiceTokenLocked(token);
mAssistants.checkServiceTokenLocked(token);
int N = mEnqueuedNotifications.size();
for (int i = 0; i < N; i++) {
final NotificationRecord n = mEnqueuedNotifications.get(i);
@@ -2875,7 +2888,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
mNotificationAssistants.checkServiceTokenLocked(token);
mAssistants.checkServiceTokenLocked(token);
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
applyAdjustment(n, adjustment);
}
@@ -2892,7 +2905,7 @@ public class NotificationManagerService extends SystemService {
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mNotificationLock) {
mNotificationAssistants.checkServiceTokenLocked(token);
mAssistants.checkServiceTokenLocked(token);
for (Adjustment adjustment : adjustments) {
NotificationRecord n = mNotificationsByKey.get(adjustment.getKey());
applyAdjustment(n, adjustment);
@@ -3272,7 +3285,7 @@ public class NotificationManagerService extends SystemService {
}
pw.println(')');
pw.println("\n Notification assistant services:");
mNotificationAssistants.dump(pw, filter);
mAssistants.dump(pw, filter);
}
if (!filter.filtered || zenOnly) {
@@ -3663,7 +3676,7 @@ public class NotificationManagerService extends SystemService {
cancelNotificationLocked(r, false, REASON_SNOOZED, wasPosted);
updateLightsLocked();
if (mSnoozeCriterionId != null) {
mNotificationAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
mAssistants.notifyAssistantSnoozedLocked(r.sbn, mSnoozeCriterionId);
mSnoozeHelper.snooze(r);
} else {
mSnoozeHelper.snooze(r, mDuration);
@@ -3727,8 +3740,8 @@ public class NotificationManagerService extends SystemService {
mRankingHelper.extractSignals(r);
// tell the assistant service about the notification
if (mNotificationAssistants.isEnabled()) {
mNotificationAssistants.onNotificationEnqueued(r);
if (mAssistants.isEnabled()) {
mAssistants.onNotificationEnqueued(r);
mHandler.postDelayed(new PostNotificationRunnable(r.getKey()),
DELAY_FOR_ASSISTANT_TIME);
} else {
@@ -5237,7 +5250,7 @@ public class NotificationManagerService extends SystemService {
Config c = new Config();
c.caption = "notification assistant service";
c.serviceInterface = NotificationAssistantService.SERVICE_INTERFACE;
c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS;
c.xmlTag = TAG_ENABLED_NOTIFICATION_ASSISTANTS;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT;
c.bindPermission = Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE;
c.settingsAction = Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS;
@@ -5349,7 +5362,7 @@ public class NotificationManagerService extends SystemService {
Config c = new Config();
c.caption = "notification listener";
c.serviceInterface = NotificationListenerService.SERVICE_INTERFACE;
c.managedServiceTypeTag = TAG_ENABLED_NOTIFICATION_LISTENERS;
c.xmlTag = TAG_ENABLED_NOTIFICATION_LISTENERS;
c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
c.bindPermission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
c.settingsAction = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS;

View File

@@ -20,6 +20,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -64,7 +65,7 @@ public class RankingHelper implements RankingConfig {
private static final int XML_VERSION = 1;
private static final String TAG_RANKING = "ranking";
static final String TAG_RANKING = "ranking";
private static final String TAG_PACKAGE = "package";
private static final String TAG_CHANNEL = "channel";
private static final String TAG_GROUP = "channelGroup";
@@ -169,7 +170,7 @@ public class RankingHelper implements RankingConfig {
}
if (type == XmlPullParser.START_TAG) {
if (TAG_PACKAGE.equals(tag)) {
int uid = XmlUtils.safeInt(parser, ATT_UID, Record.UNKNOWN_UID);
int uid = XmlUtils.readIntAttribute(parser, ATT_UID, Record.UNKNOWN_UID);
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
if (forRestore) {
@@ -182,14 +183,21 @@ public class RankingHelper implements RankingConfig {
}
Record r = getOrCreateRecord(name, uid,
XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
r.importance = XmlUtils.safeInt(parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
r.priority = XmlUtils.safeInt(parser, ATT_PRIORITY, DEFAULT_PRIORITY);
r.visibility = XmlUtils.safeInt(parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
r.showBadge = XmlUtils.safeBool(parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
XmlUtils.readIntAttribute(
parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE),
XmlUtils.readIntAttribute(parser, ATT_PRIORITY, DEFAULT_PRIORITY),
XmlUtils.readIntAttribute(
parser, ATT_VISIBILITY, DEFAULT_VISIBILITY),
XmlUtils.readBooleanAttribute(
parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE));
r.importance = XmlUtils.readIntAttribute(
parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
r.priority = XmlUtils.readIntAttribute(
parser, ATT_PRIORITY, DEFAULT_PRIORITY);
r.visibility = XmlUtils.readIntAttribute(
parser, ATT_VISIBILITY, DEFAULT_VISIBILITY);
r.showBadge = XmlUtils.readBooleanAttribute(
parser, ATT_SHOW_BADGE, DEFAULT_SHOW_BADGE);
final int innerDepth = parser.getDepth();
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -214,7 +222,7 @@ public class RankingHelper implements RankingConfig {
if (TAG_CHANNEL.equals(tagName)) {
String id = parser.getAttributeValue(null, ATT_ID);
String channelName = parser.getAttributeValue(null, ATT_NAME);
int channelImportance = XmlUtils.safeInt(
int channelImportance = XmlUtils.readIntAttribute(
parser, ATT_IMPORTANCE, DEFAULT_IMPORTANCE);
if (!TextUtils.isEmpty(id) && !TextUtils.isEmpty(channelName)) {
NotificationChannel channel = new NotificationChannel(id,

View File

@@ -1,52 +0,0 @@
/**
* 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.annotation.NonNull;
import android.text.TextUtils;
import org.xmlpull.v1.XmlPullParser;
class XmlUtils {
static @NonNull String safeString(XmlPullParser parser, String att, String defValue) {
final String value = parser.getAttributeValue(null, att);
if (value == null) return defValue;
return value;
}
static @NonNull boolean safeBool(XmlPullParser parser, String att, boolean defValue) {
final String value = parser.getAttributeValue(null, att);
if (TextUtils.isEmpty(value)) return defValue;
return Boolean.parseBoolean(value);
}
static @NonNull int safeInt(XmlPullParser parser, String att, int defValue) {
final String val = parser.getAttributeValue(null, att);
return tryParseInt(val, defValue);
}
private static int tryParseInt(String value, int defValue) {
if (TextUtils.isEmpty(value)) return defValue;
try {
return Integer.parseInt(value);
} catch (NumberFormatException e) {
return defValue;
}
}
}

View File

@@ -170,7 +170,7 @@ public class ManagedServicesTest extends NotificationTestCase {
null);
writeExpectedValuesToSettings(approvalLevel);
assertTrue(service.readXml(parser));
service.migrateToXml();
verifyExpectedApprovedEntries(service);
}
@@ -182,7 +182,7 @@ public class ManagedServicesTest extends NotificationTestCase {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
assertFalse(loadXml(service));
loadXml(service);
verifyExpectedApprovedEntries(service);
}
@@ -239,7 +239,7 @@ public class ManagedServicesTest extends NotificationTestCase {
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(baos.toByteArray())), null);
parser.nextTag();
assertFalse(service.readXml(parser));
service.readXml(parser);
verifyExpectedApprovedEntries(service);
assertFalse(service.isPackageOrComponentAllowed("this.is.a.package.name", 0));
@@ -341,11 +341,8 @@ public class ManagedServicesTest extends NotificationTestCase {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
null);
writeExpectedValuesToSettings(approvalLevel);
service.readXml(parser);
service.migrateToXml();
mExpectedPrimaryPackages.put(0, "another.package");
mExpectedPrimaryComponentNames.put(0, "another.package/B1");
@@ -360,11 +357,8 @@ public class ManagedServicesTest extends NotificationTestCase {
for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
mIpm, approvalLevel);
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(new ByteArrayInputStream(new byte[]{})),
null);
writeExpectedValuesToSettings(approvalLevel);
service.readXml(parser);
service.migrateToXml();
mExpectedSecondaryComponentNames.put(10, "component/2");
mExpectedSecondaryPackages.put(10, "component");
@@ -516,9 +510,9 @@ public class ManagedServicesTest extends NotificationTestCase {
assertEquals(0, service.getAllowedComponents(10).size());
}
private boolean loadXml(ManagedServices service) throws Exception {
private void loadXml(ManagedServices service) throws Exception {
final StringBuffer xml = new StringBuffer();
xml.append("<" + service.getConfig().managedServiceTypeTag + ">\n");
xml.append("<" + service.getConfig().xmlTag + ">\n");
for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
xml.append(getXmlEntry(
mExpectedPrimary.get(service.mApprovalLevel).get(userId), userId, true));
@@ -527,13 +521,13 @@ public class ManagedServicesTest extends NotificationTestCase {
xml.append(getXmlEntry(
mExpectedSecondary.get(service.mApprovalLevel).get(userId), userId, false));
}
xml.append("</" + service.getConfig().managedServiceTypeTag + ">");
xml.append("</" + service.getConfig().xmlTag + ">");
XmlPullParser parser = Xml.newPullParser();
parser.setInput(new BufferedInputStream(
new ByteArrayInputStream(xml.toString().getBytes())), null);
parser.nextTag();
return service.readXml(parser);
service.readXml(parser);
}
private void addExpectedServices(final ManagedServices service, final List<String> packages,
@@ -674,7 +668,7 @@ public class ManagedServicesTest extends NotificationTestCase {
@Override
protected Config getConfig() {
final Config c = new Config();
c.managedServiceTypeTag= "test";
c.xmlTag = "test";
c.secureSettingName = SETTING;
c.secondarySettingName = SECONDARY_SETTING;
c.bindPermission = "permission";

View File

@@ -20,9 +20,6 @@ import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_NONE;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static com.android.server.notification.NotificationManagerService
.MESSAGE_SEND_RANKING_UPDATE;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -34,12 +31,10 @@ import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -60,35 +55,34 @@ import android.content.pm.ParceledListSlice;
import android.graphics.Color;
import android.media.AudioManager;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
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.service.notification.ZenModeConfig;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.util.ArrayMap;
import android.util.AtomicFile;
import android.util.Log;
import android.util.Slog;
import com.android.server.lights.Light;
import com.android.server.lights.LightsManager;
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
import com.android.server.notification.NotificationManagerService.NotificationListeners;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.stubbing.Answer;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -115,7 +109,6 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
private TestableLooper mTestableLooper;
@Mock
private RankingHelper mRankingHelper;
@Mock
AtomicFile mPolicyFile;
File mFile;
@Mock
@@ -129,8 +122,8 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
private NotificationChannel mTestNotificationChannel = new NotificationChannel(
TEST_CHANNEL_ID, TEST_CHANNEL_ID, NotificationManager.IMPORTANCE_DEFAULT);
@Mock
private NotificationManagerService.NotificationListeners mNotificationListeners;
@Mock private NotificationManagerService.NotificationAssistants mNotificationAssistants;
private NotificationListeners mListeners;
@Mock private NotificationAssistants mAssistants;
@Mock private ConditionProviders mConditionProviders;
private ManagedServices.ManagedServiceInfo mListener;
@Mock private ICompanionDeviceManager mCompanionMgr;
@@ -182,18 +175,34 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mockLightsManager.getLight(anyInt())).thenReturn(mock(Light.class));
when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
// write to a test file; the system file isn't readable from tests
mFile = new File(mContext.getCacheDir(), "test.xml");
mFile.createNewFile();
when(mPolicyFile.openRead()).thenReturn(new FileInputStream(mFile));
when(mPolicyFile.startWrite()).thenReturn(new FileOutputStream(mFile));
final String preupgradeXml = "<notification-policy></notification-policy>";
mPolicyFile = new AtomicFile(mFile);
FileOutputStream fos = mPolicyFile.startWrite();
fos.write(preupgradeXml.getBytes());
mPolicyFile.finishWrite(fos);
FileInputStream fStream = new FileInputStream(mFile);
mListener = mNotificationListeners.new ManagedServiceInfo(
// Setup managed services
mListener = mListeners.new ManagedServiceInfo(
null, new ComponentName(PKG, "test_class"), uid, true, null, 0);
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
ManagedServices.Config listenerConfig = new ManagedServices.Config();
listenerConfig.xmlTag = NotificationListeners.TAG_ENABLED_NOTIFICATION_LISTENERS;
when(mListeners.getConfig()).thenReturn(listenerConfig);
ManagedServices.Config assistantConfig = new ManagedServices.Config();
assistantConfig.xmlTag = NotificationAssistants.TAG_ENABLED_NOTIFICATION_ASSISTANTS;
when(mAssistants.getConfig()).thenReturn(assistantConfig);
ManagedServices.Config dndConfig = new ManagedServices.Config();
dndConfig.xmlTag = ConditionProviders.TAG_ENABLED_DND_APPS;
when(mConditionProviders.getConfig()).thenReturn(dndConfig);
try {
mNotificationManagerService.init(mTestableLooper.getLooper(),
mPackageManager, mPackageManagerClient, mockLightsManager,
mNotificationListeners, mNotificationAssistants, mConditionProviders,
mListeners, mAssistants, mConditionProviders,
mCompanionMgr, mSnoozeHelper, mUsageStats, mPolicyFile, mActivityManager,
mGroupHelper);
} catch (SecurityException e) {
@@ -786,13 +795,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
eq(channel2.getId()), anyBoolean()))
.thenReturn(channel2);
reset(mNotificationListeners);
reset(mListeners);
mBinderService.createNotificationChannels(PKG,
new ParceledListSlice(Arrays.asList(mTestNotificationChannel, channel2)));
verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(channel2),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
}
@@ -806,13 +815,13 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
NotificationChannelGroup group1 = new NotificationChannelGroup("a", "b");
NotificationChannelGroup group2 = new NotificationChannelGroup("n", "m");
reset(mNotificationListeners);
reset(mListeners);
mBinderService.createNotificationChannelGroups(PKG,
new ParceledListSlice(Arrays.asList(group1, group2)));
verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(group1),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(group2),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_ADDED));
}
@@ -828,9 +837,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
eq(mTestNotificationChannel.getId()), anyBoolean()))
.thenReturn(mTestNotificationChannel);
reset(mNotificationListeners);
reset(mListeners);
mBinderService.updateNotificationChannelForPackage(PKG, 0, mTestNotificationChannel);
verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -844,9 +853,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mRankingHelper.getNotificationChannel(eq(PKG), anyInt(),
eq(mTestNotificationChannel.getId()), anyBoolean()))
.thenReturn(mTestNotificationChannel);
reset(mNotificationListeners);
reset(mListeners);
mBinderService.deleteNotificationChannel(PKG, mTestNotificationChannel.getId());
verify(mNotificationListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
}
@@ -860,9 +869,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mNotificationManagerService.setRankingHelper(mRankingHelper);
when(mRankingHelper.getNotificationChannelGroup(eq(ncg.getId()), eq(PKG), anyInt()))
.thenReturn(ncg);
reset(mNotificationListeners);
reset(mListeners);
mBinderService.deleteNotificationChannelGroup(PKG, ncg.getId());
verify(mNotificationListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
verify(mListeners, times(1)).notifyNotificationChannelGroupChanged(eq(PKG),
eq(Process.myUserHandle()), eq(ncg),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_DELETED));
}
@@ -879,7 +888,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, times(1)).updateNotificationChannel(anyString(), anyInt(), any());
verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -900,7 +909,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -914,7 +923,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mListener = mock(ManagedServices.ManagedServiceInfo.class);
mListener.component = new ComponentName(PKG, PKG);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.updateNotificationChannelFromPrivilegedListener(
@@ -926,7 +935,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mRankingHelper, never()).updateNotificationChannel(anyString(), anyInt(), any());
verify(mNotificationListeners, never()).notifyNotificationChannelChanged(eq(PKG),
verify(mListeners, never()).notifyNotificationChannelChanged(eq(PKG),
eq(Process.myUserHandle()), eq(mTestNotificationChannel),
eq(NotificationListenerService.NOTIFICATION_CHANNEL_OR_GROUP_UPDATED));
}
@@ -971,7 +980,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
mListener = mock(ManagedServices.ManagedServiceInfo.class);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.getNotificationChannelsFromPrivilegedListener(
@@ -1022,7 +1031,7 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
when(mCompanionMgr.getAssociations(PKG, uid)).thenReturn(associations);
mListener = mock(ManagedServices.ManagedServiceInfo.class);
when(mListener.enabledAndUserMatches(anyInt())).thenReturn(false);
when(mNotificationListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
when(mListeners.checkServiceTokenLocked(any())).thenReturn(mListener);
try {
mBinderService.getNotificationChannelGroupsFromPrivilegedListener(
@@ -1191,11 +1200,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
}
verify(mNotificationListeners, times(1)).setPackageOrComponentEnabled(
verify(mListeners, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1210,11 +1219,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
}
}
verify(mNotificationAssistants, times(1)).setPackageOrComponentEnabled(
verify(mAssistants, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
verify(mListeners, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1231,9 +1240,9 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.getPackageName(), 0, true, true);
verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
verify(mListeners, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1243,11 +1252,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
ComponentName c = ComponentName.unflattenFromString("package/Component");
mBinderService.setNotificationListenerAccessGranted(c, true);
verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1258,11 +1267,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mBinderService.setNotificationAssistantAccessGranted(c, true);
verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1272,11 +1281,11 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
ComponentName c = ComponentName.unflattenFromString("package/Component");
mBinderService.setNotificationPolicyAccessGranted(c.getPackageName(), true);
verify(mNotificationListeners, never()).setPackageOrComponentEnabled(
verify(mListeners, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, true, true);
verify(mConditionProviders, never()).setPackageOrComponentEnabled(
c.flattenToString(), 0, false, true);
verify(mNotificationAssistants, never()).setPackageOrComponentEnabled(
verify(mAssistants, never()).setPackageOrComponentEnabled(
any(), anyInt(), anyBoolean(), anyBoolean());
}
@@ -1427,4 +1436,50 @@ public class NotificationManagerServiceTest extends NotificationTestCase {
mNotificationManagerService.handleRankingSort();
verify(handler, never()).scheduleSendRankingUpdate();
}
@Test
public void testReadPolicyXml_readApprovedServicesFromXml() throws Exception {
final String preupgradeXml = "<notification-policy version=\"1\">"
+ "<zen></zen>"
+ "<ranking></ranking>"
+ "<enabled_listeners>"
+ "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ "</enabled_listeners>"
+ "<enabled_assistants>"
+ "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ "</enabled_assistants>"
+ "<dnd_apps>"
+ "<service_listing approved=\"test\" user=\"0\" primary=\"true\" />"
+ "</dnd_apps>"
+ "</notification-policy>";
mNotificationManagerService.readPolicyXml(
new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
verify(mListeners, times(1)).readXml(any());
verify(mConditionProviders, times(1)).readXml(any());
verify(mAssistants, times(1)).readXml(any());
// numbers are inflated for setup
verify(mListeners, times(1)).migrateToXml();
verify(mConditionProviders, times(1)).migrateToXml();
verify(mAssistants, times(1)).migrateToXml();
}
@Test
public void testReadPolicyXml_readApprovedServicesFromSettings() throws Exception {
final String preupgradeXml = "<notification-policy version=\"1\">"
+ "<zen></zen>"
+ "<ranking></ranking>"
+ "</notification-policy>";
mNotificationManagerService.readPolicyXml(
new BufferedInputStream(new ByteArrayInputStream(preupgradeXml.getBytes())), false);
verify(mListeners, never()).readXml(any());
verify(mConditionProviders, never()).readXml(any());
verify(mAssistants, never()).readXml(any());
// numbers are inflated for setup
verify(mListeners, times(2)).migrateToXml();
verify(mConditionProviders, times(2)).migrateToXml();
verify(mAssistants, times(2)).migrateToXml();
}
}