diff options
3 files changed, 224 insertions, 17 deletions
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java new file mode 100644 index 000000000000..fac9e98a6caf --- /dev/null +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/NotificationListenerController.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2017 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 com.android.systemui.plugins; + +import android.service.notification.NotificationListenerService.RankingMap; +import android.service.notification.StatusBarNotification; + +import com.android.systemui.plugins.NotificationListenerController.NotificationProvider; +import com.android.systemui.plugins.annotations.DependsOn; +import com.android.systemui.plugins.annotations.ProvidesInterface; + +@ProvidesInterface(action = NotificationListenerController.ACTION, + version = NotificationListenerController.VERSION) +@DependsOn(target = NotificationProvider.class) +public interface NotificationListenerController extends Plugin { + String ACTION = "com.android.systemui.action.PLUGIN_NOTIFICATION_ASSISTANT"; + int VERSION = 1; + + void onListenerConnected(NotificationProvider provider); + + default boolean onNotificationPosted(StatusBarNotification sbn, RankingMap rankingMap) { + return false; + } + default boolean onNotificationRemoved(StatusBarNotification sbn, RankingMap rankingMap) { + return false; + } + + default StatusBarNotification[] getActiveNotifications( + StatusBarNotification[] activeNotifications) { + return activeNotifications; + } + + default RankingMap getCurrentRanking(RankingMap currentRanking) { + return currentRanking; + } + + @ProvidesInterface(version = NotificationProvider.VERSION) + interface NotificationProvider { + int VERSION = 1; + + // Methods to get info about current notifications + StatusBarNotification[] getActiveNotifications(); + RankingMap getRankingMap(); + + // Methods to notify sysui of changes to notification list. + void addNotification(StatusBarNotification sbn); + void removeNotification(StatusBarNotification sbn); + void updateRanking(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java new file mode 100644 index 000000000000..9ff907b17564 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationListenerWithPlugins.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2017 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 com.android.systemui.statusbar.phone; + +import android.content.ComponentName; +import android.content.Context; +import android.os.RemoteException; +import android.service.notification.NotificationListenerService; +import android.service.notification.StatusBarNotification; + +import com.android.systemui.Dependency; +import com.android.systemui.plugins.NotificationListenerController; +import com.android.systemui.plugins.NotificationListenerController.NotificationProvider; +import com.android.systemui.plugins.PluginListener; +import com.android.systemui.plugins.PluginManager; + +import java.util.ArrayList; + +/** + * A version of NotificationListenerService that passes all info to + * any plugins connected. Also allows those plugins the chance to cancel + * any incoming callbacks or to trigger new ones. + */ +public class NotificationListenerWithPlugins extends NotificationListenerService implements + PluginListener<NotificationListenerController> { + + private ArrayList<NotificationListenerController> mPlugins = new ArrayList<>(); + private boolean mConnected; + + @Override + public void registerAsSystemService(Context context, ComponentName componentName, + int currentUser) throws RemoteException { + super.registerAsSystemService(context, componentName, currentUser); + Dependency.get(PluginManager.class).addPluginListener(this, + NotificationListenerController.class); + } + + @Override + public void unregisterAsSystemService() throws RemoteException { + super.unregisterAsSystemService(); + Dependency.get(PluginManager.class).removePluginListener(this); + } + + @Override + public StatusBarNotification[] getActiveNotifications() { + StatusBarNotification[] activeNotifications = super.getActiveNotifications(); + for (NotificationListenerController plugin : mPlugins) { + activeNotifications = plugin.getActiveNotifications(activeNotifications); + } + return activeNotifications; + } + + @Override + public RankingMap getCurrentRanking() { + RankingMap currentRanking = super.getCurrentRanking(); + for (NotificationListenerController plugin : mPlugins) { + currentRanking = plugin.getCurrentRanking(currentRanking); + } + return currentRanking; + } + + public void onPluginConnected() { + mConnected = true; + mPlugins.forEach(p -> p.onListenerConnected(getProvider())); + } + + /** + * Called when listener receives a onNotificationPosted. + * Returns true to indicate this callback should be skipped. + */ + public boolean onPluginNotificationPosted(StatusBarNotification sbn, + final RankingMap rankingMap) { + for (NotificationListenerController plugin : mPlugins) { + if (plugin.onNotificationPosted(sbn, rankingMap)) { + return true; + } + } + return false; + } + + /** + * Called when listener receives a onNotificationRemoved. + * Returns true to indicate this callback should be skipped. + */ + public boolean onPluginNotificationRemoved(StatusBarNotification sbn, + final RankingMap rankingMap) { + for (NotificationListenerController plugin : mPlugins) { + if (plugin.onNotificationRemoved(sbn, rankingMap)) { + return true; + } + } + return false; + } + + public RankingMap onPluginRankingUpdate(RankingMap rankingMap) { + return getCurrentRanking(); + } + + @Override + public void onPluginConnected(NotificationListenerController plugin, Context pluginContext) { + mPlugins.add(plugin); + if (mConnected) { + plugin.onListenerConnected(getProvider()); + } + } + + @Override + public void onPluginDisconnected(NotificationListenerController plugin) { + mPlugins.remove(plugin); + } + + private NotificationProvider getProvider() { + return new NotificationProvider() { + @Override + public StatusBarNotification[] getActiveNotifications() { + return NotificationListenerWithPlugins.super.getActiveNotifications(); + } + + @Override + public RankingMap getRankingMap() { + return NotificationListenerWithPlugins.super.getCurrentRanking(); + } + + @Override + public void addNotification(StatusBarNotification sbn) { + onNotificationPosted(sbn, getRankingMap()); + } + + @Override + public void removeNotification(StatusBarNotification sbn) { + onNotificationRemoved(sbn, getRankingMap()); + } + + @Override + public void updateRanking() { + onNotificationRankingUpdate(getRankingMap()); + } + }; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java index 10cb567436e0..e8b6e079e261 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java @@ -5769,11 +5769,12 @@ public class StatusBar extends SystemUI implements DemoMode, } }; - private final NotificationListenerService mNotificationListener = - new NotificationListenerService() { + private final NotificationListenerWithPlugins mNotificationListener = + new NotificationListenerWithPlugins() { @Override public void onListenerConnected() { if (DEBUG) Log.d(TAG, "onListenerConnected"); + onPluginConnected(); final StatusBarNotification[] notifications = getActiveNotifications(); if (notifications == null) { Log.w(TAG, "onListenerConnected unable to get active notifications."); @@ -5798,7 +5799,7 @@ public class StatusBar extends SystemUI implements DemoMode, public void onNotificationPosted(final StatusBarNotification sbn, final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn); - if (sbn != null) { + if (sbn != null && !onPluginNotificationPosted(sbn, rankingMap)) { mHandler.post(new Runnable() { @Override public void run() { @@ -5842,14 +5843,9 @@ public class StatusBar extends SystemUI implements DemoMode, public void onNotificationRemoved(StatusBarNotification sbn, final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn); - if (sbn != null) { + if (sbn != null && !onPluginNotificationRemoved(sbn, rankingMap)) { final String key = sbn.getKey(); - mHandler.post(new Runnable() { - @Override - public void run() { - removeNotification(key, rankingMap); - } - }); + mHandler.post(() -> removeNotification(key, rankingMap)); } } @@ -5857,13 +5853,10 @@ public class StatusBar extends SystemUI implements DemoMode, public void onNotificationRankingUpdate(final RankingMap rankingMap) { if (DEBUG) Log.d(TAG, "onRankingUpdate"); if (rankingMap != null) { - mHandler.post(new Runnable() { - @Override - public void run() { - updateNotificationRanking(rankingMap); - } - }); - } } + RankingMap r = onPluginRankingUpdate(rankingMap); + mHandler.post(() -> updateNotificationRanking(r)); + } + } }; |