blob: a87dca45bf759eac105ac49d3f209c54f48b79e5 [file] [log] [blame]
Jason Monk297c04e2018-08-23 17:16:59 -04001/*
2 * Copyright (C) 2018 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
15package com.android.systemui.statusbar.phone;
16
Jason Monk297c04e2018-08-23 17:16:59 -040017import static com.android.systemui.SysUiServiceProvider.getComponent;
18import static com.android.systemui.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED;
19import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
20import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
21import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
Jason Monk297c04e2018-08-23 17:16:59 -040022
Ned Burns1dd6b402019-01-02 15:25:23 -050023import android.annotation.Nullable;
Jason Monk297c04e2018-08-23 17:16:59 -040024import android.app.KeyguardManager;
Jason Monk297c04e2018-08-23 17:16:59 -040025import android.content.Context;
Jason Monk297c04e2018-08-23 17:16:59 -040026import android.content.pm.PackageManager;
Jason Monk297c04e2018-08-23 17:16:59 -040027import android.os.RemoteException;
28import android.os.ServiceManager;
Jason Monk297c04e2018-08-23 17:16:59 -040029import android.service.notification.StatusBarNotification;
30import android.service.vr.IVrManager;
31import android.service.vr.IVrStateCallbacks;
Jason Monk297c04e2018-08-23 17:16:59 -040032import android.util.Log;
33import android.util.Slog;
Jason Monk297c04e2018-08-23 17:16:59 -040034import android.view.View;
35import android.view.ViewGroup;
36import android.view.accessibility.AccessibilityManager;
37import android.widget.TextView;
38
39import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
40import com.android.internal.statusbar.IStatusBarService;
Gus Prevasca1b6f72018-12-28 10:53:11 -050041import com.android.internal.statusbar.NotificationVisibility;
Selim Cinek9ba78f12018-12-07 14:37:33 -080042import com.android.internal.widget.MessagingGroup;
43import com.android.internal.widget.MessagingMessage;
Lucas Dupinc12fad32019-05-14 20:59:17 +000044import com.android.keyguard.KeyguardUpdateMonitor;
Jason Monk297c04e2018-08-23 17:16:59 -040045import com.android.systemui.Dependency;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050046import com.android.systemui.ForegroundServiceNotificationListener;
Jason Monk297c04e2018-08-23 17:16:59 -040047import com.android.systemui.InitController;
48import com.android.systemui.R;
Jason Monk297c04e2018-08-23 17:16:59 -040049import com.android.systemui.plugins.ActivityStarter;
50import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Beverly8fdb5332019-02-04 14:29:49 -050051import com.android.systemui.plugins.statusbar.StatusBarStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040052import com.android.systemui.statusbar.CommandQueue;
53import com.android.systemui.statusbar.NotificationLockscreenUserManager;
54import com.android.systemui.statusbar.NotificationMediaManager;
55import com.android.systemui.statusbar.NotificationPresenter;
56import com.android.systemui.statusbar.NotificationRemoteInputManager;
Jason Monk297c04e2018-08-23 17:16:59 -040057import com.android.systemui.statusbar.NotificationViewHierarchyManager;
Jason Monk297c04e2018-08-23 17:16:59 -040058import com.android.systemui.statusbar.StatusBarState;
Beverly8fdb5332019-02-04 14:29:49 -050059import com.android.systemui.statusbar.SysuiStatusBarStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040060import com.android.systemui.statusbar.notification.AboveShelfObserver;
61import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
Gus Prevasb43dc652018-12-20 13:11:45 -050062import com.android.systemui.statusbar.notification.NotificationAlertingManager;
Gus Prevas26bc59b2018-12-19 11:26:39 -050063import com.android.systemui.statusbar.notification.NotificationEntryListener;
Jason Monk297c04e2018-08-23 17:16:59 -040064import com.android.systemui.statusbar.notification.NotificationEntryManager;
Gus Prevasec9e1f02018-12-18 15:28:12 -050065import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
Gus Prevas5b9098dc2018-12-21 17:07:15 -050066import com.android.systemui.statusbar.notification.VisualStabilityManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050067import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Ned Burnsc5864672019-02-20 12:57:29 -050068import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
Jason Monk297c04e2018-08-23 17:16:59 -040069import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
70import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
71import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
72import com.android.systemui.statusbar.notification.row.NotificationGutsManager.OnSettingsClickListener;
73import com.android.systemui.statusbar.notification.row.NotificationInfo.CheckSaveListener;
74import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
Selim Cinek9ba78f12018-12-07 14:37:33 -080075import com.android.systemui.statusbar.policy.ConfigurationController;
Jason Monk297c04e2018-08-23 17:16:59 -040076import com.android.systemui.statusbar.policy.KeyguardMonitor;
Jason Monk297c04e2018-08-23 17:16:59 -040077
Selim Cinekab9c7b22018-12-11 18:15:47 -080078import java.util.ArrayList;
79
Selim Cinek9ba78f12018-12-07 14:37:33 -080080public class StatusBarNotificationPresenter implements NotificationPresenter,
Ned Burnsc5864672019-02-20 12:57:29 -050081 ConfigurationController.ConfigurationListener,
82 NotificationRowBinderImpl.BindRowCallback {
Jason Monk297c04e2018-08-23 17:16:59 -040083
84 private final LockscreenGestureLogger mLockscreenGestureLogger =
85 Dependency.get(LockscreenGestureLogger.class);
86
87 private static final String TAG = "StatusBarNotificationPresenter";
88
89 private final ShadeController mShadeController = Dependency.get(ShadeController.class);
90 private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
Jason Monk297c04e2018-08-23 17:16:59 -040091 private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
92 private final NotificationViewHierarchyManager mViewHierarchyManager =
93 Dependency.get(NotificationViewHierarchyManager.class);
94 private final NotificationLockscreenUserManager mLockscreenUserManager =
95 Dependency.get(NotificationLockscreenUserManager.class);
Beverly8fdb5332019-02-04 14:29:49 -050096 private final SysuiStatusBarStateController mStatusBarStateController =
97 (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
Jason Monk297c04e2018-08-23 17:16:59 -040098 private final NotificationEntryManager mEntryManager =
99 Dependency.get(NotificationEntryManager.class);
Gus Prevasec9e1f02018-12-18 15:28:12 -0500100 private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider =
101 Dependency.get(NotificationInterruptionStateProvider.class);
Jason Monk297c04e2018-08-23 17:16:59 -0400102 private final NotificationMediaManager mMediaManager =
103 Dependency.get(NotificationMediaManager.class);
Gus Prevas5b9098dc2018-12-21 17:07:15 -0500104 private final VisualStabilityManager mVisualStabilityManager =
105 Dependency.get(VisualStabilityManager.class);
Ned Burns1016d962019-01-08 16:52:39 -0500106 private final NotificationGutsManager mGutsManager =
107 Dependency.get(NotificationGutsManager.class);
Jason Monk297c04e2018-08-23 17:16:59 -0400108
109 private final NotificationPanelView mNotificationPanel;
110 private final HeadsUpManagerPhone mHeadsUpManager;
111 private final AboveShelfObserver mAboveShelfObserver;
112 private final DozeScrimController mDozeScrimController;
113 private final ScrimController mScrimController;
114 private final Context mContext;
115 private final CommandQueue mCommandQueue;
116
117 private final AccessibilityManager mAccessibilityManager;
Jason Monk297c04e2018-08-23 17:16:59 -0400118 private final KeyguardManager mKeyguardManager;
119 private final ActivityLaunchAnimator mActivityLaunchAnimator;
Gus Prevas0b8174a2018-12-07 11:35:53 -0500120 private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
Jason Monk297c04e2018-08-23 17:16:59 -0400121 private final int mMaxAllowedKeyguardNotifications;
122 private final IStatusBarService mBarService;
Lucas Dupinc12fad32019-05-14 20:59:17 +0000123 private boolean mReinflateNotificationsOnUserSwitched;
124 private boolean mDispatchUiModeChangeOnUserSwitched;
Jason Monk297c04e2018-08-23 17:16:59 -0400125 private final UnlockMethodCache mUnlockMethodCache;
126 private TextView mNotificationPanelDebugText;
127
128 protected boolean mVrMode;
129 private int mMaxKeyguardNotifications;
Jason Monk297c04e2018-08-23 17:16:59 -0400130
Gus Prevas21437b32018-12-05 10:36:13 -0500131 public StatusBarNotificationPresenter(Context context,
132 NotificationPanelView panel,
133 HeadsUpManagerPhone headsUp,
134 StatusBarWindowView statusBarWindow,
135 ViewGroup stackScroller,
136 DozeScrimController dozeScrimController,
Jason Monk297c04e2018-08-23 17:16:59 -0400137 ScrimController scrimController,
Gus Prevas0b8174a2018-12-07 11:35:53 -0500138 ActivityLaunchAnimator activityLaunchAnimator,
Gus Prevasb43dc652018-12-20 13:11:45 -0500139 StatusBarKeyguardViewManager statusBarKeyguardViewManager,
Ned Burnsc5864672019-02-20 12:57:29 -0500140 NotificationAlertingManager notificationAlertingManager,
141 NotificationRowBinderImpl notificationRowBinder) {
Jason Monk297c04e2018-08-23 17:16:59 -0400142 mContext = context;
143 mNotificationPanel = panel;
144 mHeadsUpManager = headsUp;
145 mCommandQueue = getComponent(context, CommandQueue.class);
146 mAboveShelfObserver = new AboveShelfObserver(stackScroller);
Gus Prevas21437b32018-12-05 10:36:13 -0500147 mActivityLaunchAnimator = activityLaunchAnimator;
Gus Prevas0b8174a2018-12-07 11:35:53 -0500148 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
Jason Monk297c04e2018-08-23 17:16:59 -0400149 mAboveShelfObserver.setListener(statusBarWindow.findViewById(
150 R.id.notification_container_parent));
151 mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
152 mDozeScrimController = dozeScrimController;
153 mScrimController = scrimController;
154 mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
Jason Monk297c04e2018-08-23 17:16:59 -0400155 mKeyguardManager = context.getSystemService(KeyguardManager.class);
156 mMaxAllowedKeyguardNotifications = context.getResources().getInteger(
157 R.integer.keyguard_max_notification_count);
158 mBarService = IStatusBarService.Stub.asInterface(
159 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
Jason Monk297c04e2018-08-23 17:16:59 -0400160
161 if (MULTIUSER_DEBUG) {
162 mNotificationPanelDebugText = mNotificationPanel.findViewById(R.id.header_debug_info);
163 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
164 }
165
166 IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
167 Context.VR_SERVICE));
168 if (vrManager != null) {
169 try {
170 vrManager.registerListener(mVrStateCallbacks);
171 } catch (RemoteException e) {
172 Slog.e(TAG, "Failed to register VR mode state listener: " + e);
173 }
174 }
Gus Prevas21437b32018-12-05 10:36:13 -0500175 NotificationRemoteInputManager remoteInputManager =
176 Dependency.get(NotificationRemoteInputManager.class);
177 remoteInputManager.setUpWithCallback(
Jason Monk297c04e2018-08-23 17:16:59 -0400178 Dependency.get(NotificationRemoteInputManager.Callback.class),
179 mNotificationPanel.createRemoteInputDelegate());
Gus Prevas21437b32018-12-05 10:36:13 -0500180 remoteInputManager.getController().addCallback(
Jason Monk297c04e2018-08-23 17:16:59 -0400181 Dependency.get(StatusBarWindowController.class));
182
183 NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
184 Dependency.get(InitController.class).addPostInitTask(() -> {
Gus Prevas26bc59b2018-12-19 11:26:39 -0500185 NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
186 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -0500187 public void onNotificationAdded(NotificationEntry entry) {
Gus Prevas26bc59b2018-12-19 11:26:39 -0500188 // Recalculate the position of the sliding windows and the titles.
189 mShadeController.updateAreThereNotifications();
190 }
191
192 @Override
Mady Mellor0ad5b9d2019-01-08 14:59:55 -0800193 public void onPostEntryUpdated(NotificationEntry entry) {
Gus Prevas26bc59b2018-12-19 11:26:39 -0500194 mShadeController.updateAreThereNotifications();
195 }
196
197 @Override
Gus Prevas772e5322018-12-21 16:22:16 -0500198 public void onEntryRemoved(
Ned Burnsf81c4c42019-01-07 14:10:43 -0500199 @Nullable NotificationEntry entry,
Gus Prevasca1b6f72018-12-28 10:53:11 -0500200 NotificationVisibility visibility,
Gus Prevas772e5322018-12-21 16:22:16 -0500201 boolean removedByUser) {
Ned Burnsef2ef6c2019-01-02 16:48:08 -0500202 StatusBarNotificationPresenter.this.onNotificationRemoved(
203 entry.key, entry.notification);
Gus Prevasdca2be52018-12-21 11:25:10 -0500204 if (removedByUser) {
205 maybeEndAmbientPulse();
206 }
Gus Prevas26bc59b2018-12-19 11:26:39 -0500207 }
208 };
209
Jason Monk297c04e2018-08-23 17:16:59 -0400210 mViewHierarchyManager.setUpWithPresenter(this, notifListContainer);
Gus Prevas8621bd22018-12-20 15:04:25 -0500211 mEntryManager.setUpWithPresenter(this, notifListContainer, mHeadsUpManager);
212 mEntryManager.addNotificationEntryListener(notificationEntryListener);
Gus Prevas5c84abb2018-12-28 16:41:49 -0500213 mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
Ned Burns1016d962019-01-08 16:52:39 -0500214 mEntryManager.addNotificationLifetimeExtender(mGutsManager);
Gus Prevas5c84abb2018-12-28 16:41:49 -0500215 mEntryManager.addNotificationLifetimeExtenders(
216 remoteInputManager.getLifetimeExtenders());
Ned Burnsc5864672019-02-20 12:57:29 -0500217 notificationRowBinder.setUpWithPresenter(this, notifListContainer, mHeadsUpManager,
Gus Prevas8ba88a82018-12-18 11:13:44 -0500218 mEntryManager, this);
Gus Prevasec9e1f02018-12-18 15:28:12 -0500219 mNotificationInterruptionStateProvider.setUpWithPresenter(
220 this, mHeadsUpManager, this::canHeadsUp);
Jason Monk297c04e2018-08-23 17:16:59 -0400221 mLockscreenUserManager.setUpWithPresenter(this);
222 mMediaManager.setUpWithPresenter(this);
Gus Prevas5b9098dc2018-12-21 17:07:15 -0500223 mVisualStabilityManager.setUpWithPresenter(this);
Ned Burns1016d962019-01-08 16:52:39 -0500224 mGutsManager.setUpWithPresenter(this,
Jason Monk297c04e2018-08-23 17:16:59 -0400225 notifListContainer, mCheckSaveListener, mOnSettingsClickListener);
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500226 // ForegroundServiceControllerListener adds its listener in its constructor
227 // but we need to request it here in order for it to be instantiated.
228 // TODO: figure out how to do this correctly once Dependency.get() is gone.
229 Dependency.get(ForegroundServiceNotificationListener.class);
Jason Monk297c04e2018-08-23 17:16:59 -0400230
231 onUserSwitched(mLockscreenUserManager.getCurrentUserId());
232 });
Selim Cinek9ba78f12018-12-07 14:37:33 -0800233 Dependency.get(ConfigurationController.class).addCallback(this);
Gus Prevasb43dc652018-12-20 13:11:45 -0500234
235 notificationAlertingManager.setHeadsUpManager(mHeadsUpManager);
Jason Monk297c04e2018-08-23 17:16:59 -0400236 }
237
Selim Cinek9ba78f12018-12-07 14:37:33 -0800238 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400239 public void onDensityOrFontScaleChanged() {
Selim Cinek9ba78f12018-12-07 14:37:33 -0800240 MessagingMessage.dropCache();
241 MessagingGroup.dropCache();
Lucas Dupinc12fad32019-05-14 20:59:17 +0000242 if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
243 updateNotificationsOnDensityOrFontScaleChanged();
244 } else {
245 mReinflateNotificationsOnUserSwitched = true;
246 }
Jason Monk297c04e2018-08-23 17:16:59 -0400247 }
248
249 @Override
Selim Cinekab9c7b22018-12-11 18:15:47 -0800250 public void onUiModeChanged() {
Lucas Dupinc12fad32019-05-14 20:59:17 +0000251 if (!KeyguardUpdateMonitor.getInstance(mContext).isSwitchingUser()) {
252 updateNotificationOnUiModeChanged();
253 } else {
254 mDispatchUiModeChangeOnUserSwitched = true;
255 }
Selim Cinekab9c7b22018-12-11 18:15:47 -0800256 }
257
Selim Cinekdd26a7e2019-02-11 18:42:55 -0800258 @Override
259 public void onOverlayChanged() {
260 onDensityOrFontScaleChanged();
261 }
262
Selim Cinekab9c7b22018-12-11 18:15:47 -0800263 private void updateNotificationOnUiModeChanged() {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500264 ArrayList<NotificationEntry> userNotifications
Selim Cinekab9c7b22018-12-11 18:15:47 -0800265 = mEntryManager.getNotificationData().getNotificationsForCurrentUser();
266 for (int i = 0; i < userNotifications.size(); i++) {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500267 NotificationEntry entry = userNotifications.get(i);
Selim Cinekab9c7b22018-12-11 18:15:47 -0800268 ExpandableNotificationRow row = entry.getRow();
269 if (row != null) {
270 row.onUiModeChanged();
271 }
272 }
273 }
274
Ned Burns1016d962019-01-08 16:52:39 -0500275 private void updateNotificationsOnDensityOrFontScaleChanged() {
276 ArrayList<NotificationEntry> userNotifications =
277 mEntryManager.getNotificationData().getNotificationsForCurrentUser();
278 for (int i = 0; i < userNotifications.size(); i++) {
279 NotificationEntry entry = userNotifications.get(i);
280 entry.onDensityOrFontScaleChanged();
281 boolean exposedGuts = entry.areGutsExposed();
282 if (exposedGuts) {
283 mGutsManager.onDensityOrFontScaleChanged(entry);
284 }
285 }
286 }
287
Selim Cinekab9c7b22018-12-11 18:15:47 -0800288 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400289 public boolean isCollapsing() {
290 return mNotificationPanel.isCollapsing()
291 || mActivityLaunchAnimator.isAnimationPending()
292 || mActivityLaunchAnimator.isAnimationRunning();
293 }
294
Gus Prevasdca2be52018-12-21 11:25:10 -0500295 private void maybeEndAmbientPulse() {
Jason Monk297c04e2018-08-23 17:16:59 -0400296 if (mNotificationPanel.hasPulsingNotifications() &&
Selim Cinekc3fec682019-06-06 18:11:07 -0700297 !mHeadsUpManager.hasNotifications()) {
Jason Monk297c04e2018-08-23 17:16:59 -0400298 // We were showing a pulse for a notification, but no notifications are pulsing anymore.
299 // Finish the pulse.
300 mDozeScrimController.pulseOutNow();
301 }
302 }
303
304 @Override
305 public void updateNotificationViews() {
306 // The function updateRowStates depends on both of these being non-null, so check them here.
307 // We may be called before they are set from DeviceProvisionedController's callback.
308 if (mScrimController == null) return;
309
310 // Do not modify the notifications during collapse.
311 if (isCollapsing()) {
312 mShadeController.addPostCollapseAction(this::updateNotificationViews);
313 return;
314 }
315
316 mViewHierarchyManager.updateNotificationViews();
317
318 mNotificationPanel.updateNotificationViews();
319 }
320
Jason Monk297c04e2018-08-23 17:16:59 -0400321 public void onNotificationRemoved(String key, StatusBarNotification old) {
322 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
323
324 if (old != null) {
325 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
326 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
327 if (mStatusBarStateController.getState() == StatusBarState.SHADE) {
328 mCommandQueue.animateCollapsePanels();
329 } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
330 && !isCollapsing()) {
331 mShadeController.goToKeyguard();
332 }
333 }
334 }
335 mShadeController.updateAreThereNotifications();
336 }
337
338 public boolean hasActiveNotifications() {
339 return !mEntryManager.getNotificationData().getActiveNotifications().isEmpty();
340 }
341
Ned Burnsf81c4c42019-01-07 14:10:43 -0500342 public boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn) {
Jason Monk297c04e2018-08-23 17:16:59 -0400343 if (mShadeController.isOccluded()) {
344 boolean devicePublic = mLockscreenUserManager.
345 isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
346 boolean userPublic = devicePublic
347 || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
348 boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
349 if (userPublic && needsRedaction) {
Selim Cinekc3fec682019-06-06 18:11:07 -0700350 // TODO(b/135046837): we can probably relax this with dynamic privacy
Jason Monk297c04e2018-08-23 17:16:59 -0400351 return false;
352 }
353 }
354
355 if (!mCommandQueue.panelsEnabled()) {
356 if (DEBUG) {
357 Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
358 }
359 return false;
360 }
361
362 if (sbn.getNotification().fullScreenIntent != null) {
363 if (mAccessibilityManager.isTouchExplorationEnabled()) {
364 if (DEBUG) Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
365 return false;
366 } else {
367 // we only allow head-up on the lockscreen if it doesn't have a fullscreen intent
368 return !mKeyguardMonitor.isShowing()
369 || mShadeController.isOccluded();
370 }
371 }
372 return true;
373 }
374
375 @Override
376 public void onUserSwitched(int newUserId) {
377 // Begin old BaseStatusBar.userSwitched
378 mHeadsUpManager.setUser(newUserId);
379 // End old BaseStatusBar.userSwitched
380 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
381 mCommandQueue.animateCollapsePanels();
Lucas Dupinc12fad32019-05-14 20:59:17 +0000382 if (mReinflateNotificationsOnUserSwitched) {
383 updateNotificationsOnDensityOrFontScaleChanged();
384 mReinflateNotificationsOnUserSwitched = false;
385 }
386 if (mDispatchUiModeChangeOnUserSwitched) {
387 updateNotificationOnUiModeChanged();
388 mDispatchUiModeChangeOnUserSwitched = false;
389 }
Jason Monk297c04e2018-08-23 17:16:59 -0400390 updateNotificationViews();
391 mMediaManager.clearCurrentMediaNotification();
392 mShadeController.setLockscreenUser(newUserId);
393 updateMediaMetaData(true, false);
394 }
395
396 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -0500397 public void onBindRow(NotificationEntry entry, PackageManager pmUser,
Jason Monk297c04e2018-08-23 17:16:59 -0400398 StatusBarNotification sbn, ExpandableNotificationRow row) {
399 row.setAboveShelfChangedListener(mAboveShelfObserver);
400 row.setSecureStateProvider(mUnlockMethodCache::canSkipBouncer);
401 }
402
403 @Override
404 public boolean isPresenterFullyCollapsed() {
405 return mNotificationPanel.isFullyCollapsed();
406 }
407
408 @Override
409 public void onActivated(ActivatableNotificationView view) {
410 onActivated();
411 if (view != null) mNotificationPanel.setActivatedChild(view);
412 }
413
414 public void onActivated() {
415 mLockscreenGestureLogger.write(
416 MetricsEvent.ACTION_LS_NOTE,
417 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
418 mNotificationPanel.showTransientIndication(R.string.notification_tap_again);
419 ActivatableNotificationView previousView = mNotificationPanel.getActivatedChild();
420 if (previousView != null) {
421 previousView.makeInactive(true /* animate */);
422 }
423 }
424
425 @Override
426 public void onActivationReset(ActivatableNotificationView view) {
427 if (view == mNotificationPanel.getActivatedChild()) {
428 mNotificationPanel.setActivatedChild(null);
429 mShadeController.onActivationReset();
430 }
431 }
432
433 @Override
434 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
435 mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
436 }
437
438 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400439 public int getMaxNotificationsWhileLocked(boolean recompute) {
440 if (recompute) {
441 mMaxKeyguardNotifications = Math.max(1,
442 mNotificationPanel.computeMaxKeyguardNotifications(
443 mMaxAllowedKeyguardNotifications));
444 return mMaxKeyguardNotifications;
445 }
446 return mMaxKeyguardNotifications;
447 }
448
449 @Override
450 public void onUpdateRowStates() {
451 mNotificationPanel.onUpdateRowStates();
452 }
453
454 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -0500455 public void onExpandClicked(NotificationEntry clickedEntry, boolean nowExpanded) {
Jason Monk297c04e2018-08-23 17:16:59 -0400456 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
457 if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD && nowExpanded) {
Evan Laird94492852018-10-25 13:43:01 -0400458 mShadeController.goToLockedShade(clickedEntry.getRow());
Jason Monk297c04e2018-08-23 17:16:59 -0400459 }
460 }
461
462 @Override
463 public boolean isDeviceInVrMode() {
464 return mVrMode;
465 }
466
Gus Prevas0b8174a2018-12-07 11:35:53 -0500467 @Override
468 public boolean isPresenterLocked() {
469 return mStatusBarKeyguardViewManager.isShowing()
470 && mStatusBarKeyguardViewManager.isSecure();
471 }
472
Jason Monk297c04e2018-08-23 17:16:59 -0400473 private void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
474 mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
475 mActivityStarter.dismissKeyguardThenExecute(dismissAction, null,
476 true /* afterKeyguardGone */);
477 }
478
Jason Monk297c04e2018-08-23 17:16:59 -0400479 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
480 @Override
481 public void onVrStateChanged(boolean enabled) {
482 mVrMode = enabled;
483 }
484 };
485
486 private final CheckSaveListener mCheckSaveListener = new CheckSaveListener() {
487 @Override
488 public void checkSave(Runnable saveImportance, StatusBarNotification sbn) {
Jason Monk297c04e2018-08-23 17:16:59 -0400489 // If the user has security enabled, show challenge if the setting is changed.
490 if (mLockscreenUserManager.isLockscreenPublicMode(sbn.getUser().getIdentifier())
491 && mKeyguardManager.isKeyguardLocked()) {
492 onLockedNotificationImportanceChange(() -> {
493 saveImportance.run();
494 return true;
495 });
496 } else {
497 saveImportance.run();
498 }
499 }
500 };
501
502 private final OnSettingsClickListener mOnSettingsClickListener = new OnSettingsClickListener() {
503 @Override
504 public void onSettingsClick(String key) {
505 try {
506 mBarService.onNotificationSettingsViewed(key);
507 } catch (RemoteException e) {
508 // if we're here we're dead
509 }
510 }
511 };
512}