am 5a657b43: Merge "NoMan: Allow listeners to specify notification trim" into lmp-dev

* commit '5a657b432a1074963484dd7df69c58576f052f07':
  NoMan: Allow listeners to specify notification trim
This commit is contained in:
Christoph Studer
2014-08-29 20:51:53 +00:00
committed by Android Git Automerger
4 changed files with 146 additions and 18 deletions

View File

@@ -58,11 +58,12 @@ interface INotificationManager
void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id);
void cancelNotificationsFromListener(in INotificationListener token, in String[] keys);
ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys);
ParceledListSlice getActiveNotificationsFromListener(in INotificationListener token, in String[] keys, int trim);
void requestHintsFromListener(in INotificationListener token, int hints);
int getHintsFromListener(in INotificationListener token);
void requestInterruptionFilterFromListener(in INotificationListener token, int interruptionFilter);
int getInterruptionFilterFromListener(in INotificationListener token);
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
ComponentName getEffectsSuppressor();

View File

@@ -1424,6 +1424,8 @@ public class Notification implements Parcelable
extras.remove(Notification.EXTRA_LARGE_ICON);
extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
extras.remove(Notification.EXTRA_PICTURE);
// Prevent light notifications from being rebuilt.
extras.remove(Builder.EXTRA_NEEDS_REBUILD);
}
}

View File

