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 {