• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5  * except in compliance with the License. You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the
10  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language governing
12  * permissions and limitations under the License.
13  */
14 
15 package com.android.systemui.statusbar.phone;
16 
17 import android.app.NotificationChannel;
18 import android.content.ComponentName;
19 import android.content.Context;
20 import android.os.RemoteException;
21 import android.os.UserHandle;
22 import android.service.notification.NotificationListenerService;
23 import android.service.notification.StatusBarNotification;
24 
25 import com.android.systemui.Dependency;
26 import com.android.systemui.plugins.NotificationListenerController;
27 import com.android.systemui.plugins.NotificationListenerController.NotificationProvider;
28 import com.android.systemui.plugins.PluginListener;
29 import com.android.systemui.shared.plugins.PluginManager;
30 
31 import java.util.ArrayList;
32 
33 /**
34  * A version of NotificationListenerService that passes all info to
35  * any plugins connected. Also allows those plugins the chance to cancel
36  * any incoming callbacks or to trigger new ones.
37  */
38 public class NotificationListenerWithPlugins extends NotificationListenerService implements
39         PluginListener<NotificationListenerController> {
40 
41     private ArrayList<NotificationListenerController> mPlugins = new ArrayList<>();
42     private boolean mConnected;
43 
44     @Override
registerAsSystemService(Context context, ComponentName componentName, int currentUser)45     public void registerAsSystemService(Context context, ComponentName componentName,
46             int currentUser) throws RemoteException {
47         super.registerAsSystemService(context, componentName, currentUser);
48         Dependency.get(PluginManager.class).addPluginListener(this,
49                 NotificationListenerController.class);
50     }
51 
52     @Override
unregisterAsSystemService()53     public void unregisterAsSystemService() throws RemoteException {
54         super.unregisterAsSystemService();
55         Dependency.get(PluginManager.class).removePluginListener(this);
56     }
57 
58     @Override
getActiveNotifications()59     public StatusBarNotification[] getActiveNotifications() {
60         StatusBarNotification[] activeNotifications = super.getActiveNotifications();
61         for (NotificationListenerController plugin : mPlugins) {
62             activeNotifications = plugin.getActiveNotifications(activeNotifications);
63         }
64         return activeNotifications;
65     }
66 
67     @Override
getCurrentRanking()68     public RankingMap getCurrentRanking() {
69         RankingMap currentRanking = super.getCurrentRanking();
70         for (NotificationListenerController plugin : mPlugins) {
71             currentRanking = plugin.getCurrentRanking(currentRanking);
72         }
73         return currentRanking;
74     }
75 
onPluginConnected()76     public void onPluginConnected() {
77         mConnected = true;
78         mPlugins.forEach(p -> p.onListenerConnected(getProvider()));
79     }
80 
81     /**
82      * Called when listener receives a onNotificationPosted.
83      * Returns true if there's a plugin determining to skip the default callbacks.
84      */
onPluginNotificationPosted(StatusBarNotification sbn, final RankingMap rankingMap)85     public boolean onPluginNotificationPosted(StatusBarNotification sbn,
86             final RankingMap rankingMap) {
87         for (NotificationListenerController plugin : mPlugins) {
88             if (plugin.onNotificationPosted(sbn, rankingMap)) {
89                 return true;
90             }
91         }
92         return false;
93     }
94 
95     /**
96      * Called when listener receives a onNotificationRemoved.
97      * Returns true if there's a plugin determining to skip the default callbacks.
98      */
onPluginNotificationRemoved(StatusBarNotification sbn, final RankingMap rankingMap)99     public boolean onPluginNotificationRemoved(StatusBarNotification sbn,
100             final RankingMap rankingMap) {
101         for (NotificationListenerController plugin : mPlugins) {
102             if (plugin.onNotificationRemoved(sbn, rankingMap)) {
103                 return true;
104             }
105         }
106         return false;
107     }
108 
109     /**
110      * Called when listener receives a onNotificationChannelModified.
111      * Returns true if there's a plugin determining to skip the default callbacks.
112      */
onPluginNotificationChannelModified( String pkgName, UserHandle user, NotificationChannel channel, int modificationType)113     public boolean onPluginNotificationChannelModified(
114             String pkgName, UserHandle user, NotificationChannel channel, int modificationType) {
115         for (NotificationListenerController plugin : mPlugins) {
116             if (plugin.onNotificationChannelModified(pkgName, user, channel, modificationType)) {
117                 return true;
118             }
119         }
120         return false;
121     }
122 
onPluginRankingUpdate(RankingMap rankingMap)123     public RankingMap onPluginRankingUpdate(RankingMap rankingMap) {
124         return getCurrentRanking();
125     }
126 
127     @Override
onPluginConnected(NotificationListenerController plugin, Context pluginContext)128     public void onPluginConnected(NotificationListenerController plugin, Context pluginContext) {
129         mPlugins.add(plugin);
130         if (mConnected) {
131             plugin.onListenerConnected(getProvider());
132         }
133     }
134 
135     @Override
onPluginDisconnected(NotificationListenerController plugin)136     public void onPluginDisconnected(NotificationListenerController plugin) {
137         mPlugins.remove(plugin);
138     }
139 
getProvider()140     private NotificationProvider getProvider() {
141         return new NotificationProvider() {
142             @Override
143             public StatusBarNotification[] getActiveNotifications() {
144                 return NotificationListenerWithPlugins.super.getActiveNotifications();
145             }
146 
147             @Override
148             public RankingMap getRankingMap() {
149                 return NotificationListenerWithPlugins.super.getCurrentRanking();
150             }
151 
152             @Override
153             public void addNotification(StatusBarNotification sbn) {
154                 onNotificationPosted(sbn, getRankingMap());
155             }
156 
157             @Override
158             public void removeNotification(StatusBarNotification sbn) {
159                 onNotificationRemoved(sbn, getRankingMap());
160             }
161 
162             @Override
163             public void updateRanking() {
164                 onNotificationRankingUpdate(getRankingMap());
165             }
166         };
167     }
168 }
169