diff --git a/Android.mk b/Android.mk
index f89e7b2..df8fbd9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -180,6 +180,7 @@
 	core/java/android/os/IUserManager.aidl \
 	core/java/android/os/IVibratorService.aidl \
 	core/java/android/service/notification/INotificationListener.aidl \
+	core/java/android/service/notification/IConditionProvider.aidl \
 	core/java/android/print/ILayoutResultCallback.aidl \
 	core/java/android/print/IPrinterDiscoveryObserver.aidl \
 	core/java/android/print/IPrintDocumentAdapter.aidl \
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 8681f5c..045fab1 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -22,6 +22,8 @@
 import android.app.Notification;
 import android.content.ComponentName;
 import android.content.Intent;
+import android.service.notification.Condition;
+import android.service.notification.IConditionProvider;
 import android.service.notification.INotificationListener;
 import android.service.notification.ZenModeConfig;
 
@@ -53,4 +55,5 @@
 
     ZenModeConfig getZenModeConfig();
     boolean setZenModeConfig(in ZenModeConfig config);
+    void notifyCondition(in IConditionProvider provider, in Condition condition);
 }
\ No newline at end of file
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 691317b..b578b48 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -723,6 +723,13 @@
             = "android.settings.NOTIFICATION_LISTENER_SETTINGS";
 
     /**
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_CONDITION_PROVIDER_SETTINGS
+            = "android.settings.ACTION_CONDITION_PROVIDER_SETTINGS";
+
+    /**
      * Activity Action: Show settings for video captioning.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you safeguard
@@ -4516,6 +4523,11 @@
          */
         public static final String ENABLED_NOTIFICATION_LISTENERS = "enabled_notification_listeners";
 
+        /**
+         * @hide
+         */
+        public static final String ENABLED_CONDITION_PROVIDERS = "enabled_condition_providers";
+
         /** @hide */
         public static final String BAR_SERVICE_COMPONENT = "bar_service_component";
 
