Allow companion device mgrs channel access
- Callbacks when channels and groups are modified
- Allow them to read and update channels and groups
Test: runtest systemui-notification
Change-Id: Ie4d02bd4583f71f9faf27603bcc59a1ec0eeaf46
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 61dacef..f4e8f3f 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -101,6 +101,10 @@
void setOnNotificationPostedTrimFromListener(in INotificationListener token, int trim);
void setInterruptionFilter(String pkg, int interruptionFilter);
+ void updateNotificationChannelFromPrivilegedListener(in INotificationListener token, String pkg, in NotificationChannel channel);
+ ParceledListSlice getNotificationChannelsFromPrivilegedListener(in INotificationListener token, String pkg);
+ ParceledListSlice getNotificationChannelGroupsFromPrivilegedListener(in INotificationListener token, String pkg);
+
void applyEnqueuedAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
void applyAdjustmentFromAssistant(in INotificationListener token, in Adjustment adjustment);
void applyAdjustmentsFromAssistant(in INotificationListener token, in List<Adjustment> adjustments);
diff --git a/core/java/android/service/notification/INotificationListener.aidl b/core/java/android/service/notification/INotificationListener.aidl
index b26e328..dc1a70d 100644
--- a/core/java/android/service/notification/INotificationListener.aidl
+++ b/core/java/android/service/notification/INotificationListener.aidl
@@ -16,6 +16,8 @@
package android.service.notification;
+import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
import android.service.notification.IStatusBarNotificationHolder;
import android.service.notification.StatusBarNotification;
import android.service.notification.NotificationRankingUpdate;
@@ -33,6 +35,10 @@
void onListenerHintsChanged(int hints);
void onInterruptionFilterChanged(int interruptionFilter);
+ // companion device managers only
+ void onNotificationChannelModification(String pkgName, in NotificationChannel channel, int modificationType);
+ void onNotificationChannelGroupModification(String pkgName, in NotificationChannelGroup group, int modificationType);
+
// rankers only
void onNotificationEnqueued(in IStatusBarNotificationHolder notificationHolder);
void onNotificationSnoozedUntilContext(in IStatusBarNotificationHolder notificationHolder, String snoozeCriterionId);
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 6ec9d69..d94017c 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -138,7 +138,6 @@
}
}
-
private class NotificationAssistantServiceWrapper extends NotificationListenerWrapper {
@Override
public void onNotificationEnqueued(IStatusBarNotificationHolder sbnHolder) {
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index f55c7cf..4833be3 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,8 +16,13 @@
package android.service.notification;
+import android.Manifest;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.TestApi;
import android.app.NotificationChannel;
+import android.app.NotificationChannelGroup;
+import android.companion.CompanionDeviceManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -51,6 +56,8 @@
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;
import java.util.Collections;
import java.util.List;
@@ -59,7 +66,7 @@
* A service that receives calls from the system when new notifications are
* posted or removed, or their ranking changed.
* <p>To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
+ * the {@link Manifest.permission#BIND_NOTIFICATION_LISTENER_SERVICE} permission
* and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
* <pre>
* <service android:name=".NotificationListener"
@@ -215,6 +222,37 @@
@SystemApi
public static final int TRIM_LIGHT = 1;
+
+ /** @hide */
+ @IntDef({NOTIFICATION_CHANNEL_OR_GROUP_ADDED, NOTIFICATION_CHANNEL_OR_GROUP_UPDATED,
+ NOTIFICATION_CHANNEL_OR_GROUP_DELETED})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ChannelOrGroupModificationTypes {}
+
+ /**
+ * Channel or group modification reason provided to
+ * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
+ * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
+ * provided object was created.
+ */
+ public static final int NOTIFICATION_CHANNEL_OR_GROUP_ADDED = 1;
+
+ /**
+ * Channel or group modification reason provided to
+ * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
+ * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
+ * provided object was updated.
+ */
+ public static final int NOTIFICATION_CHANNEL_OR_GROUP_UPDATED = 2;
+
+ /**
+ * Channel or group modification reason provided to
+ * {@link #onNotificationChannelModified(String, NotificationChannel, int)} or
+ * {@link #onNotificationChannelGroupModified(String, NotificationChannelGroup, int)}- the
+ * provided object was deleted.
+ */
+ public static final int NOTIFICATION_CHANNEL_OR_GROUP_DELETED = 3;
+
private final Object mLock = new Object();
private Handler mHandler;
@@ -388,6 +426,40 @@
}
/**
+ * Implement this method to learn about notification channel modifications.
+ *
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} in order to receive this callback.
+ *
+ * @param pkg The package the channel belongs to.
+ * @param channel The channel that has changed.
+ * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
+ * {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
+ * {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
+ */
+ public void onNotificationChannelModified(String pkg, NotificationChannel channel,
+ @ChannelOrGroupModificationTypes int modificationType) {
+ // optional
+ }
+
+ /**
+ * Implement this method to learn about notification channel group modifications.
+ *
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} in order to receive this callback.
+ *
+ * @param pkg The package the group belongs to.
+ * @param group The group that has changed.
+ * @param modificationType One of {@link #NOTIFICATION_CHANNEL_OR_GROUP_ADDED},
+ * {@link #NOTIFICATION_CHANNEL_OR_GROUP_UPDATED},
+ * {@link #NOTIFICATION_CHANNEL_OR_GROUP_DELETED}.
+ */
+ public void onNotificationChannelGroupModified(String pkg, NotificationChannelGroup group,
+ @ChannelOrGroupModificationTypes int modificationType) {
+ // optional
+ }
+
+ /**
* Implement this method to be notified when the
* {@link #getCurrentInterruptionFilter() interruption filter} changed.
*
@@ -587,6 +659,69 @@
}
}
+
+ /**
+ * Updates a notification channel for a given package. This should only be used to reflect
+ * changes a user has made to the channel via the listener's user interface.
+ *
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} in order to use this method.
+ *
+ * @param pkg The package the channel belongs to.
+ * @param channel the channel to update.
+ */
+ public final void updateNotificationChannel(@NonNull String pkg,
+ @NonNull NotificationChannel channel) {
+ if (!isBound()) return;
+ try {
+ getNotificationInterface().updateNotificationChannelFromPrivilegedListener(
+ mWrapper, pkg, channel);
+ } catch (RemoteException e) {
+ Log.v(TAG, "Unable to contact notification manager", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns all notification channels belonging to the given package.
+ *
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} in order to use this method.
+ *
+ * @param pkg The package to retrieve channels for.
+ */
+ public final List<NotificationChannel> getNotificationChannels(@NonNull String pkg) {
+ if (!isBound()) return null;
+ try {
+
+ return getNotificationInterface().getNotificationChannelsFromPrivilegedListener(
+ mWrapper, pkg).getList();
+ } catch (RemoteException e) {
+ Log.v(TAG, "Unable to contact notification manager", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns all notification channel groups belonging to the given package.
+ *
+ * <p>The caller must have {@link CompanionDeviceManager#getAssociations() an associated
+ * device} in order to use this method.
+ *
+ * @param pkg The package to retrieve channel groups for.
+ */
+ public final List<NotificationChannelGroup> getNotificationChannelGroups(@NonNull String pkg) {
+ if (!isBound()) return null;
+ try {
+
+ return getNotificationInterface().getNotificationChannelGroupsFromPrivilegedListener(
+ mWrapper, pkg).getList();
+ } catch (RemoteException e) {
+ Log.v(TAG, "Unable to contact notification manager", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/**
* Sets the notification trim that will be received via {@link #onNotificationPosted}.
*
@@ -1116,6 +1251,28 @@
// no-op in the listener
}
+ @Override
+ public void onNotificationChannelModification(String pkgName, NotificationChannel channel,
+ @ChannelOrGroupModificationTypes int modificationType) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = pkgName;
+ args.arg2 = channel;
+ args.arg3 = modificationType;
+ mHandler.obtainMessage(
+ MyHandler.MSG_ON_NOTIFICATION_CHANNEL_MODIFIED, args).sendToTarget();
+ }
+
+ @Override
+ public void onNotificationChannelGroupModification(String pkgName,
+ NotificationChannelGroup group,
+ @ChannelOrGroupModificationTypes int modificationType) {
+ SomeArgs args = SomeArgs.obtain();
+ args.arg1 = pkgName;
+ args.arg2 = group;
+ args.arg3 = modificationType;
+ mHandler.obtainMessage(
+ MyHandler.MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED, args).sendToTarget();
+ }
}
/**
@@ -1632,6 +1789,8 @@
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 static final int MSG_ON_NOTIFICATION_CHANNEL_MODIFIED = 7;
+ public static final int MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED = 8;
public MyHandler(Looper looper) {
super(looper, null, false);
@@ -1678,6 +1837,22 @@
final int interruptionFilter = msg.arg1;
onInterruptionFilterChanged(interruptionFilter);
} break;
+
+ case MSG_ON_NOTIFICATION_CHANNEL_MODIFIED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ String pkgName = (String) args.arg1;
+ NotificationChannel channel = (NotificationChannel) args.arg2;
+ int modificationType = (int) args.arg3;
+ onNotificationChannelModified(pkgName, channel, modificationType);
+ } break;
+
+ case MSG_ON_NOTIFICATION_CHANNEL_GROUP_MODIFIED: {
+ SomeArgs args = (SomeArgs) msg.obj;
+ String pkgName = (String) args.arg1;
+ NotificationChannelGroup group = (NotificationChannelGroup) args.arg2;
+ int modificationType = (int) args.arg3;
+ onNotificationChannelGroupModified(pkgName, group, modificationType);
+ } break;
}
}
}