Add managed profile whitelist to control NotificationListenerServices
Only let notification listeners installed in the primary profile
see work profile notification if allowed by policy
Bug: 36657192
Test: runtest systemui-notification
Test: runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services
Change-Id: If719151644380e9162180a24d12f798e42867c0a
(cherry picked from commit 7e4cbadc6a561be62bf3b5e4c949bbb863018cc7)
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 3cb2f35..b8d633f 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -19,10 +19,12 @@
import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
+import static android.content.Context.DEVICE_POLICY_SERVICE;
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PendingIntent;
+import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -39,6 +41,7 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
+import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -895,7 +898,9 @@
if (this.userid == UserHandle.USER_ALL) return true;
if (this.isSystem) return true;
if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
- return supportsProfiles() && mUserProfiles.isCurrentProfile(nid);
+ return supportsProfiles()
+ && mUserProfiles.isCurrentProfile(nid)
+ && isPermittedForProfile(nid);
}
public boolean supportsProfiles() {
@@ -906,7 +911,7 @@
public void binderDied() {
if (DEBUG) Slog.d(TAG, "binderDied");
// Remove the service, but don't unbind from the service. The system will bring the
- // service back up, and the onServiceConnected handler will readd the service with the
+ // service back up, and the onServiceConnected handler will read the service with the
// new binding. If this isn't a bound service, and is just a registered
// service, just removing it from the list is all we need to do anyway.
removeServiceImpl(this.service, this.userid);
@@ -918,6 +923,26 @@
if (this.connection == null) return false;
return mEnabledServicesForCurrentProfiles.contains(this.component);
}
+
+ /**
+ * Returns true if this service is allowed to receive events for the given userId. A
+ * managed profile owner can disallow non-system services running outside of the profile
+ * from receiving events from the profile.
+ */
+ public boolean isPermittedForProfile(int userId) {
+ if (!mUserProfiles.isManagedProfile(userId)) {
+ return true;
+ }
+ DevicePolicyManager dpm =
+ (DevicePolicyManager) mContext.getSystemService(DEVICE_POLICY_SERVICE);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return dpm.isNotificationListenerServicePermitted(
+ component.getPackageName(), userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
}
/** convenience method for looking in mEnabledServicesForCurrentProfiles */
@@ -959,6 +984,13 @@
return mCurrentProfiles.get(userId) != null;
}
}
+
+ public boolean isManagedProfile(int userId) {
+ synchronized (mCurrentProfiles) {
+ UserInfo user = mCurrentProfiles.get(userId);
+ return user != null && user.isManagedProfile();
+ }
+ }
}
public static class Config {