@@ -81,6 +81,33 @@ public abstract class NotificationListenerService extends Service {
* This does not change the interruption filter, only the effects. **/
public static final int HINT_HOST_DISABLE_EFFECTS = 1;
/**
* The full trim of the StatusBarNotification including all its features.
*
* @hide
*/
@SystemApi
public static final int TRIM_FULL = 0;
/**
* A light trim of the StatusBarNotification excluding the following features:
*
* <ol>
* <li>{@link Notification#tickerView tickerView}</li>
* <li>{@link Notification#contentView contentView}</li>
* <li>{@link Notification#largeIcon largeIcon}</li>
* <li>{@link Notification#bigContentView bigContentView}</li>
* <li>{@link Notification#headsUpContentView headsUpContentView}</li>
* <li>{@link Notification#EXTRA_LARGE_ICON extras[EXTRA_LARGE_ICON]}</li>
* <li>{@link Notification#EXTRA_LARGE_ICON_BIG extras[EXTRA_LARGE_ICON_BIG]}</li>
* <li>{@link Notification#EXTRA_PICTURE extras[EXTRA_PICTURE]}</li>
* </ol>
*
* @hide
*/
@SystemApi
public static final int TRIM_LIGHT = 1;
private INotificationListenerWrapper mWrapper = null;
private RankingMap mRankingMap;
@@ -313,6 +340,32 @@ public abstract class NotificationListenerService extends Service {
}
}
/**
* Sets the notification trim that will be received via {@link #onNotificationPosted}.
*
* <p>
* Setting a trim other than {@link #TRIM_FULL} enables listeners that don't need access to the
* full notification features right away to reduce their memory footprint. Full notifications
* can be requested on-demand via {@link #getActiveNotifications(int)}.
*
* <p>
* Set to {@link #TRIM_FULL} initially.
*
* @hide
*
* @param trim trim of the notifications to be passed via {@link #onNotificationPosted}.
* See <code>TRIM_*</code> constants.
*/
@SystemApi
public final void setOnNotificationPostedTrim(int trim) {
if (!isBound()) return;
try {
getNotificationInterface().setOnNotificationPostedTrimFromListener(mWrapper, trim);
} catch (RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
}
}
/**
* Request the list of outstanding notifications (that is, those that are visible to the
* current user). Useful when you don't know what's already been posted.
@@ -320,7 +373,21 @@ public abstract class NotificationListenerService extends Service {
* @return An array of active notifications, sorted in natural order.
*/
public StatusBarNotification[] getActiveNotifications() {
return getActiveNotifications(null);
return getActiveNotifications(null, TRIM_FULL);
}
/**
* Request the list of outstanding notifications (that is, those that are visible to the
* current user). Useful when you don't know what's already been posted.
*
* @hide
*
* @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
* @return An array of active notifications, sorted in natural order.
*/
@SystemApi
public StatusBarNotification[] getActiveNotifications(int trim) {
return getActiveNotifications(null, trim);
}
/**
@@ -328,14 +395,33 @@ public abstract class NotificationListenerService extends Service {
* notifications but didn't want to retain the bits, and now need to go back and extract
* more data out of those notifications.
*
* @param keys the keys of the notifications to request
* @return An array of notifications corresponding to the requested keys, in the
* same order as the key list.
*/
public StatusBarNotification[] getActiveNotifications(String[] keys) {
if (!isBound()) return null;
return getActiveNotifications(keys, TRIM_FULL);
}
/**
* Request one or more notifications by key. Useful if you have been keeping track of
* notifications but didn't want to retain the bits, and now need to go back and extract
* more data out of those notifications.
*
* @hide
*
* @param keys the keys of the notifications to request
* @param trim trim of the notifications to be returned. See <code>TRIM_*</code> constants.
* @return An array of notifications corresponding to the requested keys, in the
* same order as the key list.
*/
@SystemApi
public StatusBarNotification[] getActiveNotifications(String[] keys, int trim) {
if (!isBound())
return null;
try {
ParceledListSlice<StatusBarNotification> parceledList =
getNotificationInterface().getActiveNotificationsFromListener(mWrapper, keys);
ParceledListSlice<StatusBarNotification> parceledList = getNotificationInterface()
.getActiveNotificationsFromListener(mWrapper, keys, trim);
List<StatusBarNotification> list = parceledList.getList();
int N = list.size();

View File

@@ -17,6 +17,8 @@
package com.android.server.notification;
import static android.service.notification.NotificationListenerService.HINT_HOST_DISABLE_EFFECTS;
import static android.service.notification.NotificationListenerService.TRIM_FULL;
import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
@@ -1290,24 +1292,23 @@ public class NotificationManagerService extends SystemService {
*/
@Override
public ParceledListSlice<StatusBarNotification> getActiveNotificationsFromListener(
INotificationListener token, String[] keys) {
INotificationListener token, String[] keys, int trim) {
synchronized (mNotificationList) {
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
final ArrayList<StatusBarNotification> list
= new ArrayList<StatusBarNotification>();
final boolean getKeys = keys != null;
final int N = getKeys ? keys.length : mNotificationList.size();
list.ensureCapacity(N);
final ArrayList<StatusBarNotification> list
= new ArrayList<StatusBarNotification>(N);
for (int i=0; i<N; i++) {
final NotificationRecord r = getKeys
? mNotificationsByKey.get(keys[i])
: mNotificationList.get(i);
if (r != null) {
StatusBarNotification sbn = r.sbn;
if (isVisibleToListener(sbn, info)) {
list.add(sbn);
}
}
if (r == null) continue;
StatusBarNotification sbn = r.sbn;
if (!isVisibleToListener(sbn, info)) continue;
StatusBarNotification sbnToSend =
(trim == TRIM_FULL) ? sbn : sbn.cloneLight();
list.add(sbnToSend);
}
return new ParceledListSlice<StatusBarNotification>(list);
}
@@ -1363,6 +1364,16 @@ public class NotificationManagerService extends SystemService {
}
}
@Override
public void setOnNotificationPostedTrimFromListener(INotificationListener token, int trim)
throws RemoteException {
synchronized (mNotificationList) {
final ManagedServiceInfo info = mListeners.checkServiceTokenLocked(token);
if (info == null) return;
mListeners.setOnNotificationPostedTrimLocked(info, trim);
}
}
@Override
public ZenModeConfig getZenModeConfig() {
enforceSystemOrSystemUI("INotificationManager.getZenModeConfig");
@@ -2611,6 +2622,8 @@ public class NotificationManagerService extends SystemService {
public class NotificationListeners extends ManagedServices {
private final ArraySet<ManagedServiceInfo> mLightTrimListeners = new ArraySet<>();
public NotificationListeners() {
super(getContext(), mHandler, mNotificationList, mUserProfiles);
}
@@ -2651,6 +2664,20 @@ public class NotificationManagerService extends SystemService {
if (mListenersDisablingEffects.remove(removed)) {
updateListenerHintsLocked();
}
mLightTrimListeners.remove(removed);
}
public void setOnNotificationPostedTrimLocked(ManagedServiceInfo info, int trim) {
if (trim == TRIM_LIGHT) {
mLightTrimListeners.add(info);
} else {
mLightTrimListeners.remove(info);
}
}
public int getOnNotificationPostedTrim(ManagedServiceInfo info) {
return mLightTrimListeners.contains(info) ? TRIM_LIGHT : TRIM_FULL;
}
/**
@@ -2661,8 +2688,10 @@ public class NotificationManagerService extends SystemService {
* but isn't anymore.
*/
public void notifyPostedLocked(StatusBarNotification sbn, StatusBarNotification oldSbn) {
// make a copy in case changes are made to the underlying Notification object
final StatusBarNotification sbnClone = sbn.clone();
// Lazily initialized snapshots of the notification.
StatusBarNotification sbnClone = null;
StatusBarNotification sbnCloneLight = null;
for (final ManagedServiceInfo info : mServices) {
boolean sbnVisible = isVisibleToListener(sbn, info);
boolean oldSbnVisible = oldSbn != null ? isVisibleToListener(oldSbn, info) : false;
@@ -2684,10 +2713,20 @@ public class NotificationManagerService extends SystemService {
continue;
}
final int trim = mListeners.getOnNotificationPostedTrim(info);
if (trim == TRIM_LIGHT && sbnCloneLight == null) {
sbnCloneLight = sbn.cloneLight();
} else if (trim == TRIM_FULL && sbnClone == null) {
sbnClone = sbn.clone();
}
final StatusBarNotification sbnToPost =
(trim == TRIM_FULL) ? sbnClone : sbnCloneLight;
mHandler.post(new Runnable() {
@Override
public void run() {
notifyPosted(info, sbnClone, update);
notifyPosted(info, sbnToPost, update);
}
});
}