diff --git a/core/java/android/service/notification/Condition.aidl b/core/java/android/service/notification/Condition.aidl
new file mode 100644
index 0000000..432852c
--- /dev/null
+++ b/core/java/android/service/notification/Condition.aidl
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2014, 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 android.service.notification;
+
+parcelable Condition;
+
diff --git a/core/java/android/service/notification/Condition.java b/core/java/android/service/notification/Condition.java
new file mode 100644
index 0000000..cfd40f3
--- /dev/null
+++ b/core/java/android/service/notification/Condition.java
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2014, 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 android.service.notification;
+
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Condition information from condition providers.
+ *
+ * @hide
+ */
+public class Condition implements Parcelable {
+
+    public static final int FLAG_RELEVANT_NOW = 1 << 0;
+    public static final int FLAG_RELEVANT_ALWAYS = 1 << 1;
+
+    public final Uri id;
+    public String caption;
+    public boolean state;
+    public int flags;
+
+
+    public Condition(Uri id, String caption, boolean state, int flags) {
+        if (id == null) throw new IllegalArgumentException("id is required");
+        if (caption == null) throw new IllegalArgumentException("caption is required");
+        this.id = id;
+        this.caption = caption;
+        this.state = state;
+        this.flags = flags;
+    }
+
+    private Condition(Parcel source) {
+        id = Uri.CREATOR.createFromParcel(source);
+        caption = source.readString();
+        state = source.readInt() == 1;
+        flags = source.readInt();
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(id, 0);
+        dest.writeString(caption);
+        dest.writeInt(state ? 1 : 0);
+        dest.writeInt(flags);
+    }
+
+    @Override
+    public String toString() {
+        return new StringBuilder(Condition.class.getSimpleName()).append('[')
+            .append("id=").append(id)
+            .append(",caption=").append(caption)
+            .append(",state=").append(state)
+            .append(",flags=").append(flags)
+            .append(']').toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Condition)) return false;
+        if (o == this) return true;
+        final Condition other = (Condition) o;
+        return Objects.equals(other.id, id)
+                && Objects.equals(other.caption, caption)
+                && other.state == state
+                && other.flags == flags;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, caption, state, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    public Condition copy() {
+        final Parcel parcel = Parcel.obtain();
+        try {
+            writeToParcel(parcel, 0);
+            parcel.setDataPosition(0);
+            return new Condition(parcel);
+        } finally {
+            parcel.recycle();
+        }
+    }
+
+    public static final Parcelable.Creator<Condition> CREATOR
+            = new Parcelable.Creator<Condition>() {
+        @Override
+        public Condition createFromParcel(Parcel source) {
+            return new Condition(source);
+        }
+
+        @Override
+        public Condition[] newArray(int size) {
+            return new Condition[size];
+        }
+    };
+}
diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java
new file mode 100644
index 0000000..8777e50
--- /dev/null
+++ b/core/java/android/service/notification/ConditionProviderService.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2014 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 android.service.notification;
+
+import android.annotation.SdkConstant;
+import android.app.INotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * A service that provides conditions about boolean state.
+ * <p>To extend this class, you must declare the service in your manifest file with
+ * the {@link android.Manifest.permission#BIND_CONDITION_PROVIDER_SERVICE} permission
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ * &lt;service android:name=".MyConditionProvider"
+ *          android:label="&#64;string/service_name"
+ *          android:permission="android.permission.BIND_CONDITION_PROVIDER_SERVICE">
+ *     &lt;intent-filter>
+ *         &lt;action android:name="android.service.notification.ConditionProviderService" />
+ *     &lt;/intent-filter>
+ * &lt;/service></pre>
+ *
+ * @hide
+ */
+public abstract class ConditionProviderService extends Service {
+    private final String TAG = ConditionProviderService.class.getSimpleName()
+            + "[" + getClass().getSimpleName() + "]";
+
+    private Provider mProvider;
+    private INotificationManager mNoMan;
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE
+            = "android.service.notification.ConditionProviderService";
+
+
+    abstract public Condition[] queryConditions(int relevance);
+    abstract public Condition[] getConditions(Uri[] conditionIds);
+    abstract public boolean subscribe(Uri conditionId);
+    abstract public boolean unsubscribe(Uri conditionId);
+
+    private final INotificationManager getNotificationInterface() {
+        if (mNoMan == null) {
+            mNoMan = INotificationManager.Stub.asInterface(
+                    ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+        }
+        return mNoMan;
+    }
+
+    public final void notifyCondition(Condition condition) {
+        if (!isBound()) return;
+        try {
+            getNotificationInterface().notifyCondition(mProvider, condition);
+        } catch (android.os.RemoteException ex) {
+            Log.v(TAG, "Unable to contact notification manager", ex);
+        }
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (mProvider == null) {
+            mProvider = new Provider();
+        }
+        return mProvider;
+    }
+
+    private boolean isBound() {
+        if (mProvider == null) {
+            Log.w(TAG, "Condition provider service not yet bound.");
+            return false;
+        }
+        return true;
+    }
+
+    private final class Provider extends IConditionProvider.Stub {
+        private final ConditionProviderService mService = ConditionProviderService.this;
+
+        @Override
+        public Condition[] queryConditions(int relevance) {
+            try {
+                return mService.queryConditions(relevance);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running queryConditions", t);
+                return null;
+            }
+        }
+
+        @Override
+        public Condition[] getConditions(Uri[] conditionIds) {
+            try {
+                return mService.getConditions(conditionIds);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running getConditions", t);
+                return null;
+            }
+        }
+
+        @Override
+        public boolean subscribe(Uri conditionId) {
+            try {
+                return mService.subscribe(conditionId);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running subscribe", t);
+                return false;
+            }
+        }
+
+        @Override
+        public boolean unsubscribe(Uri conditionId) {
+            try {
+                return mService.unsubscribe(conditionId);
+            } catch (Throwable t) {
+                Log.w(TAG, "Error running unsubscribe", t);
+                return false;
+            }
+        }
+    }
+}
diff --git a/core/java/android/service/notification/IConditionProvider.aidl b/core/java/android/service/notification/IConditionProvider.aidl
new file mode 100644
index 0000000..cb582da
--- /dev/null
+++ b/core/java/android/service/notification/IConditionProvider.aidl
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2014, 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 android.service.notification;
+
+import android.net.Uri;
+import android.service.notification.Condition;
+
+/** @hide */
+interface IConditionProvider {
+    Condition[] queryConditions(int relevance);
+    Condition[] getConditions(in Uri[] conditionIds);
+    boolean subscribe(in Uri conditionId);
+    boolean unsubscribe(in Uri conditionId);
+}
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8dfce64..4f093a8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2627,6 +2627,15 @@
         android:description="@string/permdesc_bindNotificationListenerService"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an {@link
+         android.service.notification.ConditionProviderService},
+         to ensure that only the system can bind to it.
+         @hide -->
+    <permission android:name="android.permission.BIND_CONDITION_PROVIDER_SERVICE"
+        android:label="@string/permlab_bindConditionProviderService"
+        android:description="@string/permdesc_bindConditionProviderService"
+        android:protectionLevel="signature" />
+
     <!-- Allows an application to call into a carrier setup flow. It is up to the
          carrier setup application to enforce that this permission is required
          @hide This is not a third-party API (intended for OEMs and system apps). -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9b89eaa..cb52db2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2054,6 +2054,11 @@
     <string name="permdesc_bindNotificationListenerService">Allows the holder to bind to the top-level interface of a notification listener service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permlab_bindConditionProviderService">bind to a condition provider service</string>
+    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
+
+    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_invokeCarrierSetup">invoke the carrier-provided configuration app</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_invokeCarrierSetup">Allows the holder to invoke the carrier-provided configuration app. Should never be needed for normal apps.</string>
@@ -3803,6 +3808,8 @@
     <!-- Label to show for a service that is running because it is observing
          the user's notifications. -->
     <string name="notification_listener_binding_label">Notification listener</string>
+    <!-- Label to show for a service that is running because it is providing conditions. -->
+    <string name="condition_provider_service_binding_label">Condition provider</string>
 
     <!-- Do Not Translate: Alternate eri.xml -->
     <string name="alternate_eri_file">/data/eri.xml</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index bb0d184..431dab8 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1580,6 +1580,7 @@
   <java-symbol type="string" name="low_internal_storage_view_text" />
   <java-symbol type="string" name="low_internal_storage_view_title" />
   <java-symbol type="string" name="notification_listener_binding_label" />
+  <java-symbol type="string" name="condition_provider_service_binding_label" />
   <java-symbol type="string" name="report" />
   <java-symbol type="string" name="select_input_method" />
   <java-symbol type="string" name="select_keyboard_layout_notification_title" />
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
new file mode 100644
index 0000000..a282270
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2014, 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.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.provider.Settings;
+import android.service.notification.IConditionProvider;
+import android.service.notification.ConditionProviderService;
+import android.util.Slog;
+
+import com.android.internal.R;
+
+public class ConditionProviders extends ManagedServices {
+
+    public ConditionProviders(Context context, Handler handler,
+            Object mutex, UserProfiles userProfiles) {
+        super(context, handler, mutex, userProfiles);
+    }
+
+    @Override
+    protected Config getConfig() {
+        Config c = new Config();
+        c.caption = "condition provider";
+        c.serviceInterface = ConditionProviderService.SERVICE_INTERFACE;
+        c.secureSettingName = Settings.Secure.ENABLED_CONDITION_PROVIDERS;
+        c.bindPermission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE;
+        c.settingsAction = Settings.ACTION_CONDITION_PROVIDER_SETTINGS;
+        c.clientLabel = R.string.condition_provider_service_binding_label;
+        return c;
+    }
+
+    @Override
+    protected IInterface asInterface(IBinder binder) {
+        return IConditionProvider.Stub.asInterface(binder);
+    }
+
+    @Override
+    protected void onServiceAdded(IInterface service) {
+        Slog.d(TAG, "onServiceAdded " + service);
+    }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
new file mode 100644
index 0000000..81b28e8
--- /dev/null
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -0,0 +1,594 @@
+/**
+ * Copyright (c) 2014, 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.app.ActivityManager;
+import android.app.PendingIntent;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Manages the lifecycle of application-provided services bound by system server.
+ *
+ * Services managed by this helper must have:
+ *  - An associated system settings value with a list of enabled component names.
+ *  - A well-known action for services to use in their intent-filter.
+ *  - A system permission for services to require in order to ensure system has exclusive binding.
+ *  - A settings page for user configuration of enabled services, and associated intent action.
+ *  - A remote interface definition (aidl) provided by the service used for communication.
+ */
+abstract public class ManagedServices {
+    protected final String TAG = getClass().getSimpleName();
+    protected static final boolean DEBUG = true;
+
+    private static final String ENABLED_SERVICES_SEPARATOR = ":";
+
+    private final Context mContext;
+    private final Object mMutex;
+    private final UserProfiles mUserProfiles;
+    private final SettingsObserver mSettingsObserver;
+    private final Config mConfig;
+
+    // contains connections to all connected services, including app services
+    // and system services
+    protected final ArrayList<ManagedServiceInfo> mServices = new ArrayList<ManagedServiceInfo>();
+    // things that will be put into mServices as soon as they're ready
+    private final ArrayList<String> mServicesBinding = new ArrayList<String>();
+    // lists the component names of all enabled (and therefore connected)
+    // app services for current profiles.
+    private ArraySet<ComponentName> mEnabledServicesForCurrentProfiles
+            = new ArraySet<ComponentName>();
+    // Just the packages from mEnabledServicesForCurrentProfiles
+    private ArraySet<String> mEnabledServicesPackageNames = new ArraySet<String>();
+
+    public ManagedServices(Context context, Handler handler, Object mutex,
+            UserProfiles userProfiles) {
+        mContext = context;
+        mMutex = mutex;
+        mUserProfiles = userProfiles;
+        mConfig = getConfig();
+        mSettingsObserver = new SettingsObserver(handler);
+    }
+
+    abstract protected Config getConfig();
+
+    private String getCaption() {
+        return mConfig.caption;
+    }
+
+    abstract protected IInterface asInterface(IBinder binder);
+
+    abstract protected void onServiceAdded(IInterface service);
+
+    private ManagedServiceInfo newServiceInfo(IInterface service,
+            ComponentName component, int userid, boolean isSystem, ServiceConnection connection,
+            int targetSdkVersion) {
+        return new ManagedServiceInfo(service, component, userid, isSystem, connection,
+                targetSdkVersion);
+    }
+
+    public void onBootPhaseAppsCanStart() {
+        mSettingsObserver.observe();
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("  All " + getCaption() + "s (" + mEnabledServicesForCurrentProfiles.size()
+                + ") enabled for current profiles:");
+        for (ComponentName cmpt : mEnabledServicesForCurrentProfiles) {
+            pw.println("    " + cmpt);
+        }
+
+        pw.println("  Live " + getCaption() + "s (" + mServices.size() + "):");
+        for (ManagedServiceInfo info : mServices) {
+            pw.println("    " + info.component
+                    + " (user " + info.userid + "): " + info.service
+                    + (info.isSystem?" SYSTEM":""));
+        }
+    }
+
+    public void onPackagesChanged(boolean queryReplace, String[] pkgList) {
+        boolean anyServicesInvolved = false;
+        if (pkgList != null && (pkgList.length > 0)) {
+            for (String pkgName : pkgList) {
+                if (mEnabledServicesPackageNames.contains(pkgName)) {
+                    anyServicesInvolved = true;
+                }
+            }
+        }
+
+        if (anyServicesInvolved) {
+            // if we're not replacing a package, clean up orphaned bits
+            if (!queryReplace) {
+                disableNonexistentServices();
+            }
+            // make sure we're still bound to any of our services who may have just upgraded
+            rebindServices();
+        }
+    }
+
+    public ManagedServiceInfo checkServiceTokenLocked(IInterface service) {
+        checkNotNull(service);
+        final IBinder token = service.asBinder();
+        final int N = mServices.size();
+        for (int i=0; i<N; i++) {
+            final ManagedServiceInfo info = mServices.get(i);
+            if (info.service.asBinder() == token) return info;
+        }
+        throw new SecurityException("Disallowed call from unknown " + getCaption() + ": "
+                + service);
+    }
+
+    public void unregisterService(IInterface service, int userid) {
+        checkNotNull(service);
+        // no need to check permissions; if your service binder is in the list,
+        // that's proof that you had permission to add it in the first place
+        unregisterServiceImpl(service, userid);
+    }
+
+    public void registerService(IInterface service, ComponentName component, int userid) {
+        checkNotNull(service);
+        registerServiceImpl(service, component, userid);
+    }
+
+    /**
+     * Remove access for any services that no longer exist.
+     */
+    private void disableNonexistentServices() {
+        int[] userIds = mUserProfiles.getCurrentProfileIds();
+        final int N = userIds.length;
+        for (int i = 0 ; i < N; ++i) {
+            disableNonexistentServices(userIds[i]);
+        }
+    }
+
+    private void disableNonexistentServices(int userId) {
+        String flatIn = Settings.Secure.getStringForUser(
+                mContext.getContentResolver(),
+                mConfig.secureSettingName,
+                userId);
+        if (!TextUtils.isEmpty(flatIn)) {
+            if (DEBUG) Slog.v(TAG, "flat before: " + flatIn);
+            PackageManager pm = mContext.getPackageManager();
+            List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
+                    new Intent(mConfig.serviceInterface),
+                    PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
+                    userId);
+
+            Set<ComponentName> installed = new ArraySet<ComponentName>();
+            for (int i = 0, count = installedServices.size(); i < count; i++) {
+                ResolveInfo resolveInfo = installedServices.get(i);
+                ServiceInfo info = resolveInfo.serviceInfo;
+
+                if (!mConfig.bindPermission.equals(info.permission)) {
+                    Slog.w(TAG, "Skipping " + getCaption() + " service "
+                            + info.packageName + "/" + info.name
+                            + ": it does not require the permission "
+                            + mConfig.bindPermission);
+                    continue;
+                }
+                installed.add(new ComponentName(info.packageName, info.name));
+            }
+
+            String flatOut = "";
+            if (!installed.isEmpty()) {
+                String[] enabled = flatIn.split(ENABLED_SERVICES_SEPARATOR);
+                ArrayList<String> remaining = new ArrayList<String>(enabled.length);
+                for (int i = 0; i < enabled.length; i++) {
+                    ComponentName enabledComponent = ComponentName.unflattenFromString(enabled[i]);
+                    if (installed.contains(enabledComponent)) {
+                        remaining.add(enabled[i]);
+                    }
+                }
+                flatOut = TextUtils.join(ENABLED_SERVICES_SEPARATOR, remaining);
+            }
+            if (DEBUG) Slog.v(TAG, "flat after: " + flatOut);
+            if (!flatIn.equals(flatOut)) {
+                Settings.Secure.putStringForUser(mContext.getContentResolver(),
+                        mConfig.secureSettingName,
+                        flatOut, userId);
+            }
+        }
+    }
+
+    /**
+     * Called whenever packages change, the user switches, or the secure setting
+     * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
+     */
+    private void rebindServices() {
+        if (DEBUG) Slog.d(TAG, "rebindServices");
+        final int[] userIds = mUserProfiles.getCurrentProfileIds();
+        final int nUserIds = userIds.length;
+
+        final SparseArray<String> flat = new SparseArray<String>();
+
+        for (int i = 0; i < nUserIds; ++i) {
+            flat.put(userIds[i], Settings.Secure.getStringForUser(
+                    mContext.getContentResolver(),
+                    mConfig.secureSettingName,
+                    userIds[i]));
+        }
+
+        ManagedServiceInfo[] toRemove = new ManagedServiceInfo[mServices.size()];
+        final SparseArray<ArrayList<ComponentName>> toAdd
+                = new SparseArray<ArrayList<ComponentName>>();
+
+        synchronized (mMutex) {
+            // unbind and remove all existing services
+            toRemove = mServices.toArray(toRemove);
+
+            final ArraySet<ComponentName> newEnabled = new ArraySet<ComponentName>();
+            final ArraySet<String> newPackages = new ArraySet<String>();
+
+            for (int i = 0; i < nUserIds; ++i) {
+                final ArrayList<ComponentName> add = new ArrayList<ComponentName>();
+                toAdd.put(userIds[i], add);
+
+                // decode the list of components
+                String toDecode = flat.get(userIds[i]);
+                if (toDecode != null) {
+                    String[] components = toDecode.split(ENABLED_SERVICES_SEPARATOR);
+                    for (int j = 0; j < components.length; j++) {
+                        final ComponentName component
+                                = ComponentName.unflattenFromString(components[j]);
+                        if (component != null) {
+                            newEnabled.add(component);
+                            add.add(component);
+                            newPackages.add(component.getPackageName());
+                        }
+                    }
+
+                }
+            }
+            mEnabledServicesForCurrentProfiles = newEnabled;
+            mEnabledServicesPackageNames = newPackages;
+        }
+
+        for (ManagedServiceInfo info : toRemove) {
+            final ComponentName component = info.component;
+            final int oldUser = info.userid;
+            Slog.v(TAG, "disabling " + getCaption() + " for user "
+                    + oldUser + ": " + component);
+            unregisterService(component, info.userid);
+        }
+
+        for (int i = 0; i < nUserIds; ++i) {
+            final ArrayList<ComponentName> add = toAdd.get(userIds[i]);
+            final int N = add.size();
+            for (int j = 0; j < N; j++) {
+                final ComponentName component = add.get(j);
+                Slog.v(TAG, "enabling " + getCaption() + " for user " + userIds[i] + ": "
+                        + component);
+                registerService(component, userIds[i]);
+            }
+        }
+    }
+
+    /**
+     * Version of registerService that takes the name of a service component to bind to.
+     */
+    private void registerService(final ComponentName name, final int userid) {
+        if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);
+
+        synchronized (mMutex) {
+            final String servicesBindingTag = name.toString() + "/" + userid;
+            if (mServicesBinding.contains(servicesBindingTag)) {
+                // stop registering this thing already! we're working on it
+                return;
+            }
+            mServicesBinding.add(servicesBindingTag);
+
+            final int N = mServices.size();
+            for (int i=N-1; i>=0; i--) {
+                final ManagedServiceInfo info = mServices.get(i);
+                if (name.equals(info.component)
+                        && info.userid == userid) {
+                    // cut old connections
+                    if (DEBUG) Slog.v(TAG, "    disconnecting old " + getCaption() + ": "
+                            + info.service);
+                    mServices.remove(i);
+                    if (info.connection != null) {
+                        mContext.unbindService(info.connection);
+                    }
+                }
+            }
+
+            Intent intent = new Intent(mConfig.serviceInterface);
+            intent.setComponent(name);
+
+            intent.putExtra(Intent.EXTRA_CLIENT_LABEL, mConfig.clientLabel);
+
+            final PendingIntent pendingIntent = PendingIntent.getActivity(
+                    mContext, 0, new Intent(mConfig.settingsAction), 0);
+            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
+
+            ApplicationInfo appInfo = null;
+            try {
+                appInfo = mContext.getPackageManager().getApplicationInfo(
+                        name.getPackageName(), 0);
+            } catch (NameNotFoundException e) {
+                // Ignore if the package doesn't exist we won't be able to bind to the service.
+            }
+            final int targetSdkVersion =
+                    appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
+
+            try {
+                if (DEBUG) Slog.v(TAG, "binding: " + intent);
+                if (!mContext.bindServiceAsUser(intent,
+                        new ServiceConnection() {
+                            IInterface mService;
+
+                            @Override
+                            public void onServiceConnected(ComponentName name, IBinder binder) {
+                                boolean added = false;
+                                synchronized (mMutex) {
+                                    mServicesBinding.remove(servicesBindingTag);
+                                    try {
+                                        mService = asInterface(binder);
+                                        ManagedServiceInfo info = newServiceInfo(mService, name,
+                                                userid, false /*isSystem*/, this, targetSdkVersion);
+                                        binder.linkToDeath(info, 0);
+                                        added = mServices.add(info);
+                                    } catch (RemoteException e) {
+                                        // already dead
+                                    }
+                                }
+                                if (added) {
+                                    onServiceAdded(mService);
+                                }
+                            }
+
+                            @Override
+                            public void onServiceDisconnected(ComponentName name) {
+                                Slog.v(TAG, getCaption() + " connection lost: " + name);
+                            }
+                        },
+                        Context.BIND_AUTO_CREATE,
+                        new UserHandle(userid)))
+                {
+                    mServicesBinding.remove(servicesBindingTag);
+                    Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);
+                    return;
+                }
+            } catch (SecurityException ex) {
+                Slog.e(TAG, "Unable to bind " + getCaption() + " service: " + intent, ex);
+                return;
+            }
+        }
+    }
+
+    /**
+     * Remove a service for the given user by ComponentName
+     */
+    private void unregisterService(ComponentName name, int userid) {
+        synchronized (mMutex) {
+            final int N = mServices.size();
+            for (int i=N-1; i>=0; i--) {
+                final ManagedServiceInfo info = mServices.get(i);
+                if (name.equals(info.component)
+                        && info.userid == userid) {
+                    mServices.remove(i);
+                    if (info.connection != null) {
+                        try {
+                            mContext.unbindService(info.connection);
+                        } catch (IllegalArgumentException ex) {
+                            // something happened to the service: we think we have a connection
+                            // but it's bogus.
+                            Slog.e(TAG, getCaption() + " " + name + " could not be unbound: " + ex);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a service from the list but does not unbind
+     *
+     * @return the removed service.
+     */
+    private ManagedServiceInfo removeServiceImpl(IInterface service, final int userid) {
+        ManagedServiceInfo serviceInfo = null;
+        synchronized (mMutex) {
+            final int N = mServices.size();
+            for (int i=N-1; i>=0; i--) {
+                final ManagedServiceInfo info = mServices.get(i);
+                if (info.service.asBinder() == service.asBinder()
+                        && info.userid == userid) {
+                    serviceInfo = mServices.remove(i);
+                }
+            }
+        }
+        return serviceInfo;
+    }
+
+    private void checkNotNull(IInterface service) {
+        if (service == null) {
+            throw new IllegalArgumentException(getCaption() + " must not be null");
+        }
+    }
+
+    private void registerServiceImpl(final IInterface service,
+            final ComponentName component, final int userid) {
+        synchronized (mMutex) {
+            try {
+                ManagedServiceInfo info = newServiceInfo(service, component, userid,
+                        true /*isSystem*/, null, Build.VERSION_CODES.L);
+                service.asBinder().linkToDeath(info, 0);
+                mServices.add(info);
+            } catch (RemoteException e) {
+                // already dead
+            }
+        }
+    }
+
+    /**
+     * Removes a service from the list and unbinds.
+     */
+    private void unregisterServiceImpl(IInterface service, int userid) {
+        ManagedServiceInfo info = removeServiceImpl(service, userid);
+        if (info != null && info.connection != null) {
+            mContext.unbindService(info.connection);
+        }
+    }
+
+    private class SettingsObserver extends ContentObserver {
+        private final Uri mSecureSettingsUri = Settings.Secure.getUriFor(mConfig.secureSettingName);
+
+        private SettingsObserver(Handler handler) {
+            super(handler);
+        }
+
+        private void observe() {
+            ContentResolver resolver = mContext.getContentResolver();
+            resolver.registerContentObserver(mSecureSettingsUri,
+                    false, this, UserHandle.USER_ALL);
+            update(null);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            update(uri);
+        }
+
+        private void update(Uri uri) {
+            if (uri == null || mSecureSettingsUri.equals(uri)) {
+                rebindServices();
+            }
+        }
+    }
+
+    public class ManagedServiceInfo implements IBinder.DeathRecipient {
+        public IInterface service;
+        public ComponentName component;
+        public int userid;
+        public boolean isSystem;
+        public ServiceConnection connection;
+        public int targetSdkVersion;
+
+        public ManagedServiceInfo(IInterface service, ComponentName component,
+                int userid, boolean isSystem, ServiceConnection connection, int targetSdkVersion) {
+            this.service = service;
+            this.component = component;
+            this.userid = userid;
+            this.isSystem = isSystem;
+            this.connection = connection;
+            this.targetSdkVersion = targetSdkVersion;
+        }
+
+        public boolean enabledAndUserMatches(int nid) {
+            if (!isEnabledForCurrentProfiles()) {
+                return false;
+            }
+            if (this.userid == UserHandle.USER_ALL) return true;
+            if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
+            return supportsProfiles() && mUserProfiles.isCurrentProfile(nid);
+        }
+
+        public boolean supportsProfiles() {
+            return targetSdkVersion >= Build.VERSION_CODES.L;
+        }
+
+        @Override
+        public void 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
+            // 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);
+        }
+
+        /** convenience method for looking in mEnabledServicesForCurrentProfiles */
+        public boolean isEnabledForCurrentProfiles() {
+            if (this.isSystem) return true;
+            if (this.connection == null) return false;
+            return mEnabledServicesForCurrentProfiles.contains(this.component);
+        }
+    }
+
+    public static class UserProfiles {
+        // Profiles of the current user.
+        private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
+
+        public void updateCache(Context context) {
+            UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
+            if (userManager != null) {
+                int currentUserId = ActivityManager.getCurrentUser();
+                List<UserInfo> profiles = userManager.getProfiles(currentUserId);
+                synchronized (mCurrentProfiles) {
+                    mCurrentProfiles.clear();
+                    for (UserInfo user : profiles) {
+                        mCurrentProfiles.put(user.id, user);
+                    }
+                }
+            }
+        }
+
+        public int[] getCurrentProfileIds() {
+            synchronized (mCurrentProfiles) {
+                int[] users = new int[mCurrentProfiles.size()];
+                final int N = mCurrentProfiles.size();
+                for (int i = 0; i < N; ++i) {
+                    users[i] = mCurrentProfiles.keyAt(i);
+                }
+                return users;
+            }
+        }
+
+        public boolean isCurrentProfile(int userId) {
+            synchronized (mCurrentProfiles) {
+                return mCurrentProfiles.get(userId) != null;
+            }
+        }
+    }
+
+    protected static class Config {
+        String caption;
+        String serviceInterface;
+        String secureSettingName;
+        String bindPermission;
+        String settingsAction;
+        int clientLabel;
+    }
+}
diff --git a/services/core/java/com/android/server/notification/NotificationListeners.java b/services/core/java/com/android/server/notification/NotificationListeners.java
deleted file mode 100644
index 91d2f98..0000000
--- a/services/core/java/com/android/server/notification/NotificationListeners.java
+++ /dev/null
@@ -1,608 +0,0 @@
-/**
- * Copyright (c) 2014, 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.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.os.Build;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.service.notification.INotificationListener;
-import android.service.notification.NotificationListenerService;
-import android.service.notification.StatusBarNotification;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.Log;
-import android.util.Slog;
-import android.util.SparseArray;
-
-import com.android.internal.R;
-import com.android.server.notification.NotificationManagerService.UserProfiles;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-public class NotificationListeners {
-    private static final String TAG = "NotificationListeners";
-    private static final boolean DBG = NotificationManagerService.DBG;
-
-    private static final String ENABLED_NOTIFICATION_LISTENERS_SEPARATOR = ":";
-
-    private final Context mContext;
-    private final Handler mHandler;
-    private final Object mMutex;
-    private final UserProfiles mUserProfiles;
-    private final SettingsObserver mSettingsObserver;
-
-    // contains connections to all connected listeners, including app services
-    // and system listeners
-    private final ArrayList<NotificationListenerInfo> mListeners
-            = new ArrayList<NotificationListenerInfo>();
-    // things that will be put into mListeners as soon as they're ready
-    private final ArrayList<String> mServicesBinding = new ArrayList<String>();
-    // lists the component names of all enabled (and therefore connected) listener
-    // app services for current profiles.
-    private ArraySet<ComponentName> mEnabledListenersForCurrentProfiles
-            = new ArraySet<ComponentName>();
-    // Just the packages from mEnabledListenersForCurrentProfiles
-    private ArraySet<String> mEnabledListenerPackageNames = new ArraySet<String>();
-
-    public NotificationListeners(Context context, Handler handler, Object mutex,
-            UserProfiles userProfiles) {
-        mContext = context;
-        mHandler = handler;
-        mMutex = mutex;
-        mUserProfiles = userProfiles;
-        mSettingsObserver = new SettingsObserver(mHandler);
-    }
-
-    public void onBootPhaseAppsCanStart() {
-        mSettingsObserver.observe();
-    }
-
-    protected void onServiceAdded(INotificationListener mListener) {
-        // for subclasses
-    }
-
-    public void dump(PrintWriter pw) {
-        pw.println("  Listeners (" + mEnabledListenersForCurrentProfiles.size()
-                + ") enabled for current profiles:");
-        for (ComponentName cmpt : mEnabledListenersForCurrentProfiles) {
-            pw.println("    " + cmpt);
-        }
-
-        pw.println("  Live listeners (" + mListeners.size() + "):");
-        for (NotificationListenerInfo info : mListeners) {
-            pw.println("    " + info.component
-                    + " (user " + info.userid + "): " + info.listener
-                    + (info.isSystem?" SYSTEM":""));
-        }
-    }
-
-    public void onPackagesChanged(boolean queryReplace, String[] pkgList) {
-        boolean anyListenersInvolved = false;
-        if (pkgList != null && (pkgList.length > 0)) {
-            for (String pkgName : pkgList) {
-                if (mEnabledListenerPackageNames.contains(pkgName)) {
-                    anyListenersInvolved = true;
-                }
-            }
-        }
-
-        if (anyListenersInvolved) {
-            // if we're not replacing a package, clean up orphaned bits
-            if (!queryReplace) {
-                disableNonexistentListeners();
-            }
-            // make sure we're still bound to any of our
-            // listeners who may have just upgraded
-            rebindListenerServices();
-        }
-    }
-
-    /**
-     * asynchronously notify all listeners about a new notification
-     */
-    public void notifyPostedLocked(StatusBarNotification sbn) {
-        // make a copy in case changes are made to the underlying Notification object
-        final StatusBarNotification sbnClone = sbn.clone();
-        for (final NotificationListenerInfo info : mListeners) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    info.notifyPostedIfUserMatch(sbnClone);
-                }
-            });
-        }
-    }
-
-    /**
-     * asynchronously notify all listeners about a removed notification
-     */
-    public void notifyRemovedLocked(StatusBarNotification sbn) {
-        // make a copy in case changes are made to the underlying Notification object
-        // NOTE: this copy is lightweight: it doesn't include heavyweight parts of the notification
-        final StatusBarNotification sbnLight = sbn.cloneLight();
-
-        for (final NotificationListenerInfo info : mListeners) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    info.notifyRemovedIfUserMatch(sbnLight);
-                }
-            });
-        }
-    }
-
-    public NotificationListenerInfo checkListenerTokenLocked(INotificationListener listener) {
-        checkNullListener(listener);
-        final IBinder token = listener.asBinder();
-        final int N = mListeners.size();
-        for (int i=0; i<N; i++) {
-            final NotificationListenerInfo info = mListeners.get(i);
-            if (info.listener.asBinder() == token) return info;
-        }
-        throw new SecurityException("Disallowed call from unknown listener: " + listener);
-    }
-
-    public void unregisterListener(INotificationListener listener, int userid) {
-        checkNullListener(listener);
-        // no need to check permissions; if your listener binder is in the list,
-        // that's proof that you had permission to add it in the first place
-        unregisterListenerImpl(listener, userid);
-    }
-
-    public void registerListener(INotificationListener listener,
-            ComponentName component, int userid) {
-        checkNullListener(listener);
-        registerListenerImpl(listener, component, userid);
-    }
-
-    /**
-     * Remove notification access for any services that no longer exist.
-     */
-    private void disableNonexistentListeners() {
-        int[] userIds = mUserProfiles.getCurrentProfileIds();
-        final int N = userIds.length;
-        for (int i = 0 ; i < N; ++i) {
-            disableNonexistentListeners(userIds[i]);
-        }
-    }
-
-    private void disableNonexistentListeners(int userId) {
-        String flatIn = Settings.Secure.getStringForUser(
-                mContext.getContentResolver(),
-                Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
-                userId);
-        if (!TextUtils.isEmpty(flatIn)) {
-            if (DBG) Slog.v(TAG, "flat before: " + flatIn);
-            PackageManager pm = mContext.getPackageManager();
-            List<ResolveInfo> installedServices = pm.queryIntentServicesAsUser(
-                    new Intent(NotificationListenerService.SERVICE_INTERFACE),
-                    PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
-                    userId);
-
-            Set<ComponentName> installed = new ArraySet<ComponentName>();
-            for (int i = 0, count = installedServices.size(); i < count; i++) {
-                ResolveInfo resolveInfo = installedServices.get(i);
-                ServiceInfo info = resolveInfo.serviceInfo;
-
-                if (!android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE.equals(
-                                info.permission)) {
-                    Slog.w(TAG, "Skipping notification listener service "
-                            + info.packageName + "/" + info.name
-                            + ": it does not require the permission "
-                            + android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE);
-                    continue;
-                }
-                installed.add(new ComponentName(info.packageName, info.name));
-            }
-
-            String flatOut = "";
-            if (!installed.isEmpty()) {
-                String[] enabled = flatIn.split(ENABLED_NOTIFICATION_LISTENERS_SEPARATOR);
-                ArrayList<String> remaining = new ArrayList<String>(enabled.length);
-                for (int i = 0; i < enabled.length; i++) {
-                    ComponentName enabledComponent = ComponentName.unflattenFromString(enabled[i]);
-                    if (installed.contains(enabledComponent)) {
-                        remaining.add(enabled[i]);
-                    }
-                }
-                flatOut = TextUtils.join(ENABLED_NOTIFICATION_LISTENERS_SEPARATOR, remaining);
-            }
-            if (DBG) Slog.v(TAG, "flat after: " + flatOut);
-            if (!flatIn.equals(flatOut)) {
-                Settings.Secure.putStringForUser(mContext.getContentResolver(),
-                        Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
-                        flatOut, userId);
-            }
-        }
-    }
-
-    /**
-     * Called whenever packages change, the user switches, or ENABLED_NOTIFICATION_LISTENERS
-     * is altered. (For example in response to USER_SWITCHED in our broadcast receiver)
-     */
-    private void rebindListenerServices() {
-        final int[] userIds = mUserProfiles.getCurrentProfileIds();
-        final int nUserIds = userIds.length;
-
-        final SparseArray<String> flat = new SparseArray<String>();
-
-        for (int i = 0; i < nUserIds; ++i) {
-            flat.put(userIds[i], Settings.Secure.getStringForUser(
-                    mContext.getContentResolver(),
-                    Settings.Secure.ENABLED_NOTIFICATION_LISTENERS,
-                    userIds[i]));
-        }
-
-        NotificationListenerInfo[] toRemove = new NotificationListenerInfo[mListeners.size()];
-        final SparseArray<ArrayList<ComponentName>> toAdd
-                = new SparseArray<ArrayList<ComponentName>>();
-
-        synchronized (mMutex) {
-            // unbind and remove all existing listeners
-            toRemove = mListeners.toArray(toRemove);
-
-            final ArraySet<ComponentName> newEnabled = new ArraySet<ComponentName>();
-            final ArraySet<String> newPackages = new ArraySet<String>();
-
-            for (int i = 0; i < nUserIds; ++i) {
-                final ArrayList<ComponentName> add = new ArrayList<ComponentName>();
-                toAdd.put(userIds[i], add);
-
-                // decode the list of components
-                String toDecode = flat.get(userIds[i]);
-                if (toDecode != null) {
-                    String[] components = toDecode.split(ENABLED_NOTIFICATION_LISTENERS_SEPARATOR);
-                    for (int j = 0; j < components.length; j++) {
-                        final ComponentName component
-                                = ComponentName.unflattenFromString(components[j]);
-                        if (component != null) {
-                            newEnabled.add(component);
-                            add.add(component);
-                            newPackages.add(component.getPackageName());
-                        }
-                    }
-
-                }
-            }
-            mEnabledListenersForCurrentProfiles = newEnabled;
-            mEnabledListenerPackageNames = newPackages;
-        }
-
-        for (NotificationListenerInfo info : toRemove) {
-            final ComponentName component = info.component;
-            final int oldUser = info.userid;
-            Slog.v(TAG, "disabling notification listener for user "
-                    + oldUser + ": " + component);
-            unregisterListenerService(component, info.userid);
-        }
-
-        for (int i = 0; i < nUserIds; ++i) {
-            final ArrayList<ComponentName> add = toAdd.get(userIds[i]);
-            final int N = add.size();
-            for (int j = 0; j < N; j++) {
-                final ComponentName component = add.get(j);
-                Slog.v(TAG, "enabling notification listener for user " + userIds[i] + ": "
-                        + component);
-                registerListenerService(component, userIds[i]);
-            }
-        }
-    }
-
-    /**
-     * Version of registerListener that takes the name of a
-     * {@link android.service.notification.NotificationListenerService} to bind to.
-     *
-     * This is the mechanism by which third parties may subscribe to notifications.
-     */
-    private void registerListenerService(final ComponentName name, final int userid) {
-        NotificationUtil.checkCallerIsSystem();
-
-        if (DBG) Slog.v(TAG, "registerListenerService: " + name + " u=" + userid);
-
-        synchronized (mMutex) {
-            final String servicesBindingTag = name.toString() + "/" + userid;
-            if (mServicesBinding.contains(servicesBindingTag)) {
-                // stop registering this thing already! we're working on it
-                return;
-            }
-            mServicesBinding.add(servicesBindingTag);
-
-            final int N = mListeners.size();
-            for (int i=N-1; i>=0; i--) {
-                final NotificationListenerInfo info = mListeners.get(i);
-                if (name.equals(info.component)
-                        && info.userid == userid) {
-                    // cut old connections
-                    if (DBG) Slog.v(TAG, "    disconnecting old listener: " + info.listener);
-                    mListeners.remove(i);
-                    if (info.connection != null) {
-                        mContext.unbindService(info.connection);
-                    }
-                }
-            }
-
-            Intent intent = new Intent(NotificationListenerService.SERVICE_INTERFACE);
-            intent.setComponent(name);
-
-            intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
-                    R.string.notification_listener_binding_label);
-
-            final PendingIntent pendingIntent = PendingIntent.getActivity(
-                    mContext, 0, new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS), 0);
-            intent.putExtra(Intent.EXTRA_CLIENT_INTENT, pendingIntent);
-
-            ApplicationInfo appInfo = null;
-            try {
-                appInfo = mContext.getPackageManager().getApplicationInfo(
-                        name.getPackageName(), 0);
-            } catch (NameNotFoundException e) {
-                // Ignore if the package doesn't exist we won't be able to bind to the service.
-            }
-            final int targetSdkVersion =
-                    appInfo != null ? appInfo.targetSdkVersion : Build.VERSION_CODES.BASE;
-
-            try {
-                if (DBG) Slog.v(TAG, "binding: " + intent);
-                if (!mContext.bindServiceAsUser(intent,
-                        new ServiceConnection() {
-                            INotificationListener mListener;
-
-                            @Override
-                            public void onServiceConnected(ComponentName name, IBinder service) {
-                                boolean added = false;
-                                synchronized (mMutex) {
-                                    mServicesBinding.remove(servicesBindingTag);
-                                    try {
-                                        mListener = INotificationListener.Stub.asInterface(service);
-                                        NotificationListenerInfo info
-                                                = new NotificationListenerInfo(
-                                                        mListener, name, userid, this,
-                                                        targetSdkVersion);
-                                        service.linkToDeath(info, 0);
-                                        added = mListeners.add(info);
-                                    } catch (RemoteException e) {
-                                        // already dead
-                                    }
-                                }
-                                if (added) {
-                                    onServiceAdded(mListener);
-                                }
-                            }
-
-                            @Override
-                            public void onServiceDisconnected(ComponentName name) {
-                                Slog.v(TAG, "notification listener connection lost: " + name);
-                            }
-                        },
-                        Context.BIND_AUTO_CREATE,
-                        new UserHandle(userid)))
-                {
-                    mServicesBinding.remove(servicesBindingTag);
-                    Slog.w(TAG, "Unable to bind listener service: " + intent);
-                    return;
-                }
-            } catch (SecurityException ex) {
-                Slog.e(TAG, "Unable to bind listener service: " + intent, ex);
-                return;
-            }
-        }
-    }
-
-    /**
-     * Remove a listener service for the given user by ComponentName
-     */
-    private void unregisterListenerService(ComponentName name, int userid) {
-        NotificationUtil.checkCallerIsSystem();
-
-        synchronized (mMutex) {
-            final int N = mListeners.size();
-            for (int i=N-1; i>=0; i--) {
-                final NotificationListenerInfo info = mListeners.get(i);
-                if (name.equals(info.component)
-                        && info.userid == userid) {
-                    mListeners.remove(i);
-                    if (info.connection != null) {
-                        try {
-                            mContext.unbindService(info.connection);
-                        } catch (IllegalArgumentException ex) {
-                            // something happened to the service: we think we have a connection
-                            // but it's bogus.
-                            Slog.e(TAG, "Listener " + name + " could not be unbound: " + ex);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Removes a listener from the list but does not unbind from the listener's service.
-     *
-     * @return the removed listener.
-     */
-    private NotificationListenerInfo removeListenerImpl(
-            final INotificationListener listener, final int userid) {
-        NotificationListenerInfo listenerInfo = null;
-        synchronized (mMutex) {
-            final int N = mListeners.size();
-            for (int i=N-1; i>=0; i--) {
-                final NotificationListenerInfo info = mListeners.get(i);
-                if (info.listener.asBinder() == listener.asBinder()
-                        && info.userid == userid) {
-                    listenerInfo = mListeners.remove(i);
-                }
-            }
-        }
-        return listenerInfo;
-    }
-
-    private void checkNullListener(INotificationListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("Listener must not be null");
-        }
-    }
-
-    private void registerListenerImpl(final INotificationListener listener,
-            final ComponentName component, final int userid) {
-        synchronized (mMutex) {
-            try {
-                NotificationListenerInfo info
-                        = new NotificationListenerInfo(listener, component, userid,
-                        /*isSystem*/ true, Build.VERSION_CODES.L);
-                listener.asBinder().linkToDeath(info, 0);
-                mListeners.add(info);
-            } catch (RemoteException e) {
-                // already dead
-            }
-        }
-    }
-
-    /**
-     * Removes a listener from the list and unbinds from its service.
-     */
-    private void unregisterListenerImpl(final INotificationListener listener, final int userid) {
-        NotificationListenerInfo info = removeListenerImpl(listener, userid);
-        if (info != null && info.connection != null) {
-            mContext.unbindService(info.connection);
-        }
-    }
-
-    private class SettingsObserver extends ContentObserver {
-        private final Uri ENABLED_NOTIFICATION_LISTENERS_URI
-                = Settings.Secure.getUriFor(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
-
-        private SettingsObserver(Handler handler) {
-            super(handler);
-        }
-
-        private void observe() {
-            ContentResolver resolver = mContext.getContentResolver();
-            resolver.registerContentObserver(ENABLED_NOTIFICATION_LISTENERS_URI,
-                    false, this, UserHandle.USER_ALL);
-            update(null);
-        }
-
-        @Override
-        public void onChange(boolean selfChange, Uri uri) {
-            update(uri);
-        }
-
-        private void update(Uri uri) {
-            if (uri == null || ENABLED_NOTIFICATION_LISTENERS_URI.equals(uri)) {
-                rebindListenerServices();
-            }
-        }
-    }
-
-    public class NotificationListenerInfo implements IBinder.DeathRecipient {
-        public INotificationListener listener;
-        public ComponentName component;
-        public int userid;
-        public boolean isSystem;
-        public ServiceConnection connection;
-        public int targetSdkVersion;
-
-        public NotificationListenerInfo(INotificationListener listener, ComponentName component,
-                int userid, boolean isSystem, int targetSdkVersion) {
-            this.listener = listener;
-            this.component = component;
-            this.userid = userid;
-            this.isSystem = isSystem;
-            this.connection = null;
-            this.targetSdkVersion = targetSdkVersion;
-        }
-
-        public NotificationListenerInfo(INotificationListener listener, ComponentName component,
-                int userid, ServiceConnection connection, int targetSdkVersion) {
-            this.listener = listener;
-            this.component = component;
-            this.userid = userid;
-            this.isSystem = false;
-            this.connection = connection;
-            this.targetSdkVersion = targetSdkVersion;
-        }
-
-        public boolean enabledAndUserMatches(StatusBarNotification sbn) {
-            final int nid = sbn.getUserId();
-            if (!isEnabledForCurrentProfiles()) {
-                return false;
-            }
-            if (this.userid == UserHandle.USER_ALL) return true;
-            if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
-            return supportsProfiles() && mUserProfiles.isCurrentProfile(nid);
-        }
-
-        public boolean supportsProfiles() {
-            return targetSdkVersion >= Build.VERSION_CODES.L;
-        }
-
-        public void notifyPostedIfUserMatch(StatusBarNotification sbn) {
-            if (!enabledAndUserMatches(sbn)) {
-                return;
-            }
-            try {
-                listener.onNotificationPosted(sbn);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
-            }
-        }
-
-        public void notifyRemovedIfUserMatch(StatusBarNotification sbn) {
-            if (!enabledAndUserMatches(sbn)) return;
-            try {
-                listener.onNotificationRemoved(sbn);
-            } catch (RemoteException ex) {
-                Log.e(TAG, "unable to notify listener (removed): " + listener, ex);
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            // Remove the listener, but don't unbind from the service. The system will bring the
-            // service back up, and the onServiceConnected handler will readd the listener with the
-            // new binding. If this isn't a bound service, and is just a registered
-            // INotificationListener, just removing it from the list is all we need to do anyway.
-            removeListenerImpl(this.listener, this.userid);
-        }
-
-        /** convenience method for looking in mEnabledListenersForCurrentProfiles */
-        public boolean isEnabledForCurrentProfiles() {
-            if (this.isSystem) return true;
-            if (this.connection == null) return false;
-            return mEnabledListenersForCurrentProfiles.contains(this.component);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5f096cb..5a1f9b2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -22,6 +22,7 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.INotificationManager;
@@ -35,10 +36,10 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
@@ -49,15 +50,18 @@
 import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.IInterface;
 import android.os.Message;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.os.UserManager;
 import android.os.Vibrator;
 import android.provider.Settings;
 import android.service.notification.INotificationListener;
+import android.service.notification.IConditionProvider;
+import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
+import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
@@ -65,7 +69,6 @@
 import android.util.AtomicFile;
 import android.util.Log;
 import android.util.Slog;
-import android.util.SparseArray;
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
@@ -78,7 +81,8 @@
 import com.android.server.SystemService;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
-import com.android.server.notification.NotificationListeners.NotificationListenerInfo;
+import com.android.server.notification.ManagedServices.ManagedServiceInfo;
+import com.android.server.notification.ManagedServices.UserProfiles;
 import com.android.server.notification.NotificationUsageStats.SingleNotificationStats;
 import com.android.server.statusbar.StatusBarManagerInternal;
 
@@ -101,7 +105,6 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Iterator;
-import java.util.List;
 import java.util.NoSuchElementException;
 
 /** {@hide} */
@@ -191,8 +194,9 @@
 
     final ArrayList<NotificationScorer> mScorers = new ArrayList<NotificationScorer>();
 
-    private NotificationListeners mListeners;
     private final UserProfiles mUserProfiles = new UserProfiles();
+    private NotificationListeners mListeners;
+    private ConditionProviders mConditionProviders;
 
     private final NotificationUsageStats mUsageStats = new NotificationUsageStats();
 
@@ -745,6 +749,7 @@
                     }
                 }
                 mListeners.onPackagesChanged(queryReplace, pkgList);
+                mConditionProviders.onPackagesChanged(queryReplace, pkgList);
             } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
                 // Keep track of screen on/off state, but do not turn off the notification light
                 // until user passes through the lock screen or views the notification.
@@ -845,18 +850,9 @@
 
         importOldBlockDb();
 
-        mListeners = new NotificationListeners(getContext(),
-                mHandler, mNotificationList, mUserProfiles) {
-            @Override
-            public void onServiceAdded(INotificationListener listener) {
-                final String[] keys = getActiveNotificationKeysFromListener(listener);
-                try {
-                    listener.onListenerConnected(keys);
-                } catch (RemoteException e) {
-                    // we tried
-                }
-            }
-        };
+        mListeners = new NotificationListeners();
+        mConditionProviders = new ConditionProviders(getContext(),
+                mHandler, mNotificationList, mUserProfiles);
         mStatusBar = getLocalService(StatusBarManagerInternal.class);
         mStatusBar.setNotificationDelegate(mNotificationDelegate);
 
@@ -972,6 +968,7 @@
             // bind to listener services.
             mSettingsObserver.observe();
             mListeners.onBootPhaseAppsCanStart();
+            mConditionProviders.onBootPhaseAppsCanStart();
         }
     }
 
@@ -1005,8 +1002,7 @@
                 return ;
             }
 
-            final boolean isSystemToast =
-                    NotificationUtil.isCallerSystem() || ("android".equals(pkg));
+            final boolean isSystemToast = isCallerSystem() || ("android".equals(pkg));
 
             if (ENABLE_BLOCKED_TOASTS && !noteNotificationOp(pkg, Binder.getCallingUid())) {
                 if (!isSystemToast) {
@@ -1097,7 +1093,7 @@
 
         @Override
         public void cancelNotificationWithTag(String pkg, String tag, int id, int userId) {
-            NotificationUtil.checkCallerIsSystemOrSameApp(pkg);
+            checkCallerIsSystemOrSameApp(pkg);
             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                     Binder.getCallingUid(), userId, true, false, "cancelNotificationWithTag", pkg);
             // Don't allow client applications to cancel foreground service notis.
@@ -1109,7 +1105,7 @@
 
         @Override
         public void cancelAllNotifications(String pkg, int userId) {
-            NotificationUtil.checkCallerIsSystemOrSameApp(pkg);
+            checkCallerIsSystemOrSameApp(pkg);
 
             userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
                     Binder.getCallingUid(), userId, true, false, "cancelAllNotifications", pkg);
@@ -1123,7 +1119,7 @@
 
         @Override
         public void setNotificationsEnabledForPackage(String pkg, int uid, boolean enabled) {
-            NotificationUtil.checkCallerIsSystem();
+            checkCallerIsSystem();
 
             setNotificationsEnabledForPackageImpl(pkg, uid, enabled);
         }
@@ -1133,7 +1129,7 @@
          */
         @Override
         public boolean areNotificationsEnabledForPackage(String pkg, int uid) {
-            NotificationUtil.checkCallerIsSystem();
+            checkCallerIsSystem();
             return (mAppOps.checkOpNoThrow(AppOpsManager.OP_POST_NOTIFICATION, uid, pkg)
                     == AppOpsManager.MODE_ALLOWED);
         }
@@ -1201,8 +1197,8 @@
         @Override
         public void registerListener(final INotificationListener listener,
                 final ComponentName component, final int userid) {
-            NotificationUtil.checkCallerIsSystem();
-            mListeners.registerListener(listener, component, userid);
+            checkCallerIsSystem();
+            mListeners.registerService(listener, component, userid);
         }
 
         /**
@@ -1210,7 +1206,7 @@
          */
         @Override
         public void unregisterListener(INotificationListener listener, int userid) {
-            mListeners.unregisterListener(listener, userid);
+            mListeners.unregisterService(listener, userid);
         }
 
         /**
@@ -1227,8 +1223,7 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationList) {
-                    final NotificationListenerInfo info =
-                            mListeners.checkListenerTokenLocked(token);
+                    final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                     if (keys != null) {
                         final int N = keys.length;
                         for (int i = 0; i < N; i++) {
@@ -1237,7 +1232,7 @@
                             if (userId != info.userid && userId != UserHandle.USER_ALL &&
                                     !mUserProfiles.isCurrentProfile(userId)) {
                                 throw new SecurityException("Disallowed call from listener: "
-                                        + info.listener);
+                                        + info.service);
                             }
                             if (r != null) {
                                 cancelNotificationFromListenerLocked(info, callingUid, callingPid,
@@ -1255,7 +1250,7 @@
             }
         }
 
-        private void cancelNotificationFromListenerLocked(NotificationListenerInfo info,
+        private void cancelNotificationFromListenerLocked(ManagedServiceInfo info,
                 int callingUid, int callingPid, String pkg, String tag, int id, int userId) {
             cancelNotification(callingUid, callingPid, pkg, tag, id, 0,
                     Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
@@ -1278,8 +1273,7 @@
             long identity = Binder.clearCallingIdentity();
             try {
                 synchronized (mNotificationList) {
-                    final NotificationListenerInfo info =
-                            mListeners.checkListenerTokenLocked(token);
+                    final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                     if (info.supportsProfiles()) {
                         Log.e(TAG, "Ignoring deprecated cancelNotification(pkg, tag, id) "
                                 + "from " + info.component
@@ -1305,14 +1299,14 @@
         public StatusBarNotification[] getActiveNotificationsFromListener(
                 INotificationListener token, String[] keys) {
             synchronized (mNotificationList) {
-                final NotificationListenerInfo info = mListeners.checkListenerTokenLocked(token);
+                final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
                 final ArrayList<StatusBarNotification> list
                         = new ArrayList<StatusBarNotification>();
                 if (keys == null) {
                     final int N = mNotificationList.size();
                     for (int i=0; i<N; i++) {
                         StatusBarNotification sbn = mNotificationList.get(i).sbn;
-                        if (info.enabledAndUserMatches(sbn)) {
+                        if (info.enabledAndUserMatches(sbn.getUserId())) {
                             list.add(sbn);
                         }
                     }
@@ -1320,7 +1314,7 @@
                     final int N = keys.length;
                     for (int i=0; i<N; i++) {
                         NotificationRecord r = mNotificationsByKey.get(keys[i]);
-                        if (r != null && info.enabledAndUserMatches(r.sbn)) {
+                        if (r != null && info.enabledAndUserMatches(r.sbn.getUserId())) {
                             list.add(r.sbn);
                         }
                     }
@@ -1336,17 +1330,23 @@
 
         @Override
         public ZenModeConfig getZenModeConfig() {
-            NotificationUtil.checkCallerIsSystem();
+            checkCallerIsSystem();
             return mZenModeHelper.getConfig();
         }
 
         @Override
         public boolean setZenModeConfig(ZenModeConfig config) {
-            NotificationUtil.checkCallerIsSystem();
+            checkCallerIsSystem();
             return mZenModeHelper.setConfig(config);
         }
 
         @Override
+        public void notifyCondition(IConditionProvider provider, Condition condition) {
+            // TODO check token
+            mZenModeHelper.notifyCondition(condition);
+        }
+
+        @Override
         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
             if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
                     != PackageManager.PERMISSION_GRANTED) {
@@ -1362,12 +1362,12 @@
 
     private String[] getActiveNotificationKeysFromListener(INotificationListener token) {
         synchronized (mNotificationList) {
-            final NotificationListenerInfo info = mListeners.checkListenerTokenLocked(token);
+            final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
             final ArrayList<String> keys = new ArrayList<String>();
             final int N = mNotificationList.size();
             for (int i=0; i<N; i++) {
                 final StatusBarNotification sbn = mNotificationList.get(i).sbn;
-                if (info.enabledAndUserMatches(sbn)) {
+                if (info.enabledAndUserMatches(sbn.getUserId())) {
                     keys.add(sbn.getKey());
                 }
             }
@@ -1379,6 +1379,7 @@
         pw.println("Current Notification Manager state:");
 
         mListeners.dump(pw);
+        mConditionProviders.dump(pw);
 
         int N;
 
@@ -1455,9 +1456,8 @@
             Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
                     + " notification=" + notification);
         }
-        NotificationUtil.checkCallerIsSystemOrSameApp(pkg);
-        final boolean isSystemNotification =
-                NotificationUtil.isUidSystem(callingUid) || ("android".equals(pkg));
+        checkCallerIsSystemOrSameApp(pkg);
+        final boolean isSystemNotification = isUidSystem(callingUid) || ("android".equals(pkg));
 
         final int userId = ActivityManager.handleIncomingUser(callingPid,
                 callingUid, incomingUserId, true, false, "enqueueNotification", pkg);
@@ -2028,7 +2028,7 @@
     void cancelNotification(final int callingUid, final int callingPid,
             final String pkg, final String tag, final int id,
             final int mustHaveFlags, final int mustNotHaveFlags, final boolean sendDelete,
-            final int userId, final int reason, final NotificationListenerInfo listener) {
+            final int userId, final int reason, final ManagedServiceInfo listener) {
         // In enqueueNotificationInternal notifications are added by scheduling the
         // work on the worker handler. Hence, we also schedule the cancel on this
         // handler to avoid a scenario where an add notification call followed by a
@@ -2099,7 +2099,7 @@
      */
     boolean cancelAllNotificationsInt(int callingUid, int callingPid, String pkg, int mustHaveFlags,
             int mustNotHaveFlags, boolean doit, int userId, int reason,
-            NotificationListenerInfo listener) {
+            ManagedServiceInfo listener) {
         EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
                 pkg, userId, mustHaveFlags, mustNotHaveFlags, reason,
                 listener == null ? null : listener.component.toShortString());
@@ -2141,7 +2141,7 @@
     }
 
     void cancelAllLocked(int callingUid, int callingPid, int userId, int reason,
-            NotificationListenerInfo listener, boolean includeCurrentProfiles) {
+            ManagedServiceInfo listener, boolean includeCurrentProfiles) {
         EventLogTags.writeNotificationCancelAll(callingUid, callingPid,
                 null, userId, 0, 0, reason,
                 listener == null ? null : listener.component.toShortString());
@@ -2234,38 +2234,129 @@
         }
     }
 
-    public static class UserProfiles {
-        // Profiles of the current user.
-        private final SparseArray<UserInfo> mCurrentProfiles = new SparseArray<UserInfo>();
+    private static boolean isUidSystem(int uid) {
+        final int appid = UserHandle.getAppId(uid);
+        return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
+    }
 
-        private void updateCache(Context context) {
-            UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-            if (userManager != null) {
-                int currentUserId = ActivityManager.getCurrentUser();
-                List<UserInfo> profiles = userManager.getProfiles(currentUserId);
-                synchronized (mCurrentProfiles) {
-                    mCurrentProfiles.clear();
-                    for (UserInfo user : profiles) {
-                        mCurrentProfiles.put(user.id, user);
+    private static boolean isCallerSystem() {
+        return isUidSystem(Binder.getCallingUid());
+    }
+
+    private static void checkCallerIsSystem() {
+        if (isCallerSystem()) {
+            return;
+        }
+        throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
+    }
+
+    private static void checkCallerIsSystemOrSameApp(String pkg) {
+        if (isCallerSystem()) {
+            return;
+        }
+        final int uid = Binder.getCallingUid();
+        try {
+            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
+                    pkg, 0, UserHandle.getCallingUserId());
+            if (!UserHandle.isSameApp(ai.uid, uid)) {
+                throw new SecurityException("Calling uid " + uid + " gave package"
+                        + pkg + " which is owned by uid " + ai.uid);
+            }
+        } catch (RemoteException re) {
+            throw new SecurityException("Unknown package " + pkg + "\n" + re);
+        }
+    }
+
+    public class NotificationListeners extends ManagedServices {
+
+        public NotificationListeners() {
+            super(getContext(), mHandler, mNotificationList, mUserProfiles);
+        }
+
+        @Override
+        protected Config getConfig() {
+            Config c = new Config();
+            c.caption = "notification listener";
+            c.serviceInterface = NotificationListenerService.SERVICE_INTERFACE;
+            c.secureSettingName = Settings.Secure.ENABLED_NOTIFICATION_LISTENERS;
+            c.bindPermission = android.Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE;
+            c.settingsAction = Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS;
+            c.clientLabel = R.string.notification_listener_binding_label;
+            return c;
+        }
+
+        @Override
+        protected IInterface asInterface(IBinder binder) {
+            return INotificationListener.Stub.asInterface(binder);
+        }
+
+        @Override
+        public void onServiceAdded(IInterface service) {
+            final INotificationListener listener = (INotificationListener) service;
+            final String[] keys = getActiveNotificationKeysFromListener(listener);
+            try {
+                listener.onListenerConnected(keys);
+            } catch (RemoteException e) {
+                // we tried
+            }
+        }
+
+        /**
+         * asynchronously notify all listeners about a new notification
+         */
+        public void notifyPostedLocked(StatusBarNotification sbn) {
+            // make a copy in case changes are made to the underlying Notification object
+            final StatusBarNotification sbnClone = sbn.clone();
+            for (final ManagedServiceInfo info : mServices) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        notifyPostedIfUserMatch(info, sbnClone);
                     }
-                }
+                });
             }
         }
 
-        public int[] getCurrentProfileIds() {
-            synchronized (mCurrentProfiles) {
-                int[] users = new int[mCurrentProfiles.size()];
-                final int N = mCurrentProfiles.size();
-                for (int i = 0; i < N; ++i) {
-                    users[i] = mCurrentProfiles.keyAt(i);
-                }
-                return users;
+        /**
+         * asynchronously notify all listeners about a removed notification
+         */
+        public void notifyRemovedLocked(StatusBarNotification sbn) {
+            // make a copy in case changes are made to the underlying Notification object
+            // NOTE: this copy is lightweight: it doesn't include heavyweight parts of the
+            // notification
+            final StatusBarNotification sbnLight = sbn.cloneLight();
+            for (ManagedServiceInfo serviceInfo : mServices) {
+                final ManagedServiceInfo info = (ManagedServiceInfo) serviceInfo;
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        notifyRemovedIfUserMatch(info, sbnLight);
+                    }
+                });
             }
         }
 
-        public boolean isCurrentProfile(int userId) {
-            synchronized (mCurrentProfiles) {
-                return mCurrentProfiles.get(userId) != null;
+        private void notifyPostedIfUserMatch(ManagedServiceInfo info, StatusBarNotification sbn) {
+            if (!info.enabledAndUserMatches(sbn.getUserId())) {
+                return;
+            }
+            final INotificationListener listener = (INotificationListener)info.service;
+            try {
+                listener.onNotificationPosted(sbn);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "unable to notify listener (posted): " + listener, ex);
+            }
+        }
+
+        private void notifyRemovedIfUserMatch(ManagedServiceInfo info, StatusBarNotification sbn) {
+            if (!info.enabledAndUserMatches(sbn.getUserId())) {
+                return;
+            }
+            final INotificationListener listener = (INotificationListener)info.service;
+            try {
+                listener.onNotificationRemoved(sbn);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "unable to notify listener (removed): " + listener, ex);
             }
         }
     }
diff --git a/services/core/java/com/android/server/notification/NotificationUtil.java b/services/core/java/com/android/server/notification/NotificationUtil.java
deleted file mode 100644
index 459adce..0000000
--- a/services/core/java/com/android/server/notification/NotificationUtil.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * Copyright (c) 2014, 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.app.AppGlobals;
-import android.content.pm.ApplicationInfo;
-import android.os.Binder;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.UserHandle;
-
-public class NotificationUtil {
-
-    // Return true if the UID is a system or phone UID and therefore should not have
-    // any notifications or toasts blocked.
-    public static boolean isUidSystem(int uid) {
-        final int appid = UserHandle.getAppId(uid);
-        return (appid == Process.SYSTEM_UID || appid == Process.PHONE_UID || uid == 0);
-    }
-
-    // same as isUidSystem(int, int) for the Binder caller's UID.
-    public static boolean isCallerSystem() {
-        return isUidSystem(Binder.getCallingUid());
-    }
-
-    public static void checkCallerIsSystem() {
-        if (isCallerSystem()) {
-            return;
-        }
-        throw new SecurityException("Disallowed call for uid " + Binder.getCallingUid());
-    }
-
-    public static void checkCallerIsSystemOrSameApp(String pkg) {
-        if (isCallerSystem()) {
-            return;
-        }
-        final int uid = Binder.getCallingUid();
-        try {
-            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(
-                    pkg, 0, UserHandle.getCallingUserId());
-            if (!UserHandle.isSameApp(ai.uid, uid)) {
-                throw new SecurityException("Calling uid " + uid + " gave package"
-                        + pkg + " which is owned by uid " + ai.uid);
-            }
-        } catch (RemoteException re) {
-            throw new SecurityException("Unknown package " + pkg + "\n" + re);
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 80f5b5c..b00beb6 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -33,6 +33,7 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.provider.Settings.Global;
+import android.service.notification.Condition;
 import android.service.notification.ZenModeConfig;
 import android.util.Slog;
 
@@ -201,6 +202,10 @@
         return true;
     }
 
+    public void notifyCondition(Condition condition) {
+        Slog.d(TAG, "notifyCondition " + condition);
+    }
+
     private boolean isCall(String pkg, Notification n) {
         return CALL_PACKAGES.contains(pkg);
     }
