blob: aecbb9097c7a9f61318cc2750a8a0c94e79ebd61 [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.statusbar.phone.StatusBar.CLOSE_PANEL_WHEN_EMPTIED;
18import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
19import static com.android.systemui.statusbar.phone.StatusBar.MULTIUSER_DEBUG;
20import static com.android.systemui.statusbar.phone.StatusBar.SPEW;
Jason Monk297c04e2018-08-23 17:16:59 -040021
Ned Burns1dd6b402019-01-02 15:25:23 -050022import android.annotation.Nullable;
Jason Monk297c04e2018-08-23 17:16:59 -040023import android.app.KeyguardManager;
Jason Monk297c04e2018-08-23 17:16:59 -040024import android.content.Context;
Jason Monk297c04e2018-08-23 17:16:59 -040025import android.os.RemoteException;
26import android.os.ServiceManager;
Jason Monk297c04e2018-08-23 17:16:59 -040027import android.service.notification.StatusBarNotification;
28import android.service.vr.IVrManager;
29import android.service.vr.IVrStateCallbacks;
Jason Monk297c04e2018-08-23 17:16:59 -040030import android.util.Log;
31import android.util.Slog;
Jason Monk297c04e2018-08-23 17:16:59 -040032import android.view.View;
33import android.view.ViewGroup;
34import android.view.accessibility.AccessibilityManager;
35import android.widget.TextView;
36
37import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
38import com.android.internal.statusbar.IStatusBarService;
Gus Prevasca1b6f72018-12-28 10:53:11 -050039import com.android.internal.statusbar.NotificationVisibility;
Selim Cinek9ba78f12018-12-07 14:37:33 -080040import com.android.internal.widget.MessagingGroup;
41import com.android.internal.widget.MessagingMessage;
Lucas Dupinc12fad32019-05-14 20:59:17 +000042import com.android.keyguard.KeyguardUpdateMonitor;
Jason Monk297c04e2018-08-23 17:16:59 -040043import com.android.systemui.Dependency;
Gus Prevaseb4e2e12018-12-28 14:57:59 -050044import com.android.systemui.ForegroundServiceNotificationListener;
Jason Monk297c04e2018-08-23 17:16:59 -040045import com.android.systemui.InitController;
46import com.android.systemui.R;
Jason Monk297c04e2018-08-23 17:16:59 -040047import com.android.systemui.plugins.ActivityStarter;
48import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Beverly8fdb5332019-02-04 14:29:49 -050049import com.android.systemui.plugins.statusbar.StatusBarStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040050import com.android.systemui.statusbar.CommandQueue;
Heemin Seog98df6972019-12-05 13:01:38 -080051import com.android.systemui.statusbar.KeyguardIndicationController;
Jason Monk297c04e2018-08-23 17:16:59 -040052import com.android.systemui.statusbar.NotificationLockscreenUserManager;
53import com.android.systemui.statusbar.NotificationMediaManager;
54import com.android.systemui.statusbar.NotificationPresenter;
55import com.android.systemui.statusbar.NotificationRemoteInputManager;
Jason Monk297c04e2018-08-23 17:16:59 -040056import com.android.systemui.statusbar.NotificationViewHierarchyManager;
Jason Monk297c04e2018-08-23 17:16:59 -040057import com.android.systemui.statusbar.StatusBarState;
Beverly8fdb5332019-02-04 14:29:49 -050058import com.android.systemui.statusbar.SysuiStatusBarStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040059import com.android.systemui.statusbar.notification.AboveShelfObserver;
60import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
Selim Cinek5454a0d2019-07-30 17:14:50 -070061import com.android.systemui.statusbar.notification.DynamicPrivacyController;
Gus Prevas26bc59b2018-12-19 11:26:39 -050062import com.android.systemui.statusbar.notification.NotificationEntryListener;
Jason Monk297c04e2018-08-23 17:16:59 -040063import com.android.systemui.statusbar.notification.NotificationEntryManager;
Gus Prevas5b9098dc2018-12-21 17:07:15 -050064import com.android.systemui.statusbar.notification.VisualStabilityManager;
Ned Burnsf81c4c42019-01-07 14:10:43 -050065import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Ned Burns012048d2020-01-08 19:57:30 -050066import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl;
Beverly Taid1e175c2020-03-10 16:37:04 +000067import com.android.systemui.statusbar.notification.interruption.NotificationInterruptStateProvider;
68import com.android.systemui.statusbar.notification.interruption.NotificationInterruptSuppressor;
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;
Lucas Dupinc8f16e82019-09-17 18:24:50 -040076import com.android.systemui.statusbar.policy.KeyguardStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040077
Evan Laird181de622019-10-24 09:53:02 -040078import java.util.List;
Selim Cinekab9c7b22018-12-11 18:15:47 -080079
Selim Cinek9ba78f12018-12-07 14:37:33 -080080public class StatusBarNotificationPresenter implements NotificationPresenter,
Ned Burnsc5864672019-02-20 12:57:29 -050081 ConfigurationController.ConfigurationListener,
Beverlyea2010c2019-11-04 09:55:29 -050082 NotificationRowBinderImpl.BindRowCallback,
83 CommandQueue.Callbacks {
Jason Monk297c04e2018-08-23 17:16:59 -040084
85 private final LockscreenGestureLogger mLockscreenGestureLogger =
86 Dependency.get(LockscreenGestureLogger.class);
87
88 private static final String TAG = "StatusBarNotificationPresenter";
89
Jason Monk297c04e2018-08-23 17:16:59 -040090 private final ActivityStarter mActivityStarter = Dependency.get(ActivityStarter.class);
Lucas Dupind236ee32019-10-08 15:33:59 -070091 private final KeyguardStateController mKeyguardStateController;
Jason Monk297c04e2018-08-23 17:16:59 -040092 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);
100 private final NotificationMediaManager mMediaManager =
101 Dependency.get(NotificationMediaManager.class);
Gus Prevas5b9098dc2018-12-21 17:07:15 -0500102 private final VisualStabilityManager mVisualStabilityManager =
103 Dependency.get(VisualStabilityManager.class);
Ned Burns1016d962019-01-08 16:52:39 -0500104 private final NotificationGutsManager mGutsManager =
105 Dependency.get(NotificationGutsManager.class);
Jason Monk297c04e2018-08-23 17:16:59 -0400106
Dave Mankoffaf8163f2020-01-08 14:24:35 -0500107 private final NotificationPanelViewController mNotificationPanel;
Jason Monk297c04e2018-08-23 17:16:59 -0400108 private final HeadsUpManagerPhone mHeadsUpManager;
109 private final AboveShelfObserver mAboveShelfObserver;
110 private final DozeScrimController mDozeScrimController;
111 private final ScrimController mScrimController;
112 private final Context mContext;
Heemin Seog98df6972019-12-05 13:01:38 -0800113 private final KeyguardIndicationController mKeyguardIndicationController;
Heemin Seogbd9bcbf2019-12-04 17:07:32 -0800114 private final StatusBar mStatusBar;
Heemin Seogba6337f2019-12-10 15:34:37 -0800115 private final ShadeController mShadeController;
Jason Monk297c04e2018-08-23 17:16:59 -0400116 private final CommandQueue mCommandQueue;
117
118 private final AccessibilityManager mAccessibilityManager;
Jason Monk297c04e2018-08-23 17:16:59 -0400119 private final KeyguardManager mKeyguardManager;
120 private final ActivityLaunchAnimator mActivityLaunchAnimator;
121 private final int mMaxAllowedKeyguardNotifications;
122 private final IStatusBarService mBarService;
Selim Cinek5454a0d2019-07-30 17:14:50 -0700123 private final DynamicPrivacyController mDynamicPrivacyController;
Lucas Dupinc12fad32019-05-14 20:59:17 +0000124 private boolean mReinflateNotificationsOnUserSwitched;
125 private boolean mDispatchUiModeChangeOnUserSwitched;
Jason Monk297c04e2018-08-23 17:16:59 -0400126 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,
Dave Mankoffaf8163f2020-01-08 14:24:35 -0500132 NotificationPanelViewController panel,
Gus Prevas21437b32018-12-05 10:36:13 -0500133 HeadsUpManagerPhone headsUp,
wilsonshihe8321942019-10-18 18:39:46 +0800134 NotificationShadeWindowView statusBarWindow,
Gus Prevas21437b32018-12-05 10:36:13 -0500135 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,
Selim Cinek5454a0d2019-07-30 17:14:50 -0700139 DynamicPrivacyController dynamicPrivacyController,
Dave Mankoffbcaca8a2019-10-31 18:04:08 -0400140 KeyguardStateController keyguardStateController,
Heemin Seog98df6972019-12-05 13:01:38 -0800141 KeyguardIndicationController keyguardIndicationController,
Heemin Seogbd9bcbf2019-12-04 17:07:32 -0800142 StatusBar statusBar,
Heemin Seogba6337f2019-12-10 15:34:37 -0800143 ShadeController shadeController,
Dave Mankoff71fca1a2019-12-19 14:16:32 -0500144 CommandQueue commandQueue,
Beverly Taid1e175c2020-03-10 16:37:04 +0000145 InitController initController,
146 NotificationInterruptStateProvider notificationInterruptStateProvider) {
Jason Monk297c04e2018-08-23 17:16:59 -0400147 mContext = context;
Lucas Dupind236ee32019-10-08 15:33:59 -0700148 mKeyguardStateController = keyguardStateController;
Jason Monk297c04e2018-08-23 17:16:59 -0400149 mNotificationPanel = panel;
150 mHeadsUpManager = headsUp;
Selim Cinek5454a0d2019-07-30 17:14:50 -0700151 mDynamicPrivacyController = dynamicPrivacyController;
Heemin Seog98df6972019-12-05 13:01:38 -0800152 mKeyguardIndicationController = keyguardIndicationController;
Heemin Seogbd9bcbf2019-12-04 17:07:32 -0800153 // TODO: use KeyguardStateController#isOccluded to remove this dependency
154 mStatusBar = statusBar;
Heemin Seogba6337f2019-12-10 15:34:37 -0800155 mShadeController = shadeController;
Dave Mankoffbcaca8a2019-10-31 18:04:08 -0400156 mCommandQueue = commandQueue;
Jason Monk297c04e2018-08-23 17:16:59 -0400157 mAboveShelfObserver = new AboveShelfObserver(stackScroller);
Gus Prevas21437b32018-12-05 10:36:13 -0500158 mActivityLaunchAnimator = activityLaunchAnimator;
Jason Monk297c04e2018-08-23 17:16:59 -0400159 mAboveShelfObserver.setListener(statusBarWindow.findViewById(
160 R.id.notification_container_parent));
161 mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
162 mDozeScrimController = dozeScrimController;
163 mScrimController = scrimController;
Jason Monk297c04e2018-08-23 17:16:59 -0400164 mKeyguardManager = context.getSystemService(KeyguardManager.class);
165 mMaxAllowedKeyguardNotifications = context.getResources().getInteger(
166 R.integer.keyguard_max_notification_count);
167 mBarService = IStatusBarService.Stub.asInterface(
168 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
Jason Monk297c04e2018-08-23 17:16:59 -0400169
170 if (MULTIUSER_DEBUG) {
Dave Mankoffaf8163f2020-01-08 14:24:35 -0500171 mNotificationPanelDebugText = mNotificationPanel.getHeaderDebugInfo();
Jason Monk297c04e2018-08-23 17:16:59 -0400172 mNotificationPanelDebugText.setVisibility(View.VISIBLE);
173 }
174
175 IVrManager vrManager = IVrManager.Stub.asInterface(ServiceManager.getService(
176 Context.VR_SERVICE));
177 if (vrManager != null) {
178 try {
179 vrManager.registerListener(mVrStateCallbacks);
180 } catch (RemoteException e) {
181 Slog.e(TAG, "Failed to register VR mode state listener: " + e);
182 }
183 }
Gus Prevas21437b32018-12-05 10:36:13 -0500184 NotificationRemoteInputManager remoteInputManager =
185 Dependency.get(NotificationRemoteInputManager.class);
186 remoteInputManager.setUpWithCallback(
Jason Monk297c04e2018-08-23 17:16:59 -0400187 Dependency.get(NotificationRemoteInputManager.Callback.class),
188 mNotificationPanel.createRemoteInputDelegate());
Gus Prevas21437b32018-12-05 10:36:13 -0500189 remoteInputManager.getController().addCallback(
wilsonshihe8321942019-10-18 18:39:46 +0800190 Dependency.get(NotificationShadeWindowController.class));
Jason Monk297c04e2018-08-23 17:16:59 -0400191
192 NotificationListContainer notifListContainer = (NotificationListContainer) stackScroller;
Dave Mankoff71fca1a2019-12-19 14:16:32 -0500193 initController.addPostInitTask(() -> {
Gus Prevas26bc59b2018-12-19 11:26:39 -0500194 NotificationEntryListener notificationEntryListener = new NotificationEntryListener() {
195 @Override
Gus Prevas772e5322018-12-21 16:22:16 -0500196 public void onEntryRemoved(
Ned Burnsf81c4c42019-01-07 14:10:43 -0500197 @Nullable NotificationEntry entry,
Gus Prevasca1b6f72018-12-28 10:53:11 -0500198 NotificationVisibility visibility,
Julia Reynolds138111f2020-02-26 11:17:39 -0500199 boolean removedByUser,
200 int reason) {
Ned Burnsef2ef6c2019-01-02 16:48:08 -0500201 StatusBarNotificationPresenter.this.onNotificationRemoved(
Ned Burns00b4b2d2019-10-17 22:09:27 -0400202 entry.getKey(), entry.getSbn());
Gus Prevasdca2be52018-12-21 11:25:10 -0500203 if (removedByUser) {
204 maybeEndAmbientPulse();
205 }
Gus Prevas26bc59b2018-12-19 11:26:39 -0500206 }
207 };
208
Jason Monk297c04e2018-08-23 17:16:59 -0400209 mViewHierarchyManager.setUpWithPresenter(this, notifListContainer);
Beverly95a0802ac2020-02-10 15:27:40 -0500210 mEntryManager.setUpWithPresenter(this);
Gus Prevas8621bd22018-12-20 15:04:25 -0500211 mEntryManager.addNotificationEntryListener(notificationEntryListener);
Gus Prevas5c84abb2018-12-28 16:41:49 -0500212 mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
Ned Burns1016d962019-01-08 16:52:39 -0500213 mEntryManager.addNotificationLifetimeExtender(mGutsManager);
Gus Prevas5c84abb2018-12-28 16:41:49 -0500214 mEntryManager.addNotificationLifetimeExtenders(
215 remoteInputManager.getLifetimeExtenders());
Beverly Taid1e175c2020-03-10 16:37:04 +0000216 notificationInterruptStateProvider.addSuppressor(mInterruptSuppressor);
Jason Monk297c04e2018-08-23 17:16:59 -0400217 mLockscreenUserManager.setUpWithPresenter(this);
218 mMediaManager.setUpWithPresenter(this);
Gus Prevas5b9098dc2018-12-21 17:07:15 -0500219 mVisualStabilityManager.setUpWithPresenter(this);
Ned Burns1016d962019-01-08 16:52:39 -0500220 mGutsManager.setUpWithPresenter(this,
Jason Monk297c04e2018-08-23 17:16:59 -0400221 notifListContainer, mCheckSaveListener, mOnSettingsClickListener);
Evan Laird3ceaa9b2019-08-05 17:11:54 -0400222 // ForegroundServiceNotificationListener adds its listener in its constructor
Gus Prevaseb4e2e12018-12-28 14:57:59 -0500223 // but we need to request it here in order for it to be instantiated.
224 // TODO: figure out how to do this correctly once Dependency.get() is gone.
225 Dependency.get(ForegroundServiceNotificationListener.class);
Jason Monk297c04e2018-08-23 17:16:59 -0400226
227 onUserSwitched(mLockscreenUserManager.getCurrentUserId());
228 });
Selim Cinek9ba78f12018-12-07 14:37:33 -0800229 Dependency.get(ConfigurationController.class).addCallback(this);
Jason Monk297c04e2018-08-23 17:16:59 -0400230 }
231
Selim Cinek9ba78f12018-12-07 14:37:33 -0800232 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400233 public void onDensityOrFontScaleChanged() {
Selim Cinek9ba78f12018-12-07 14:37:33 -0800234 MessagingMessage.dropCache();
235 MessagingGroup.dropCache();
Dave Mankoffe2294692019-08-14 11:53:13 -0400236 if (!Dependency.get(KeyguardUpdateMonitor.class).isSwitchingUser()) {
Lucas Dupinc12fad32019-05-14 20:59:17 +0000237 updateNotificationsOnDensityOrFontScaleChanged();
238 } else {
239 mReinflateNotificationsOnUserSwitched = true;
240 }
Jason Monk297c04e2018-08-23 17:16:59 -0400241 }
242
243 @Override
Selim Cinekab9c7b22018-12-11 18:15:47 -0800244 public void onUiModeChanged() {
Dave Mankoffe2294692019-08-14 11:53:13 -0400245 if (!Dependency.get(KeyguardUpdateMonitor.class).isSwitchingUser()) {
Lucas Dupinc12fad32019-05-14 20:59:17 +0000246 updateNotificationOnUiModeChanged();
247 } else {
248 mDispatchUiModeChangeOnUserSwitched = true;
249 }
Selim Cinekab9c7b22018-12-11 18:15:47 -0800250 }
251
Selim Cinekdd26a7e2019-02-11 18:42:55 -0800252 @Override
253 public void onOverlayChanged() {
254 onDensityOrFontScaleChanged();
255 }
256
Selim Cinekab9c7b22018-12-11 18:15:47 -0800257 private void updateNotificationOnUiModeChanged() {
Evan Laird181de622019-10-24 09:53:02 -0400258 List<NotificationEntry> userNotifications =
259 mEntryManager.getActiveNotificationsForCurrentUser();
Selim Cinekab9c7b22018-12-11 18:15:47 -0800260 for (int i = 0; i < userNotifications.size(); i++) {
Ned Burnsf81c4c42019-01-07 14:10:43 -0500261 NotificationEntry entry = userNotifications.get(i);
Selim Cinekab9c7b22018-12-11 18:15:47 -0800262 ExpandableNotificationRow row = entry.getRow();
263 if (row != null) {
264 row.onUiModeChanged();
265 }
266 }
267 }
268
Ned Burns1016d962019-01-08 16:52:39 -0500269 private void updateNotificationsOnDensityOrFontScaleChanged() {
Evan Laird181de622019-10-24 09:53:02 -0400270 List<NotificationEntry> userNotifications =
271 mEntryManager.getActiveNotificationsForCurrentUser();
Ned Burns1016d962019-01-08 16:52:39 -0500272 for (int i = 0; i < userNotifications.size(); i++) {
273 NotificationEntry entry = userNotifications.get(i);
274 entry.onDensityOrFontScaleChanged();
275 boolean exposedGuts = entry.areGutsExposed();
276 if (exposedGuts) {
277 mGutsManager.onDensityOrFontScaleChanged(entry);
278 }
279 }
280 }
281
Selim Cinekab9c7b22018-12-11 18:15:47 -0800282 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400283 public boolean isCollapsing() {
284 return mNotificationPanel.isCollapsing()
285 || mActivityLaunchAnimator.isAnimationPending()
286 || mActivityLaunchAnimator.isAnimationRunning();
287 }
288
Gus Prevasdca2be52018-12-21 11:25:10 -0500289 private void maybeEndAmbientPulse() {
Jason Monk297c04e2018-08-23 17:16:59 -0400290 if (mNotificationPanel.hasPulsingNotifications() &&
Selim Cinekc3fec682019-06-06 18:11:07 -0700291 !mHeadsUpManager.hasNotifications()) {
Jason Monk297c04e2018-08-23 17:16:59 -0400292 // We were showing a pulse for a notification, but no notifications are pulsing anymore.
293 // Finish the pulse.
294 mDozeScrimController.pulseOutNow();
295 }
296 }
297
298 @Override
299 public void updateNotificationViews() {
300 // The function updateRowStates depends on both of these being non-null, so check them here.
301 // We may be called before they are set from DeviceProvisionedController's callback.
302 if (mScrimController == null) return;
303
304 // Do not modify the notifications during collapse.
305 if (isCollapsing()) {
306 mShadeController.addPostCollapseAction(this::updateNotificationViews);
307 return;
308 }
309
310 mViewHierarchyManager.updateNotificationViews();
311
312 mNotificationPanel.updateNotificationViews();
313 }
314
Jason Monk297c04e2018-08-23 17:16:59 -0400315 public void onNotificationRemoved(String key, StatusBarNotification old) {
316 if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
317
318 if (old != null) {
319 if (CLOSE_PANEL_WHEN_EMPTIED && !hasActiveNotifications()
320 && !mNotificationPanel.isTracking() && !mNotificationPanel.isQsExpanded()) {
321 if (mStatusBarStateController.getState() == StatusBarState.SHADE) {
322 mCommandQueue.animateCollapsePanels();
323 } else if (mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED
324 && !isCollapsing()) {
Heemin Seog98df6972019-12-05 13:01:38 -0800325 mStatusBarStateController.setState(StatusBarState.KEYGUARD);
Jason Monk297c04e2018-08-23 17:16:59 -0400326 }
327 }
328 }
Jason Monk297c04e2018-08-23 17:16:59 -0400329 }
330
331 public boolean hasActiveNotifications() {
Evan Laird181de622019-10-24 09:53:02 -0400332 return mEntryManager.hasActiveNotifications();
Jason Monk297c04e2018-08-23 17:16:59 -0400333 }
334
Jason Monk297c04e2018-08-23 17:16:59 -0400335 @Override
336 public void onUserSwitched(int newUserId) {
337 // Begin old BaseStatusBar.userSwitched
338 mHeadsUpManager.setUser(newUserId);
339 // End old BaseStatusBar.userSwitched
340 if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
341 mCommandQueue.animateCollapsePanels();
Lucas Dupinc12fad32019-05-14 20:59:17 +0000342 if (mReinflateNotificationsOnUserSwitched) {
343 updateNotificationsOnDensityOrFontScaleChanged();
344 mReinflateNotificationsOnUserSwitched = false;
345 }
346 if (mDispatchUiModeChangeOnUserSwitched) {
347 updateNotificationOnUiModeChanged();
348 mDispatchUiModeChangeOnUserSwitched = false;
349 }
Jason Monk297c04e2018-08-23 17:16:59 -0400350 updateNotificationViews();
351 mMediaManager.clearCurrentMediaNotification();
Heemin Seogba6337f2019-12-10 15:34:37 -0800352 mStatusBar.setLockscreenUser(newUserId);
Jason Monk297c04e2018-08-23 17:16:59 -0400353 updateMediaMetaData(true, false);
354 }
355
356 @Override
Kevin Han37423222020-03-10 16:05:07 -0700357 public void onBindRow(ExpandableNotificationRow row) {
Jason Monk297c04e2018-08-23 17:16:59 -0400358 row.setAboveShelfChangedListener(mAboveShelfObserver);
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400359 row.setSecureStateProvider(mKeyguardStateController::canDismissLockScreen);
Jason Monk297c04e2018-08-23 17:16:59 -0400360 }
361
362 @Override
363 public boolean isPresenterFullyCollapsed() {
364 return mNotificationPanel.isFullyCollapsed();
365 }
366
367 @Override
368 public void onActivated(ActivatableNotificationView view) {
369 onActivated();
370 if (view != null) mNotificationPanel.setActivatedChild(view);
371 }
372
373 public void onActivated() {
374 mLockscreenGestureLogger.write(
375 MetricsEvent.ACTION_LS_NOTE,
376 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
377 mNotificationPanel.showTransientIndication(R.string.notification_tap_again);
378 ActivatableNotificationView previousView = mNotificationPanel.getActivatedChild();
379 if (previousView != null) {
380 previousView.makeInactive(true /* animate */);
381 }
382 }
383
384 @Override
385 public void onActivationReset(ActivatableNotificationView view) {
386 if (view == mNotificationPanel.getActivatedChild()) {
387 mNotificationPanel.setActivatedChild(null);
Heemin Seog98df6972019-12-05 13:01:38 -0800388 mKeyguardIndicationController.hideTransientIndication();
Jason Monk297c04e2018-08-23 17:16:59 -0400389 }
390 }
391
392 @Override
393 public void updateMediaMetaData(boolean metaDataChanged, boolean allowEnterAnimation) {
394 mMediaManager.updateMediaMetaData(metaDataChanged, allowEnterAnimation);
395 }
396
397 @Override
Jason Monk297c04e2018-08-23 17:16:59 -0400398 public int getMaxNotificationsWhileLocked(boolean recompute) {
399 if (recompute) {
400 mMaxKeyguardNotifications = Math.max(1,
401 mNotificationPanel.computeMaxKeyguardNotifications(
402 mMaxAllowedKeyguardNotifications));
403 return mMaxKeyguardNotifications;
404 }
405 return mMaxKeyguardNotifications;
406 }
407
408 @Override
409 public void onUpdateRowStates() {
410 mNotificationPanel.onUpdateRowStates();
411 }
412
413 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -0500414 public void onExpandClicked(NotificationEntry clickedEntry, boolean nowExpanded) {
Jason Monk297c04e2018-08-23 17:16:59 -0400415 mHeadsUpManager.setExpanded(clickedEntry, nowExpanded);
Selim Cinek5454a0d2019-07-30 17:14:50 -0700416 if (nowExpanded) {
417 if (mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
418 mShadeController.goToLockedShade(clickedEntry.getRow());
419 } else if (clickedEntry.isSensitive()
420 && mDynamicPrivacyController.isInLockedDownShade()) {
421 mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
422 mActivityStarter.dismissKeyguardThenExecute(() -> false /* dismissAction */
423 , null /* cancelRunnable */, false /* afterKeyguardGone */);
424 }
Jason Monk297c04e2018-08-23 17:16:59 -0400425 }
426 }
427
428 @Override
429 public boolean isDeviceInVrMode() {
430 return mVrMode;
431 }
432
Jason Monk297c04e2018-08-23 17:16:59 -0400433 private void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {
434 mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
435 mActivityStarter.dismissKeyguardThenExecute(dismissAction, null,
436 true /* afterKeyguardGone */);
437 }
438
Jason Monk297c04e2018-08-23 17:16:59 -0400439 private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() {
440 @Override
441 public void onVrStateChanged(boolean enabled) {
442 mVrMode = enabled;
443 }
444 };
445
446 private final CheckSaveListener mCheckSaveListener = new CheckSaveListener() {
447 @Override
448 public void checkSave(Runnable saveImportance, StatusBarNotification sbn) {
Jason Monk297c04e2018-08-23 17:16:59 -0400449 // If the user has security enabled, show challenge if the setting is changed.
450 if (mLockscreenUserManager.isLockscreenPublicMode(sbn.getUser().getIdentifier())
451 && mKeyguardManager.isKeyguardLocked()) {
452 onLockedNotificationImportanceChange(() -> {
453 saveImportance.run();
454 return true;
455 });
456 } else {
457 saveImportance.run();
458 }
459 }
460 };
461
462 private final OnSettingsClickListener mOnSettingsClickListener = new OnSettingsClickListener() {
463 @Override
464 public void onSettingsClick(String key) {
465 try {
466 mBarService.onNotificationSettingsViewed(key);
467 } catch (RemoteException e) {
468 // if we're here we're dead
469 }
470 }
471 };
Beverly Taid1e175c2020-03-10 16:37:04 +0000472
473 private final NotificationInterruptSuppressor mInterruptSuppressor =
474 new NotificationInterruptSuppressor() {
475 @Override
476 public String getName() {
477 return TAG;
478 }
479
480 @Override
481 public boolean suppressAwakeHeadsUp(NotificationEntry entry) {
482 final StatusBarNotification sbn = entry.getSbn();
483 if (mStatusBar.isOccluded()) {
484 boolean devicePublic = mLockscreenUserManager
485 .isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
486 boolean userPublic = devicePublic
487 || mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
488 boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
489 if (userPublic && needsRedaction) {
490 // TODO(b/135046837): we can probably relax this with dynamic privacy
491 return true;
492 }
493 }
494
495 if (!mCommandQueue.panelsEnabled()) {
496 if (DEBUG) {
497 Log.d(TAG, "No heads up: disabled panel : " + sbn.getKey());
498 }
499 return true;
500 }
501
502 if (sbn.getNotification().fullScreenIntent != null) {
503 // we don't allow head-up on the lockscreen (unless there's a
504 // "showWhenLocked" activity currently showing) if
505 // the potential HUN has a fullscreen intent
506 if (mKeyguardStateController.isShowing() && !mStatusBar.isOccluded()) {
507 if (DEBUG) {
508 Log.d(TAG, "No heads up: entry has fullscreen intent on lockscreen "
509 + sbn.getKey());
510 }
511 return true;
512 }
513
514 if (mAccessibilityManager.isTouchExplorationEnabled()) {
515 if (DEBUG) {
516 Log.d(TAG, "No heads up: accessible fullscreen: " + sbn.getKey());
517 }
518 return true;
519 }
520 }
521 return false;
522 }
523
524 @Override
525 public boolean suppressAwakeInterruptions(NotificationEntry entry) {
526 return isDeviceInVrMode();
527 }
528
529 @Override
530 public boolean suppressInterruptions(NotificationEntry entry) {
531 return mStatusBar.areNotificationAlertsDisabled();
532 }
533 };
Jason Monk297c04e2018-08-23 17:16:59 -0400534}