summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/service/notification/NotificationAssistantService.java164
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java164
2 files changed, 235 insertions, 93 deletions
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index b5387f14e40c..41af837a1dbc 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -18,18 +18,17 @@ package android.service.notification;
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
-import android.app.INotificationManager;
-import android.app.Notification;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.os.Handler;
import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.os.Looper;
+import android.os.Message;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.util.Log;
+import com.android.internal.os.SomeArgs;
/**
* A service that helps the user manage notifications by modifying the
@@ -125,8 +124,24 @@ public abstract class NotificationAssistantService extends NotificationListenerS
}
}
+ private Handler mHandler;
+
+ /** @hide */
+ @Override
+ public void registerAsSystemService(Context context, ComponentName componentName,
+ int currentUser) throws RemoteException {
+ super.registerAsSystemService(context, componentName, currentUser);
+ mHandler = new MyHandler(getContext().getMainLooper());
+ }
+
+ @Override
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ mHandler = new MyHandler(getContext().getMainLooper());
+ }
+
@Override
- public IBinder onBind(Intent intent) {
+ public final IBinder onBind(Intent intent) {
if (mWrapper == null) {
mWrapper = new NotificationAssistantWrapper();
}
@@ -198,8 +213,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
* @param key the notification key
* @param adjustment the new importance with an explanation
*/
- public final void adjustImportance(String key, Adjustment adjustment)
- {
+ public final void adjustImportance(String key, Adjustment adjustment) {
if (!isBound()) return;
try {
getNotificationInterface().setImportanceFromAssistant(mWrapper, key,
@@ -212,7 +226,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS
private class NotificationAssistantWrapper extends NotificationListenerWrapper {
@Override
public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder,
- int importance, boolean user) throws RemoteException {
+ int importance, boolean user) {
StatusBarNotification sbn;
try {
sbn = sbnHolder.get();
@@ -221,54 +235,114 @@ public abstract class NotificationAssistantService extends NotificationListenerS
return;
}
- try {
- Adjustment adjustment =
- NotificationAssistantService.this.onNotificationEnqueued(sbn, importance, user);
- if (adjustment != null) {
- adjustImportance(sbn.getKey(), adjustment);
- }
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationEnqueued", t);
- }
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = sbn;
+ args.argi1 = importance;
+ args.argi2 = user ? 1 : 0;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ENQUEUED,
+ args).sendToTarget();
}
@Override
- public void onNotificationVisibilityChanged(String key, long time, boolean visible)
- throws RemoteException {
- try {
- NotificationAssistantService.this.onNotificationVisibilityChanged(key, time,
- visible);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationVisibilityChanged", t);
- }
+ public void onNotificationVisibilityChanged(String key, long time, boolean visible) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = key;
+ args.arg2 = time;
+ args.argi1 = visible ? 1 : 0;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_VISIBILITY_CHANGED,
+ args).sendToTarget();
}
@Override
- public void onNotificationClick(String key, long time) throws RemoteException {
- try {
- NotificationAssistantService.this.onNotificationClick(key, time);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationClick", t);
- }
+ public void onNotificationClick(String key, long time) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = key;
+ args.arg2 = time;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_CLICK,
+ args).sendToTarget();
}
@Override
- public void onNotificationActionClick(String key, long time, int actionIndex)
- throws RemoteException {
- try {
- NotificationAssistantService.this.onNotificationActionClick(key, time, actionIndex);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationActionClick", t);
- }
+ public void onNotificationActionClick(String key, long time, int actionIndex) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = key;
+ args.arg2 = time;
+ args.argi1 = actionIndex;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_ACTION_CLICK,
+ args).sendToTarget();
}
@Override
- public void onNotificationRemovedReason(String key, long time, int reason)
- throws RemoteException {
- try {
- NotificationAssistantService.this.onNotificationRemoved(key, time, reason);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationRemoved", t);
+ public void onNotificationRemovedReason(String key, long time, int reason) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = key;
+ args.arg2 = time;
+ args.argi1 = reason;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_REMOVED_REASON,
+ args).sendToTarget();
+ }
+ }
+
+ private final class MyHandler extends Handler {
+ public static final int MSG_ON_NOTIFICATION_ENQUEUED = 1;
+ public static final int MSG_ON_NOTIFICATION_VISIBILITY_CHANGED = 2;
+ public static final int MSG_ON_NOTIFICATION_CLICK = 3;
+ public static final int MSG_ON_NOTIFICATION_ACTION_CLICK = 4;
+ public static final int MSG_ON_NOTIFICATION_REMOVED_REASON = 5;
+
+ public MyHandler(Looper looper) {
+ super(looper, null, false);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_NOTIFICATION_ENQUEUED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ StatusBarNotification sbn = (StatusBarNotification) args.arg1;
+ final int importance = args.argi1;
+ final boolean user = args.argi2 == 1;
+ args.recycle();
+ Adjustment adjustment = onNotificationEnqueued(sbn, importance, user);
+ if (adjustment != null) {
+ adjustImportance(sbn.getKey(), adjustment);
+ }
+ } break;
+
+ case MSG_ON_NOTIFICATION_VISIBILITY_CHANGED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ final String key = (String) args.arg1;
+ final long time = (long) args.arg2;
+ final boolean visible = args.argi1 == 1;
+ args.recycle();
+ onNotificationVisibilityChanged(key, time, visible);
+ } break;
+
+ case MSG_ON_NOTIFICATION_CLICK: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ final String key = (String) args.arg1;
+ final long time = (long) args.arg2;
+ args.recycle();
+ onNotificationClick(key, time);
+ } break;
+
+ case MSG_ON_NOTIFICATION_ACTION_CLICK: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ final String key = (String) args.arg1;
+ final long time = (long) args.arg2;
+ final int actionIndex = args.argi1;
+ args.recycle();
+ onNotificationActionClick(key, time, actionIndex);
+ } break;
+
+ case MSG_ON_NOTIFICATION_REMOVED_REASON: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ final String key = (String) args.arg1;
+ final long time = (long) args.arg2;
+ final int reason = args.argi1;
+ args.recycle();
+ onNotificationRemoved(key, time, reason);
+ } break;
}
}
}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index b4332e181fc4..73a890fb0308 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,6 +16,10 @@
package android.service.notification;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.SdkConstant;
@@ -43,7 +47,8 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.widget.RemoteViews;
-
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.SomeArgs;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
@@ -163,8 +168,14 @@ public abstract class NotificationListenerService extends Service {
@SystemApi
public static final int TRIM_LIGHT = 1;
+ private final Object mLock = new Object();
+
+ private Handler mHandler;
+
/** @hide */
protected NotificationListenerWrapper mWrapper = null;
+
+ @GuardedBy("mLock")
private RankingMap mRankingMap;
private INotificationManager mNoMan;
@@ -195,6 +206,12 @@ public abstract class NotificationListenerService extends Service {
public static final String CATEGORY_VR_NOTIFICATIONS =
"android.intent.category.vr.notifications";
+ @Override
+ protected void attachBaseContext(Context base) {
+ super.attachBaseContext(base);
+ mHandler = new MyHandler(getMainLooper());
+ }
+
/**
* Implement this method to learn about new notifications as they are posted by apps.
*
@@ -642,7 +659,9 @@ public abstract class NotificationListenerService extends Service {
* @return A {@link RankingMap} object providing access to ranking information
*/
public RankingMap getCurrentRanking() {
- return mRankingMap;
+ synchronized (mLock) {
+ return mRankingMap;
+ }
}
@Override
@@ -684,6 +703,7 @@ public abstract class NotificationListenerService extends Service {
INotificationManager noMan = getNotificationInterface();
noMan.registerListener(mWrapper, componentName, currentUser);
mCurrentUser = currentUser;
+ mHandler = new MyHandler(context.getMainLooper());
}
/**
@@ -710,7 +730,7 @@ public abstract class NotificationListenerService extends Service {
* <P>The service should wait for the {@link #onListenerConnected()} event
* before performing any operations.
*/
- public static final void requestRebind(ComponentName componentName)
+ public static void requestRebind(ComponentName componentName)
throws RemoteException {
INotificationManager noMan = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
@@ -782,7 +802,6 @@ public abstract class NotificationListenerService extends Service {
}
try {
- Notification notification = sbn.getNotification();
// convert icon metadata to legacy format for older clients
createLegacyIconExtras(sbn.getNotification());
maybePopulateRemoteViews(sbn.getNotification());
@@ -794,20 +813,23 @@ public abstract class NotificationListenerService extends Service {
}
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
- synchronized (mWrapper) {
- applyUpdate(update);
- try {
- if (sbn != null) {
- NotificationListenerService.this.onNotificationPosted(sbn, mRankingMap);
- } else {
- // still pass along the ranking map, it may contain other information
- NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
- }
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationPosted", t);
+ synchronized (mLock) {
+ applyUpdateLocked(update);
+ if (sbn != null) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = sbn;
+ args.arg2 = mRankingMap;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_POSTED,
+ args).sendToTarget();
+ } else {
+ // still pass along the ranking map, it may contain other information
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
+ mRankingMap).sendToTarget();
}
}
+
}
+
@Override
public void onNotificationRemoved(IStatusBarNotificationHolder sbnHolder,
NotificationRankingUpdate update) {
@@ -819,56 +841,48 @@ public abstract class NotificationListenerService extends Service {
return;
}
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
- synchronized (mWrapper) {
- applyUpdate(update);
- try {
- NotificationListenerService.this.onNotificationRemoved(sbn, mRankingMap);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationRemoved", t);
- }
+ synchronized (mLock) {
+ applyUpdateLocked(update);
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = sbn;
+ args.arg2 = mRankingMap;
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_REMOVED,
+ args).sendToTarget();
}
+
}
+
@Override
public void onListenerConnected(NotificationRankingUpdate update) {
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
- synchronized (mWrapper) {
- applyUpdate(update);
- try {
- NotificationListenerService.this.onListenerConnected();
- } catch (Throwable t) {
- Log.w(TAG, "Error running onListenerConnected", t);
- }
+ synchronized (mLock) {
+ applyUpdateLocked(update);
}
+ mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_CONNECTED).sendToTarget();
}
+
@Override
public void onNotificationRankingUpdate(NotificationRankingUpdate update)
throws RemoteException {
// protect subclass from concurrent modifications of (@link mNotificationKeys}.
- synchronized (mWrapper) {
- applyUpdate(update);
- try {
- NotificationListenerService.this.onNotificationRankingUpdate(mRankingMap);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onNotificationRankingUpdate", t);
- }
+ synchronized (mLock) {
+ applyUpdateLocked(update);
+ mHandler.obtainMessage(MyHandler.MSG_ON_NOTIFICATION_RANKING_UPDATE,
+ mRankingMap).sendToTarget();
}
+
}
+
@Override
public void onListenerHintsChanged(int hints) throws RemoteException {
- try {
- NotificationListenerService.this.onListenerHintsChanged(hints);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onListenerHintsChanged", t);
- }
+ mHandler.obtainMessage(MyHandler.MSG_ON_LISTENER_HINTS_CHANGED,
+ hints, 0).sendToTarget();
}
@Override
public void onInterruptionFilterChanged(int interruptionFilter) throws RemoteException {
- try {
- NotificationListenerService.this.onInterruptionFilterChanged(interruptionFilter);
- } catch (Throwable t) {
- Log.w(TAG, "Error running onInterruptionFilterChanged", t);
- }
+ mHandler.obtainMessage(MyHandler.MSG_ON_INTERRUPTION_FILTER_CHANGED,
+ interruptionFilter, 0).sendToTarget();
}
@Override
@@ -901,11 +915,12 @@ public abstract class NotificationListenerService extends Service {
}
}
- private void applyUpdate(NotificationRankingUpdate update) {
+ private void applyUpdateLocked(NotificationRankingUpdate update) {
mRankingMap = new RankingMap(update);
}
- private Context getContext() {
+ /** @hide */
+ protected Context getContext() {
if (mSystemContext != null) {
return mSystemContext;
}
@@ -1289,4 +1304,57 @@ public abstract class NotificationListenerService extends Service {
}
};
}
+
+ private final class MyHandler extends Handler {
+ public static final int MSG_ON_NOTIFICATION_POSTED = 1;
+ public static final int MSG_ON_NOTIFICATION_REMOVED = 2;
+ public static final int MSG_ON_LISTENER_CONNECTED = 3;
+ public static final int MSG_ON_NOTIFICATION_RANKING_UPDATE = 4;
+ public static final int MSG_ON_LISTENER_HINTS_CHANGED = 5;
+ public static final int MSG_ON_INTERRUPTION_FILTER_CHANGED = 6;
+
+ public MyHandler(Looper looper) {
+ super(looper, null, false);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_ON_NOTIFICATION_POSTED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ StatusBarNotification sbn = (StatusBarNotification) args.arg1;
+ RankingMap rankingMap = (RankingMap) args.arg2;
+ args.recycle();
+ onNotificationPosted(sbn, rankingMap);
+ } break;
+
+ case MSG_ON_NOTIFICATION_REMOVED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ StatusBarNotification sbn = (StatusBarNotification) args.arg1;
+ RankingMap rankingMap = (RankingMap) args.arg2;
+ args.recycle();
+ onNotificationRemoved(sbn, rankingMap);
+ } break;
+
+ case MSG_ON_LISTENER_CONNECTED: {
+ onListenerConnected();
+ } break;
+
+ case MSG_ON_NOTIFICATION_RANKING_UPDATE: {
+ RankingMap rankingMap = (RankingMap) msg.obj;
+ onNotificationRankingUpdate(rankingMap);
+ } break;
+
+ case MSG_ON_LISTENER_HINTS_CHANGED: {
+ final int hints = msg.arg1;
+ onListenerHintsChanged(hints);
+ } break;
+
+ case MSG_ON_INTERRUPTION_FILTER_CHANGED: {
+ final int interruptionFilter = msg.arg1;
+ onInterruptionFilterChanged(interruptionFilter);
+ } break;
+ }
+ }
+ }
}