diff options
| author | Chris Wren <cwren@android.com> | 2015-12-15 15:34:46 -0500 |
|---|---|---|
| committer | Chris Wren <cwren@android.com> | 2016-01-04 11:22:37 -0500 |
| commit | 51017d0e23ce9855fabcf786a2067ceb19121fbc (patch) | |
| tree | 48d2c9e0f88cb34a55bb40aa6e8c807148388a08 /core/java | |
| parent | 4a5b54fb3b02db53c1f46aafe07a318bdc5d7e3c (diff) | |
implement assistant service connection
Added a guest-mode to ManagedServices.
Like system services, the lifecycle of a guest is not managed.
Unlike system services, guests are not considered privledged.
The Assistant gets all the usual listener events.
Implemented adjustImportance.
Future work: enqueued, clicked, visibility, removed, annotations
Bug: 22455414
Change-Id: Ic41c0bf625b5e98cb577b49098bba23a539bb507
Diffstat (limited to 'core/java')
7 files changed, 160 insertions, 124 deletions
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index abe9822e972f..e60cb0377e96 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -78,6 +78,8 @@ interface INotificationManager void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim); void setInterruptionFilter(String pkg, int interruptionFilter); + void setImportanceFromAssistant(in INotificationListener token, String key, int importance, CharSequence explanation); + ComponentName getEffectsSuppressor(); boolean matchesCallFilter(in Bundle extras); boolean isSystemConditionProviderEnabled(String path); diff --git a/core/java/android/service/notification/INotificationAssistant.aidl b/core/java/android/service/notification/INotificationAssistant.aidl deleted file mode 100644 index 5c5f358b99b9..000000000000 --- a/core/java/android/service/notification/INotificationAssistant.aidl +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright (c) 2015, 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.service.notification; - -import android.service.notification.NotificationAdjustment; -import android.service.notification.IStatusBarNotificationHolder; -import android.service.notification.NotificationRankingUpdate; - -/** @hide */ -interface INotificationAssistant -{ - void onListenerConnected(in NotificationRankingUpdate update); - void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder, - in NotificationRankingUpdate update); - void onNotificationRankingUpdate(in NotificationRankingUpdate update); - void onListenerHintsChanged(int hints); - void onInterruptionFilterChanged(int interruptionFilter); - NotificationAdjustment onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder, int importance, boolean user); - void onNotificationVisibilityChanged(String key, long time, boolean visible); - void onNotificationClick(String key, long time); - void onNotificationActionClick(String key, long time, int actionIndex); - void onNotificationRemoved(String key, long time, int reason); -}
\ No newline at end of file diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl index e6bf6ba97492..a0de17f4b7cf 100644 --- a/core/java/android/service/notification/INotificationListener.aidl +++ b/core/java/android/service/notification/INotificationListener.aidl @@ -23,6 +23,7 @@ import android.service.notification.NotificationRankingUpdate; /** @hide */ oneway interface INotificationListener { + // listeners and assistants void onListenerConnected(in NotificationRankingUpdate update); void onNotificationPosted(in IStatusBarNotificationHolder notificationHolder, in NotificationRankingUpdate update); @@ -31,4 +32,11 @@ oneway interface INotificationListener void onNotificationRankingUpdate(in NotificationRankingUpdate update); void onListenerHintsChanged(int hints); void onInterruptionFilterChanged(int interruptionFilter); + + // assistants only + void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder, int importance, boolean user); + void onNotificationVisibilityChanged(String key, long time, boolean visible); + void onNotificationClick(String key, long time); + void onNotificationActionClick(String key, long time, int actionIndex); + void onNotificationRemovedReason(String key, long time, int reason); } diff --git a/core/java/android/service/notification/NotificationAdjustment.aidl b/core/java/android/service/notification/NotificationAdjustment.aidl deleted file mode 100644 index 805fe2c67695..000000000000 --- a/core/java/android/service/notification/NotificationAdjustment.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2015, 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.service.notification; - -parcelable NotificationAdjustment;
\ No newline at end of file diff --git a/core/java/android/service/notification/NotificationAdjustment.java b/core/java/android/service/notification/NotificationAdjustment.java deleted file mode 100644 index c5f0db9bf5f1..000000000000 --- a/core/java/android/service/notification/NotificationAdjustment.java +++ /dev/null @@ -1,57 +0,0 @@ -package android.service.notification; - -import android.net.Uri; -import android.os.Parcel; -import android.os.Parcelable; - -public class NotificationAdjustment implements Parcelable { - int mImportance; - CharSequence mExplanation; - Uri mReference; - - /** - * Create a notification importance adjustment. - * - * @param importance The final importance of the notification. - * @param explanation A human-readable justification for the adjustment. - * @param reference A reference to an external object that augments the - * explanation, such as a - * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, - * or null. - */ - public NotificationAdjustment(int importance, CharSequence explanation, Uri reference) { - mImportance = importance; - mExplanation = explanation; - mReference = reference; - } - - private NotificationAdjustment(Parcel source) { - this(source.readInt(), source.readCharSequence(), - (Uri) source.readParcelable(NotificationAdjustment.class.getClassLoader())); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mImportance); - dest.writeCharSequence(mExplanation); - dest.writeParcelable(mReference, 0); - } - - public static final Parcelable.Creator<NotificationAdjustment> CREATOR - = new Parcelable.Creator<NotificationAdjustment>() { - @Override - public NotificationAdjustment createFromParcel(Parcel source) { - return new NotificationAdjustment(source); - } - - @Override - public NotificationAdjustment[] newArray(int size) { - return new NotificationAdjustment[size]; - } - }; -} diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java index 7ce5e1f9da9c..3a8956ec15d9 100644 --- a/core/java/android/service/notification/NotificationAssistantService.java +++ b/core/java/android/service/notification/NotificationAssistantService.java @@ -20,8 +20,11 @@ import android.annotation.SdkConstant; import android.app.Notification; import android.content.Intent; import android.net.Uri; +import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; +import android.os.RemoteException; +import android.util.Log; /** * A service that helps the user manage notifications by modifying the @@ -39,6 +42,8 @@ import android.os.Parcelable; * </service></pre> */ public abstract class NotificationAssistantService extends NotificationListenerService { + private static final String TAG = "NotificationAssistant"; + /** * The {@link Intent} that must be declared as handled by the service. */ @@ -85,6 +90,36 @@ public abstract class NotificationAssistantService extends NotificationListenerS /** Notification was canceled because it was an invisible member of a group. */ public static final int REASON_GROUP_OPTIMIZATION = 13; + public class Adjustment { + int mImportance; + CharSequence mExplanation; + Uri mReference; + + /** + * Create a notification importance adjustment. + * + * @param importance The final importance of the notification. + * @param explanation A human-readable justification for the adjustment. + * @param reference A reference to an external object that augments the + * explanation, such as a + * {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI}, + * or null. + */ + public Adjustment(int importance, CharSequence explanation, Uri reference) { + mImportance = importance; + mExplanation = explanation; + mReference = reference; + } + } + + @Override + public IBinder onBind(Intent intent) { + if (mWrapper == null) { + mWrapper = new NotificationAssistantWrapper(); + } + return mWrapper; + } + /** * A notification was posted by an app. Called before alert. * @@ -93,7 +128,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS * @param user true if the initial importance reflects an explicit user preference. * @return an adjustment or null to take no action, within 100ms. */ - abstract public NotificationAdjustment onNotificationEnqueued(StatusBarNotification sbn, + abstract public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance, boolean user); /** @@ -150,9 +185,15 @@ 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, NotificationAdjustment adjustment) + public final void adjustImportance(String key, Adjustment adjustment) { - // TODO: pack up the adjustment and send it to the NotificationManager. + if (!isBound()) return; + try { + getNotificationInterface().setImportanceFromAssistant(mWrapper, key, + adjustment.mImportance, adjustment.mExplanation); + } catch (android.os.RemoteException ex) { + Log.v(TAG, "Unable to contact notification manager", ex); + } } /** @@ -160,7 +201,7 @@ public abstract class NotificationAssistantService extends NotificationListenerS * be fired when the host notification is deleted, or when this annotation * is removed or replaced. * - * @param key the notification key + * @param key the key of the notification to be annotated * @param annotation the new annotation object */ public final void setAnnotation(String key, Notification annotation) @@ -171,10 +212,74 @@ public abstract class NotificationAssistantService extends NotificationListenerS /** * Remove the annotation from a notification. * - * @param key the notification key + * @param key the key of the notification to be cleansed of annotatons */ public final void clearAnnotation(String key) { // TODO: ask the NotificationManager to clear the annotation. } + + private class NotificationAssistantWrapper extends NotificationListenerWrapper { + @Override + public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder, + int importance, boolean user) throws RemoteException { + StatusBarNotification sbn; + try { + sbn = sbnHolder.get(); + } catch (RemoteException e) { + Log.w(TAG, "onNotificationEnqueued: Error receiving StatusBarNotification", e); + 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); + } + } + + @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); + } + } + + @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); + } + } + + @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); + } + } + + @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); + } + } + } } diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index 1e62edc6634f..6c99489d7709 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -15,6 +15,7 @@ */ package android.service.notification; +import android.service.notification.IStatusBarNotificationHolder; import android.annotation.SystemApi; import android.annotation.SdkConstant; @@ -151,7 +152,8 @@ public abstract class NotificationListenerService extends Service { @SystemApi public static final int TRIM_LIGHT = 1; - private INotificationListenerWrapper mWrapper = null; + /** @hide */ + protected NotificationListenerWrapper mWrapper = null; private RankingMap mRankingMap; private INotificationManager mNoMan; @@ -291,7 +293,8 @@ public abstract class NotificationListenerService extends Service { // optional } - private final INotificationManager getNotificationInterface() { + /** @hide */ + protected final INotificationManager getNotificationInterface() { if (mNoMan == null) { mNoMan = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); @@ -634,12 +637,13 @@ public abstract class NotificationListenerService extends Service { @Override public IBinder onBind(Intent intent) { if (mWrapper == null) { - mWrapper = new INotificationListenerWrapper(); + mWrapper = new NotificationListenerWrapper(); } return mWrapper; } - private boolean isBound() { + /** @hide */ + protected boolean isBound() { if (mWrapper == null) { Log.w(TAG, "Notification listener service not yet bound."); return false; @@ -664,7 +668,7 @@ public abstract class NotificationListenerService extends Service { int currentUser) throws RemoteException { mSystemContext = context; if (mWrapper == null) { - mWrapper = new INotificationListenerWrapper(); + mWrapper = new NotificationListenerWrapper(); } INotificationManager noMan = getNotificationInterface(); noMan.registerListener(mWrapper, componentName, currentUser); @@ -716,7 +720,8 @@ public abstract class NotificationListenerService extends Service { } } - private class INotificationListenerWrapper extends INotificationListener.Stub { + /** @hide */ + protected class NotificationListenerWrapper extends INotificationListener.Stub { @Override public void onNotificationPosted(IStatusBarNotificationHolder sbnHolder, NotificationRankingUpdate update) { @@ -817,6 +822,35 @@ public abstract class NotificationListenerService extends Service { Log.w(TAG, "Error running onInterruptionFilterChanged", t); } } + + @Override + public void onNotificationEnqueued(IStatusBarNotificationHolder notificationHolder, + int importance, boolean user) throws RemoteException { + // no-op in the listener + } + + @Override + public void onNotificationVisibilityChanged(String key, long time, boolean visible) + throws RemoteException { + // no-op in the listener + } + + @Override + public void onNotificationClick(String key, long time) throws RemoteException { + // no-op in the listener + } + + @Override + public void onNotificationActionClick(String key, long time, int actionIndex) + throws RemoteException { + // no-op in the listener + } + + @Override + public void onNotificationRemovedReason(String key, long time, int reason) + throws RemoteException { + // no-op in the listener + } } private void applyUpdate(NotificationRankingUpdate update) { |
