diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 2c270fc8a95cb..7a69c6234eb95 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -61,7 +61,7 @@ interface INotificationManager
StatusBarNotification[] getActiveNotifications(String callingPkg);
StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);
- void registerListener(in INotificationListener listener, in ComponentName component, int userid, boolean asRanker);
+ void registerListener(in INotificationListener listener, in ComponentName component, int userid);
void unregisterListener(in INotificationListener listener, int userid);
void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 057a4e9439710..194593af69700 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -145,7 +145,6 @@ public class NotificationManager
public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL
= "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL";
-
/** @hide */
@IntDef({INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS,
INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN})
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 4b8e88f2395bd..9cc6fb6160621 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -701,18 +701,12 @@ public abstract class NotificationListenerService extends Service {
@SystemApi
public void registerAsSystemService(Context context, ComponentName componentName,
int currentUser) throws RemoteException {
- registerAsSystemServiceImpl(context, componentName, currentUser, false /* asRanker */);
- }
-
- /** @hide */
- protected void registerAsSystemServiceImpl(Context context, ComponentName componentName,
- int currentUser, boolean asRanker) throws RemoteException {
- mSystemContext = context;
if (mWrapper == null) {
mWrapper = new NotificationListenerWrapper();
}
+ mSystemContext = context;
INotificationManager noMan = getNotificationInterface();
- noMan.registerListener(mWrapper, componentName, currentUser, asRanker);
+ noMan.registerListener(mWrapper, componentName, currentUser);
mCurrentUser = currentUser;
mHandler = new MyHandler(context.getMainLooper());
}
diff --git a/core/java/android/service/notification/NotificationRankerService.java b/core/java/android/service/notification/NotificationRankerService.java
index 520b4c225dfd8..e325354385148 100644
--- a/core/java/android/service/notification/NotificationRankerService.java
+++ b/core/java/android/service/notification/NotificationRankerService.java
@@ -37,7 +37,7 @@ import com.android.internal.os.SomeArgs;
*/
@SystemApi
public abstract class NotificationRankerService extends NotificationListenerService {
- private static final String TAG = "NotificationRanker";
+ private static final String TAG = "NotificationRankers";
/**
* The {@link Intent} that must be declared as handled by the service.
@@ -118,9 +118,8 @@ public abstract class NotificationRankerService extends NotificationListenerServ
/** @hide */
@Override
public void registerAsSystemService(Context context, ComponentName componentName,
- int currentUser) throws RemoteException {
- registerAsSystemServiceImpl(context, componentName, currentUser, true /* as Ranker */);
- mHandler = new MyHandler(getContext().getMainLooper());
+ int currentUser) {
+ throw new IllegalStateException("the ranker may not start itself.");
}
@Override
diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml
index 100b35c13d34b..519db66cf9103 100644
--- a/packages/ExtServices/AndroidManifest.xml
+++ b/packages/ExtServices/AndroidManifest.xml
@@ -15,18 +15,27 @@
-->
+
+
+
+
+
+
diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml
index 531e5171dec81..076340341d1ff 100644
--- a/packages/ExtServices/res/values/strings.xml
+++ b/packages/ExtServices/res/values/strings.xml
@@ -16,4 +16,5 @@
Android Services Library
+ Android Notification Ranking Service
diff --git a/packages/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
new file mode 100644
index 0000000000000..0b2b1a447b91d
--- /dev/null
+++ b/packages/ExtServices/src/android/ext/services/notification/Ranker.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 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.ext.services.notification;
+
+import android.service.notification.NotificationRankerService;
+import android.service.notification.StatusBarNotification;
+import android.util.Log;
+
+/**
+ * Class that provides an updatable ranker module for the notification manager..
+ */
+public final class Ranker extends NotificationRankerService {
+ private static final String TAG = "RocketRanker";
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);;
+
+ @Override
+ public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance,
+ boolean user) {
+ if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey());
+ return null;
+ }
+
+ @Override
+ public void onNotificationPosted(StatusBarNotification sbn) {
+ if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey());
+ }
+
+ @Override
+ public void onListenerConnected() {
+ if (DEBUG) Log.i(TAG, "CONNECTED");
+ }
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 0d6e3e5c947c3..ac6121b899365 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -325,12 +325,16 @@ abstract public class ManagedServices {
component.flattenToShortString());
}
- final int[] userIds = mUserProfiles.getCurrentProfileIds();
- for (int userId : userIds) {
- if (enabled) {
- registerServiceLocked(component, userId);
- } else {
- unregisterServiceLocked(component, userId);
+
+ synchronized (mMutex) {
+ final int[] userIds = mUserProfiles.getCurrentProfileIds();
+
+ for (int userId : userIds) {
+ if (enabled) {
+ registerServiceLocked(component, userId);
+ } else {
+ unregisterServiceLocked(component, userId);
+ }
}
}
}
@@ -450,7 +454,7 @@ abstract public class ManagedServices {
return queryPackageForServices(packageName, userId, null);
}
- protected Set queryPackageForServices(String packageName, int userId,
+ public Set queryPackageForServices(String packageName, int userId,
String category) {
Set installed = new ArraySet<>();
final PackageManager pm = mContext.getPackageManager();
@@ -633,7 +637,21 @@ abstract public class ManagedServices {
}
}
+ /**
+ * Inject a system service into the management list.
+ */
+ public void registerSystemService(final ComponentName name, final int userid) {
+ synchronized (mMutex) {
+ registerServiceLocked(name, userid, true /* isSystem */);
+ }
+ }
+
private void registerServiceLocked(final ComponentName name, final int userid) {
+ registerServiceLocked(name, userid, false /* isSystem */);
+ }
+
+ private void registerServiceLocked(final ComponentName name, final int userid,
+ final boolean isSystem) {
if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid);
final String servicesBindingTag = name.toString() + "/" + userid;
@@ -691,7 +709,7 @@ abstract public class ManagedServices {
try {
mService = asInterface(binder);
info = newServiceInfo(mService, name,
- userid, false /*isSystem*/, this, targetSdkVersion);
+ userid, isSystem, this, targetSdkVersion);
binder.linkToDeath(info, 0);
added = mServices.add(info);
} catch (RemoteException e) {
@@ -887,6 +905,7 @@ abstract public class ManagedServices {
return false;
}
if (this.userid == UserHandle.USER_ALL) return true;
+ if (this.userid == UserHandle.USER_SYSTEM) return true;
if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
return supportsProfiles() && mUserProfiles.isCurrentProfile(nid);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a6a1934286d93..cca00fd9fc3b3 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -161,6 +161,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
/** {@hide} */
@@ -213,6 +214,7 @@ public class NotificationManagerService extends SystemService {
/** notification_enqueue status value for an ignored notification. */
private static final int EVENTLOG_ENQUEUE_STATUS_IGNORED = 2;
+ private String mRankerServicePackageName;
private IActivityManager mAm;
AudioManager mAudioManager;
@@ -291,7 +293,7 @@ public class NotificationManagerService extends SystemService {
private final UserProfiles mUserProfiles = new UserProfiles();
private NotificationListeners mListeners;
- private NotificationRanker mRankerServices;
+ private NotificationRankers mRankerServices;
private ConditionProviders mConditionProviders;
private NotificationUsageStats mUsageStats;
@@ -897,6 +899,10 @@ public class NotificationManagerService extends SystemService {
mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class);
+ // This is the package that contains the AOSP framework update.
+ mRankerServicePackageName = getContext().getPackageManager()
+ .getServicesSystemSharedLibraryPackageName();
+
mHandler = new WorkerHandler();
mRankingThread.start();
String[] extractorNames;
@@ -941,8 +947,26 @@ public class NotificationManagerService extends SystemService {
importOldBlockDb();
+ // This is a MangedServices object that keeps track of the listeners.
mListeners = new NotificationListeners();
- mRankerServices = new NotificationRanker();
+
+ // This is a MangedServices object that keeps track of the ranker.
+ mRankerServices = new NotificationRankers();
+ // Find the updatable ranker and register it.
+ Set rankerComponents = mRankerServices.queryPackageForServices(
+ mRankerServicePackageName, UserHandle.USER_SYSTEM, null);
+ Iterator iterator = rankerComponents.iterator();
+ if (iterator.hasNext()) {
+ ComponentName rankerComponent = iterator.next();
+ if (iterator.hasNext()) {
+ Slog.e(TAG, "found multiple ranker services:" + rankerComponents);
+ } else {
+ mRankerServices.registerSystemService(rankerComponent, UserHandle.USER_SYSTEM);
+ }
+ } else {
+ Slog.w(TAG, "could not start ranker service: none found");
+ }
+
mStatusBar = getLocalService(StatusBarManagerInternal.class);
mStatusBar.setNotificationDelegate(mNotificationDelegate);
@@ -1421,13 +1445,9 @@ public class NotificationManagerService extends SystemService {
*/
@Override
public void registerListener(final INotificationListener listener,
- final ComponentName component, final int userid, boolean asRanker) {
+ final ComponentName component, final int userid) {
enforceSystemOrSystemUI("INotificationManager.registerListener");
- if (asRanker) {
- mRankerServices.registerService(listener, component, userid);
- } else {
- mListeners.registerService(listener, component, userid);
- }
+ mListeners.registerService(listener, component, userid);
}
/**
@@ -2149,6 +2169,7 @@ public class NotificationManagerService extends SystemService {
pw.print(listener.component);
}
pw.println(')');
+ pw.println("\n mRankerServicePackageName: " + mRankerServicePackageName);
pw.println("\n Notification ranker services:");
mRankerServices.dump(pw, filter);
}
@@ -3496,9 +3517,9 @@ public class NotificationManagerService extends SystemService {
}
}
- public class NotificationRanker extends ManagedServices {
+ public class NotificationRankers extends ManagedServices {
- public NotificationRanker() {
+ public NotificationRankers() {
super(getContext(), mHandler, mNotificationList, mUserProfiles);
}
@@ -3541,7 +3562,7 @@ public class NotificationManagerService extends SystemService {
// mServices is the list inside ManagedServices of all the rankers,
// There should be only one, but it's a list, so while we enforce
// singularity elsewhere, we keep it general here, to avoid surprises.
- for (final ManagedServiceInfo info : NotificationRanker.this.mServices) {
+ for (final ManagedServiceInfo info : NotificationRankers.this.mServices) {
boolean sbnVisible = isVisibleToListener(sbn, info);
if (!sbnVisible) {
continue;