add a ranking service to the rocket

Bug: 22960980
Change-Id: Ic0e911a2f048a4b47171b338c3de13125852be43
This commit is contained in:
Chris Wren
2016-03-01 17:17:47 -05:00
parent e0ba7eb365
commit 0efdb88ccc
9 changed files with 122 additions and 34 deletions

View File

@@ -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);

View File

@@ -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})

View File

@@ -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());
}

View File

@@ -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

View File

@@ -15,18 +15,27 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
package="android.ext.services"
android:versionCode="1"
android:versionName="1"
coreApp="true">
<application android:label="@string/app_name"
android:allowBackup="false"
android:forceDeviceEncrypted="true"
android:encryptionAware="true">
<library android:name="android.ext.services"/>
<service android:name=".notification.Ranker"
android:label="@string/notification_ranker"
android:permission="android.permission.BIND_NOTIFICATION_RANKER_SERVICE"
android:exported="true">
<intent-filter>
<action android:name="android.service.notification.NotificationRankerService" />
</intent-filter>
</service>
</application>
</manifest>

View File

@@ -16,4 +16,5 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name">Android Services Library</string>
<string name="notification_ranker">Android Notification Ranking Service</string>
</resources>

View File

@@ -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");
}
}

View File

@@ -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<ComponentName> queryPackageForServices(String packageName, int userId,
public Set<ComponentName> queryPackageForServices(String packageName, int userId,
String category) {
Set<ComponentName> 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);
}

View File

@@ -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<ComponentName> rankerComponents = mRankerServices.queryPackageForServices(
mRankerServicePackageName, UserHandle.USER_SYSTEM, null);
Iterator<ComponentName> 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;