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;