• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.notification.row;
18 
19 import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
20 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
21 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
22 
23 import android.view.View;
24 import android.view.ViewGroup;
25 
26 import androidx.annotation.NonNull;
27 
28 import com.android.systemui.classifier.FalsingCollector;
29 import com.android.systemui.plugins.FalsingManager;
30 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
31 import com.android.systemui.plugins.statusbar.StatusBarStateController;
32 import com.android.systemui.shared.plugins.PluginManager;
33 import com.android.systemui.statusbar.NotificationMediaManager;
34 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
35 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
36 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
37 import com.android.systemui.statusbar.notification.collection.render.NodeController;
38 import com.android.systemui.statusbar.notification.logging.NotificationLogger;
39 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
40 import com.android.systemui.statusbar.notification.row.dagger.AppName;
41 import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
42 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
43 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
44 import com.android.systemui.statusbar.phone.KeyguardBypassController;
45 import com.android.systemui.statusbar.policy.HeadsUpManager;
46 import com.android.systemui.util.time.SystemClock;
47 import com.android.systemui.wmshell.BubblesManager;
48 
49 import java.util.List;
50 import java.util.Optional;
51 
52 import javax.inject.Inject;
53 import javax.inject.Named;
54 
55 /**
56  * Controller for {@link ExpandableNotificationRow}.
57  */
58 @NotificationRowScope
59 public class ExpandableNotificationRowController implements NodeController {
60     private final ExpandableNotificationRow mView;
61     private final NotificationListContainer mListContainer;
62     private final ActivatableNotificationViewController mActivatableNotificationViewController;
63     private final NotificationMediaManager mMediaManager;
64     private final PluginManager mPluginManager;
65     private final SystemClock mClock;
66     private final String mAppName;
67     private final String mNotificationKey;
68     private final KeyguardBypassController mKeyguardBypassController;
69     private final GroupMembershipManager mGroupMembershipManager;
70     private final GroupExpansionManager mGroupExpansionManager;
71     private final RowContentBindStage mRowContentBindStage;
72     private final NotificationLogger mNotificationLogger;
73     private final HeadsUpManager mHeadsUpManager;
74     private final ExpandableNotificationRow.OnExpandClickListener mOnExpandClickListener;
75     private final StatusBarStateController mStatusBarStateController;
76 
77     private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
78             this::logNotificationExpansion;
79     private final ExpandableNotificationRow.CoordinateOnClickListener mOnFeedbackClickListener;
80     private final NotificationGutsManager mNotificationGutsManager;
81     private final OnUserInteractionCallback mOnUserInteractionCallback;
82     private final FalsingManager mFalsingManager;
83     private final FalsingCollector mFalsingCollector;
84     private final boolean mAllowLongPress;
85     private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;
86     private final Optional<BubblesManager> mBubblesManagerOptional;
87 
88     @Inject
ExpandableNotificationRowController( ExpandableNotificationRow view, NotificationListContainer listContainer, ActivatableNotificationViewController activatableNotificationViewController, NotificationMediaManager mediaManager, PluginManager pluginManager, SystemClock clock, @AppName String appName, @NotificationKey String notificationKey, KeyguardBypassController keyguardBypassController, GroupMembershipManager groupMembershipManager, GroupExpansionManager groupExpansionManager, RowContentBindStage rowContentBindStage, NotificationLogger notificationLogger, HeadsUpManager headsUpManager, ExpandableNotificationRow.OnExpandClickListener onExpandClickListener, StatusBarStateController statusBarStateController, NotificationGutsManager notificationGutsManager, @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress, OnUserInteractionCallback onUserInteractionCallback, FalsingManager falsingManager, FalsingCollector falsingCollector, PeopleNotificationIdentifier peopleNotificationIdentifier, Optional<BubblesManager> bubblesManagerOptional)89     public ExpandableNotificationRowController(
90             ExpandableNotificationRow view,
91             NotificationListContainer listContainer,
92             ActivatableNotificationViewController activatableNotificationViewController,
93             NotificationMediaManager mediaManager,
94             PluginManager pluginManager,
95             SystemClock clock,
96             @AppName String appName,
97             @NotificationKey String notificationKey,
98             KeyguardBypassController keyguardBypassController,
99             GroupMembershipManager groupMembershipManager,
100             GroupExpansionManager groupExpansionManager,
101             RowContentBindStage rowContentBindStage,
102             NotificationLogger notificationLogger,
103             HeadsUpManager headsUpManager,
104             ExpandableNotificationRow.OnExpandClickListener onExpandClickListener,
105             StatusBarStateController statusBarStateController,
106             NotificationGutsManager notificationGutsManager,
107             @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
108             OnUserInteractionCallback onUserInteractionCallback,
109             FalsingManager falsingManager,
110             FalsingCollector falsingCollector,
111             PeopleNotificationIdentifier peopleNotificationIdentifier,
112             Optional<BubblesManager> bubblesManagerOptional) {
113         mView = view;
114         mListContainer = listContainer;
115         mActivatableNotificationViewController = activatableNotificationViewController;
116         mMediaManager = mediaManager;
117         mPluginManager = pluginManager;
118         mClock = clock;
119         mAppName = appName;
120         mNotificationKey = notificationKey;
121         mKeyguardBypassController = keyguardBypassController;
122         mGroupMembershipManager = groupMembershipManager;
123         mGroupExpansionManager = groupExpansionManager;
124         mRowContentBindStage = rowContentBindStage;
125         mNotificationLogger = notificationLogger;
126         mHeadsUpManager = headsUpManager;
127         mOnExpandClickListener = onExpandClickListener;
128         mStatusBarStateController = statusBarStateController;
129         mNotificationGutsManager = notificationGutsManager;
130         mOnUserInteractionCallback = onUserInteractionCallback;
131         mFalsingManager = falsingManager;
132         mOnFeedbackClickListener = mNotificationGutsManager::openGuts;
133         mAllowLongPress = allowLongPress;
134         mFalsingCollector = falsingCollector;
135         mPeopleNotificationIdentifier = peopleNotificationIdentifier;
136         mBubblesManagerOptional = bubblesManagerOptional;
137     }
138 
139     /**
140      * Initialize the controller.
141      */
init(NotificationEntry entry)142     public void init(NotificationEntry entry) {
143         mActivatableNotificationViewController.init();
144         mView.initialize(
145                 entry,
146                 mAppName,
147                 mNotificationKey,
148                 mExpansionLogger,
149                 mKeyguardBypassController,
150                 mGroupMembershipManager,
151                 mGroupExpansionManager,
152                 mHeadsUpManager,
153                 mRowContentBindStage,
154                 mOnExpandClickListener,
155                 mMediaManager,
156                 mOnFeedbackClickListener,
157                 mFalsingManager,
158                 mFalsingCollector,
159                 mStatusBarStateController,
160                 mPeopleNotificationIdentifier,
161                 mOnUserInteractionCallback,
162                 mBubblesManagerOptional,
163                 mNotificationGutsManager
164         );
165         mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
166         if (mAllowLongPress) {
167             mView.setLongPressListener((v, x, y, item) -> {
168                 if (mView.isSummaryWithChildren()) {
169                     mView.expandNotification();
170                     return true;
171                 }
172                 return mNotificationGutsManager.openGuts(v, x, y, item);
173             });
174         }
175         if (ENABLE_REMOTE_INPUT) {
176             mView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
177         }
178 
179         mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
180             @Override
181             public void onViewAttachedToWindow(View v) {
182                 mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
183                 mPluginManager.addPluginListener(mView,
184                         NotificationMenuRowPlugin.class, false /* Allow multiple */);
185                 mView.setOnKeyguard(mStatusBarStateController.getState() == KEYGUARD);
186                 mStatusBarStateController.addCallback(mStatusBarStateListener);
187             }
188 
189             @Override
190             public void onViewDetachedFromWindow(View v) {
191                 mPluginManager.removePluginListener(mView);
192                 mStatusBarStateController.removeCallback(mStatusBarStateListener);
193             }
194         });
195     }
196 
197     private final StatusBarStateController.StateListener mStatusBarStateListener =
198             new StatusBarStateController.StateListener() {
199                 @Override
200                 public void onStateChanged(int newState) {
201                     mView.setOnKeyguard(newState == KEYGUARD);
202                 }
203             };
204 
logNotificationExpansion(String key, boolean userAction, boolean expanded)205     private void logNotificationExpansion(String key, boolean userAction, boolean expanded) {
206         mNotificationLogger.onExpansionChanged(key, userAction, expanded);
207     }
208 
209     @Override
210     @NonNull
getNodeLabel()211     public String getNodeLabel() {
212         return mView.getEntry().getKey();
213     }
214 
215     @Override
216     @NonNull
getView()217     public View getView() {
218         return mView;
219     }
220 
221     @Override
getChildAt(int index)222     public View getChildAt(int index) {
223         return mView.getChildNotificationAt(index);
224     }
225 
226     @Override
addChildAt(NodeController child, int index)227     public void addChildAt(NodeController child, int index) {
228         ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
229 
230         mView.addChildNotification((ExpandableNotificationRow) child.getView());
231         mListContainer.notifyGroupChildAdded(childView);
232     }
233 
234     @Override
moveChildTo(NodeController child, int index)235     public void moveChildTo(NodeController child, int index) {
236         ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
237         mView.removeChildNotification(childView);
238         mView.addChildNotification(childView, index);
239     }
240 
241     @Override
removeChild(NodeController child, boolean isTransfer)242     public void removeChild(NodeController child, boolean isTransfer) {
243         ExpandableNotificationRow childView = (ExpandableNotificationRow) child.getView();
244 
245         mView.removeChildNotification(childView);
246         if (!isTransfer) {
247             mListContainer.notifyGroupChildRemoved(childView, mView);
248         }
249     }
250 
251     @Override
getChildCount()252     public int getChildCount() {
253         final List<ExpandableNotificationRow> mChildren = mView.getAttachedChildren();
254         return mChildren != null ? mChildren.size() : 0;
255     }
256 }
257