blob: bec53a1b2d3cdeb645e8bb2f667a8fbb68891ff1 [file] [log] [blame]
Gus Prevas21437b32018-12-05 10:36:13 -05001/*
2 * Copyright (C) 2018 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
17package com.android.systemui.statusbar.phone;
18
Mady Mellorc2ff0112019-03-28 14:18:06 -070019import static android.service.notification.NotificationListenerService.REASON_CLICK;
20
Gus Prevas21437b32018-12-05 10:36:13 -050021import static com.android.systemui.statusbar.phone.StatusBar.getActivityOptions;
22
23import android.app.ActivityManager;
24import android.app.ActivityTaskManager;
25import android.app.KeyguardManager;
26import android.app.Notification;
Gus Prevasd65c2db2018-12-18 17:13:38 -050027import android.app.NotificationManager;
Gus Prevas21437b32018-12-05 10:36:13 -050028import android.app.PendingIntent;
29import android.app.TaskStackBuilder;
30import android.content.Context;
31import android.content.Intent;
32import android.os.AsyncTask;
Mark Renouf6b2331c2019-03-21 13:40:08 -040033import android.os.Handler;
Gus Prevas21437b32018-12-05 10:36:13 -050034import android.os.Looper;
35import android.os.RemoteException;
Gus Prevas21437b32018-12-05 10:36:13 -050036import android.os.UserHandle;
Gus Prevasd65c2db2018-12-18 17:13:38 -050037import android.service.dreams.IDreamManager;
Gus Prevas21437b32018-12-05 10:36:13 -050038import android.service.notification.StatusBarNotification;
39import android.text.TextUtils;
Gus Prevasd65c2db2018-12-18 17:13:38 -050040import android.util.EventLog;
Gus Prevas21437b32018-12-05 10:36:13 -050041import android.util.Log;
42import android.view.RemoteAnimationAdapter;
43
Gus Prevasd65c2db2018-12-18 17:13:38 -050044import com.android.internal.logging.MetricsLogger;
Gus Prevas21437b32018-12-05 10:36:13 -050045import com.android.internal.statusbar.IStatusBarService;
46import com.android.internal.statusbar.NotificationVisibility;
47import com.android.internal.widget.LockPatternUtils;
Mark Renouf6b2331c2019-03-21 13:40:08 -040048import com.android.systemui.ActivityIntentHelper;
Gus Prevas21437b32018-12-05 10:36:13 -050049import com.android.systemui.Dependency;
Gus Prevasd65c2db2018-12-18 17:13:38 -050050import com.android.systemui.EventLogTags;
51import com.android.systemui.UiOffloadThread;
Gus Prevas21437b32018-12-05 10:36:13 -050052import com.android.systemui.assist.AssistManager;
Mark Renouffec45da2019-03-13 13:24:27 -040053import com.android.systemui.bubbles.BubbleController;
Gus Prevas21437b32018-12-05 10:36:13 -050054import com.android.systemui.plugins.ActivityStarter;
Beverly8fdb5332019-02-04 14:29:49 -050055import com.android.systemui.plugins.statusbar.StatusBarStateController;
Gus Prevas21437b32018-12-05 10:36:13 -050056import com.android.systemui.statusbar.CommandQueue;
57import com.android.systemui.statusbar.NotificationLockscreenUserManager;
58import com.android.systemui.statusbar.NotificationPresenter;
59import com.android.systemui.statusbar.NotificationRemoteInputManager;
60import com.android.systemui.statusbar.RemoteInputController;
61import com.android.systemui.statusbar.StatusBarState;
Gus Prevas21437b32018-12-05 10:36:13 -050062import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
63import com.android.systemui.statusbar.notification.NotificationActivityStarter;
Gus Prevasd65c2db2018-12-18 17:13:38 -050064import com.android.systemui.statusbar.notification.NotificationEntryListener;
Gus Prevas21437b32018-12-05 10:36:13 -050065import com.android.systemui.statusbar.notification.NotificationEntryManager;
Gus Prevasd65c2db2018-12-18 17:13:38 -050066import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
Ned Burnsf81c4c42019-01-07 14:10:43 -050067import com.android.systemui.statusbar.notification.collection.NotificationEntry;
Gustav Senntonf892fe92019-01-22 15:31:42 +000068import com.android.systemui.statusbar.notification.logging.NotificationLogger;
Gus Prevas21437b32018-12-05 10:36:13 -050069import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
70import com.android.systemui.statusbar.policy.HeadsUpUtil;
71import com.android.systemui.statusbar.policy.KeyguardMonitor;
Gus Prevas21437b32018-12-05 10:36:13 -050072
73/**
74 * Status bar implementation of {@link NotificationActivityStarter}.
75 */
76public class StatusBarNotificationActivityStarter implements NotificationActivityStarter {
77
78 private static final String TAG = "NotificationClickHandler";
Gus Prevasd65c2db2018-12-18 17:13:38 -050079 protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Gus Prevas21437b32018-12-05 10:36:13 -050080
Mark Renouf906a93f2019-03-15 16:04:58 -040081 private final AssistManager mAssistManager;
82 private final NotificationGroupManager mGroupManager;
83 private final StatusBarRemoteInputCallback mStatusBarRemoteInputCallback;
84 private final NotificationRemoteInputManager mRemoteInputManager;
85 private final NotificationLockscreenUserManager mLockscreenUserManager;
86 private final ShadeController mShadeController;
87 private final KeyguardMonitor mKeyguardMonitor;
88 private final ActivityStarter mActivityStarter;
89 private final NotificationEntryManager mEntryManager;
90 private final StatusBarStateController mStatusBarStateController;
91 private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
92 private final MetricsLogger mMetricsLogger;
Gus Prevas21437b32018-12-05 10:36:13 -050093 private final Context mContext;
94 private final NotificationPanelView mNotificationPanel;
95 private final NotificationPresenter mPresenter;
96 private final LockPatternUtils mLockPatternUtils;
97 private final HeadsUpManagerPhone mHeadsUpManager;
98 private final KeyguardManager mKeyguardManager;
99 private final ActivityLaunchAnimator mActivityLaunchAnimator;
100 private final IStatusBarService mBarService;
101 private final CommandQueue mCommandQueue;
Gus Prevasd65c2db2018-12-18 17:13:38 -0500102 private final IDreamManager mDreamManager;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400103 private final Handler mMainThreadHandler;
Mark Renouffec45da2019-03-13 13:24:27 -0400104 private final Handler mBackgroundHandler;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400105 private final ActivityIntentHelper mActivityIntentHelper;
Mark Renouffec45da2019-03-13 13:24:27 -0400106 private final BubbleController mBubbleController;
Gus Prevas21437b32018-12-05 10:36:13 -0500107
108 private boolean mIsCollapsingToShowActivityOverLockscreen;
109
110 public StatusBarNotificationActivityStarter(Context context,
Mark Renouf906a93f2019-03-15 16:04:58 -0400111 CommandQueue commandQueue,
112 AssistManager assistManager,
Gus Prevas21437b32018-12-05 10:36:13 -0500113 NotificationPanelView panel,
114 NotificationPresenter presenter,
Mark Renouf906a93f2019-03-15 16:04:58 -0400115 NotificationEntryManager entryManager,
Gus Prevas21437b32018-12-05 10:36:13 -0500116 HeadsUpManagerPhone headsUpManager,
Mark Renouf906a93f2019-03-15 16:04:58 -0400117 ActivityStarter activityStarter,
118 ActivityLaunchAnimator activityLaunchAnimator,
119 IStatusBarService statusBarService,
120 StatusBarStateController statusBarStateController,
121 KeyguardManager keyguardManager,
122 IDreamManager dreamManager,
123 NotificationRemoteInputManager remoteInputManager,
124 StatusBarRemoteInputCallback remoteInputCallback,
125 NotificationGroupManager groupManager,
126 NotificationLockscreenUserManager lockscreenUserManager,
127 ShadeController shadeController,
128 KeyguardMonitor keyguardMonitor,
129 NotificationInterruptionStateProvider notificationInterruptionStateProvider,
130 MetricsLogger metricsLogger,
Mark Renouf6b2331c2019-03-21 13:40:08 -0400131 LockPatternUtils lockPatternUtils,
132 Handler mainThreadHandler,
Mark Renouffec45da2019-03-13 13:24:27 -0400133 Handler backgroundHandler,
134 ActivityIntentHelper activityIntentHelper,
135 BubbleController bubbleController) {
Gus Prevas21437b32018-12-05 10:36:13 -0500136 mContext = context;
137 mNotificationPanel = panel;
138 mPresenter = presenter;
Gus Prevas21437b32018-12-05 10:36:13 -0500139 mHeadsUpManager = headsUpManager;
Gus Prevas21437b32018-12-05 10:36:13 -0500140 mActivityLaunchAnimator = activityLaunchAnimator;
Mark Renouf906a93f2019-03-15 16:04:58 -0400141 mBarService = statusBarService;
142 mCommandQueue = commandQueue;
143 mKeyguardManager = keyguardManager;
144 mDreamManager = dreamManager;
145 mRemoteInputManager = remoteInputManager;
146 mLockscreenUserManager = lockscreenUserManager;
147 mShadeController = shadeController;
148 mKeyguardMonitor = keyguardMonitor;
149 mActivityStarter = activityStarter;
150 mEntryManager = entryManager;
151 mStatusBarStateController = statusBarStateController;
152 mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
153 mMetricsLogger = metricsLogger;
154 mAssistManager = assistManager;
155 mGroupManager = groupManager;
156 mLockPatternUtils = lockPatternUtils;
Mark Renouffec45da2019-03-13 13:24:27 -0400157 mBackgroundHandler = backgroundHandler;
Gus Prevasd65c2db2018-12-18 17:13:38 -0500158 mEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
159 @Override
Ned Burnsf81c4c42019-01-07 14:10:43 -0500160 public void onPendingEntryAdded(NotificationEntry entry) {
Gus Prevasd65c2db2018-12-18 17:13:38 -0500161 handleFullScreenIntent(entry);
162 }
163 });
Mark Renouf906a93f2019-03-15 16:04:58 -0400164 mStatusBarRemoteInputCallback = remoteInputCallback;
Mark Renouf6b2331c2019-03-21 13:40:08 -0400165 mMainThreadHandler = mainThreadHandler;
166 mActivityIntentHelper = activityIntentHelper;
Mark Renouffec45da2019-03-13 13:24:27 -0400167 mBubbleController = bubbleController;
Gus Prevas21437b32018-12-05 10:36:13 -0500168 }
169
170 /**
171 * Called when a notification is clicked.
172 *
173 * @param sbn notification that was clicked
174 * @param row row for that notification
175 */
176 @Override
177 public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
178 RemoteInputController controller = mRemoteInputManager.getController();
179 if (controller.isRemoteInputActive(row.getEntry())
180 && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
181 // We have an active remote input typed and the user clicked on the notification.
182 // this was probably unintentional, so we're closing the edit text instead.
183 controller.closeRemoteInputs();
184 return;
185 }
186 Notification notification = sbn.getNotification();
187 final PendingIntent intent = notification.contentIntent != null
188 ? notification.contentIntent
189 : notification.fullScreenIntent;
Mark Renouffec45da2019-03-13 13:24:27 -0400190 final boolean isBubble = row.getEntry().isBubble();
191
192 // This code path is now executed for notification without a contentIntent.
193 // The only valid case is Bubble notifications. Guard against other cases
194 // entering here.
195 if (intent == null && !isBubble) {
196 Log.e(TAG, "onNotificationClicked called for non-clickable notification!");
197 return;
198 }
199
Gus Prevas21437b32018-12-05 10:36:13 -0500200 final String notificationKey = sbn.getKey();
201
Mark Renouffec45da2019-03-13 13:24:27 -0400202 boolean isActivityIntent = intent != null && intent.isActivity() && !isBubble;
Gus Prevas21437b32018-12-05 10:36:13 -0500203 final boolean afterKeyguardGone = isActivityIntent
Mark Renouf6b2331c2019-03-21 13:40:08 -0400204 && mActivityIntentHelper.wouldLaunchResolverActivity(intent.getIntent(),
Gus Prevas21437b32018-12-05 10:36:13 -0500205 mLockscreenUserManager.getCurrentUserId());
206 final boolean wasOccluded = mShadeController.isOccluded();
Mark Renouffec45da2019-03-13 13:24:27 -0400207 boolean showOverLockscreen = mKeyguardMonitor.isShowing() && intent != null
Mark Renouf6b2331c2019-03-21 13:40:08 -0400208 && mActivityIntentHelper.wouldShowOverLockscreen(intent.getIntent(),
Gus Prevas21437b32018-12-05 10:36:13 -0500209 mLockscreenUserManager.getCurrentUserId());
210 ActivityStarter.OnDismissAction postKeyguardAction =
211 () -> handleNotificationClickAfterKeyguardDismissed(
212 sbn, row, controller, intent, notificationKey,
213 isActivityIntent, wasOccluded, showOverLockscreen);
214 if (showOverLockscreen) {
215 mIsCollapsingToShowActivityOverLockscreen = true;
216 postKeyguardAction.onDismiss();
217 } else {
218 mActivityStarter.dismissKeyguardThenExecute(
219 postKeyguardAction, null /* cancel */, afterKeyguardGone);
220 }
221 }
222
223 private boolean handleNotificationClickAfterKeyguardDismissed(
224 StatusBarNotification sbn,
225 ExpandableNotificationRow row,
226 RemoteInputController controller,
227 PendingIntent intent,
228 String notificationKey,
229 boolean isActivityIntent,
230 boolean wasOccluded,
231 boolean showOverLockscreen) {
232 // TODO: Some of this code may be able to move to NotificationEntryManager.
233 if (mHeadsUpManager != null && mHeadsUpManager.isAlerting(notificationKey)) {
234 // Release the HUN notification to the shade.
235
236 if (mPresenter.isPresenterFullyCollapsed()) {
237 HeadsUpUtil.setIsClickedHeadsUpNotification(row, true);
238 }
239 //
240 // In most cases, when FLAG_AUTO_CANCEL is set, the notification will
241 // become canceled shortly by NoMan, but we can't assume that.
242 mHeadsUpManager.removeNotification(sbn.getKey(),
243 true /* releaseImmediately */);
244 }
245 StatusBarNotification parentToCancel = null;
246 if (shouldAutoCancel(sbn) && mGroupManager.isOnlyChildInGroup(sbn)) {
247 StatusBarNotification summarySbn =
248 mGroupManager.getLogicalGroupSummary(sbn).notification;
249 if (shouldAutoCancel(summarySbn)) {
250 parentToCancel = summarySbn;
251 }
252 }
253 final StatusBarNotification parentToCancelFinal = parentToCancel;
254 final Runnable runnable = () -> handleNotificationClickAfterPanelCollapsed(
255 sbn, row, controller, intent, notificationKey,
256 isActivityIntent, wasOccluded, parentToCancelFinal);
257
258 if (showOverLockscreen) {
259 mShadeController.addPostCollapseAction(runnable);
260 mShadeController.collapsePanel(true /* animate */);
261 } else if (mKeyguardMonitor.isShowing()
262 && mShadeController.isOccluded()) {
263 mShadeController.addAfterKeyguardGoneRunnable(runnable);
264 mShadeController.collapsePanel();
265 } else {
Mark Renouffec45da2019-03-13 13:24:27 -0400266 mBackgroundHandler.postAtFrontOfQueue(runnable);
Gus Prevas21437b32018-12-05 10:36:13 -0500267 }
Gus Prevas21437b32018-12-05 10:36:13 -0500268 return !mNotificationPanel.isFullyCollapsed();
269 }
270
271 private void handleNotificationClickAfterPanelCollapsed(
272 StatusBarNotification sbn,
273 ExpandableNotificationRow row,
274 RemoteInputController controller,
275 PendingIntent intent,
276 String notificationKey,
277 boolean isActivityIntent,
278 boolean wasOccluded,
279 StatusBarNotification parentToCancelFinal) {
280 try {
281 // The intent we are sending is for the application, which
282 // won't have permission to immediately start an activity after
283 // the user switches to home. We know it is safe to do at this
284 // point, so make sure new activity switches are now allowed.
285 ActivityManager.getService().resumeAppSwitches();
286 } catch (RemoteException e) {
287 }
Gus Prevas21437b32018-12-05 10:36:13 -0500288 // If we are launching a work activity and require to launch
289 // separate work challenge, we defer the activity action and cancel
290 // notification until work challenge is unlocked.
291 if (isActivityIntent) {
292 final int userId = intent.getCreatorUserHandle().getIdentifier();
293 if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)
294 && mKeyguardManager.isDeviceLocked(userId)) {
295 // TODO(b/28935539): should allow certain activities to
296 // bypass work challenge
297 if (mStatusBarRemoteInputCallback.startWorkChallengeIfNecessary(userId,
298 intent.getIntentSender(), notificationKey)) {
299 // Show work challenge, do not run PendingIntent and
300 // remove notification
301 collapseOnMainThread();
302 return;
303 }
304 }
305 }
306 Intent fillInIntent = null;
Ned Burnsf81c4c42019-01-07 14:10:43 -0500307 NotificationEntry entry = row.getEntry();
Mark Renouffec45da2019-03-13 13:24:27 -0400308 final boolean isBubble = entry.isBubble();
Gus Prevas21437b32018-12-05 10:36:13 -0500309 CharSequence remoteInputText = null;
310 if (!TextUtils.isEmpty(entry.remoteInputText)) {
311 remoteInputText = entry.remoteInputText;
312 }
313 if (!TextUtils.isEmpty(remoteInputText) && !controller.isSpinning(entry.key)) {
314 fillInIntent = new Intent().putExtra(Notification.EXTRA_REMOTE_INPUT_DRAFT,
315 remoteInputText.toString());
316 }
Mark Renouffec45da2019-03-13 13:24:27 -0400317 if (isBubble) {
318 expandBubbleStackOnMainThread(notificationKey);
319 } else {
320 startNotificationIntent(intent, fillInIntent, row, wasOccluded, isActivityIntent);
321 }
322 if (isActivityIntent || isBubble) {
Gus Prevas21437b32018-12-05 10:36:13 -0500323 mAssistManager.hideAssist();
324 }
325 if (shouldCollapse()) {
326 collapseOnMainThread();
327 }
328
329 final int count =
330 mEntryManager.getNotificationData().getActiveNotifications().size();
331 final int rank = mEntryManager.getNotificationData().getRank(notificationKey);
Gustav Senntonf892fe92019-01-22 15:31:42 +0000332 NotificationVisibility.NotificationLocation location =
333 NotificationLogger.getNotificationLocation(
334 mEntryManager.getNotificationData().get(notificationKey));
Gus Prevas21437b32018-12-05 10:36:13 -0500335 final NotificationVisibility nv = NotificationVisibility.obtain(notificationKey,
Gustav Senntonf892fe92019-01-22 15:31:42 +0000336 rank, count, true, location);
Gus Prevas21437b32018-12-05 10:36:13 -0500337 try {
338 mBarService.onNotificationClick(notificationKey, nv);
339 } catch (RemoteException ex) {
340 // system process is dead if we're here.
341 }
Mark Renouffec45da2019-03-13 13:24:27 -0400342 if (!isBubble) {
343 if (parentToCancelFinal != null) {
344 removeNotification(parentToCancelFinal);
345 }
346 if (shouldAutoCancel(sbn)
347 || mRemoteInputManager.isNotificationKeptForRemoteInputHistory(
348 notificationKey)) {
349 // Automatically remove all notifications that we may have kept around longer
350 removeNotification(sbn);
351 }
Gus Prevas21437b32018-12-05 10:36:13 -0500352 }
353 mIsCollapsingToShowActivityOverLockscreen = false;
354 }
355
Mark Renouffec45da2019-03-13 13:24:27 -0400356 private void expandBubbleStackOnMainThread(String notificationKey) {
357 if (Looper.getMainLooper().isCurrentThread()) {
358 mBubbleController.expandStackAndSelectBubble(notificationKey);
359 } else {
360 mMainThreadHandler.post(
361 () -> mBubbleController.expandStackAndSelectBubble(notificationKey));
362 }
363 }
364
Mark Renouf7bb6a242019-03-13 12:08:38 -0400365 private void startNotificationIntent(PendingIntent intent, Intent fillInIntent,
366 ExpandableNotificationRow row, boolean wasOccluded, boolean isActivityIntent) {
367 RemoteAnimationAdapter adapter = mActivityLaunchAnimator.getLaunchAnimation(row,
368 wasOccluded);
369 try {
370 if (adapter != null) {
371 ActivityTaskManager.getService()
372 .registerRemoteAnimationForNextActivityStart(
373 intent.getCreatorPackage(), adapter);
374 }
375 int launchResult = intent.sendAndReturnResult(mContext, 0, fillInIntent, null,
376 null, null, getActivityOptions(adapter));
377 mActivityLaunchAnimator.setLaunchResult(launchResult, isActivityIntent);
378 } catch (RemoteException | PendingIntent.CanceledException e) {
379 // the stack trace isn't very helpful here.
380 // Just log the exception message.
381 Log.w(TAG, "Sending contentIntent failed: " + e);
382 // TODO: Dismiss Keyguard.
383 }
384 }
385
Gus Prevas21437b32018-12-05 10:36:13 -0500386 @Override
387 public void startNotificationGutsIntent(final Intent intent, final int appUid,
388 ExpandableNotificationRow row) {
389 mActivityStarter.dismissKeyguardThenExecute(() -> {
390 AsyncTask.execute(() -> {
391 int launchResult = TaskStackBuilder.create(mContext)
392 .addNextIntentWithParentStack(intent)
393 .startActivities(getActivityOptions(
394 mActivityLaunchAnimator.getLaunchAnimation(
395 row, mShadeController.isOccluded())),
396 new UserHandle(UserHandle.getUserId(appUid)));
397 mActivityLaunchAnimator.setLaunchResult(launchResult, true /* isActivityIntent */);
398 if (shouldCollapse()) {
399 // Putting it back on the main thread, since we're touching views
Mark Renouf6b2331c2019-03-21 13:40:08 -0400400 mMainThreadHandler.post(() -> mCommandQueue.animateCollapsePanels(
Gus Prevas21437b32018-12-05 10:36:13 -0500401 CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL, true /* force */));
402 }
403 });
404 return true;
405 }, null, false /* afterKeyguardGone */);
406 }
407
Ned Burnsf81c4c42019-01-07 14:10:43 -0500408 private void handleFullScreenIntent(NotificationEntry entry) {
Selim Cinekc3fec682019-06-06 18:11:07 -0700409 if (mNotificationInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
Gus Prevasd65c2db2018-12-18 17:13:38 -0500410 if (shouldSuppressFullScreenIntent(entry)) {
411 if (DEBUG) {
412 Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + entry.key);
413 }
414 } else if (entry.importance < NotificationManager.IMPORTANCE_HIGH) {
415 if (DEBUG) {
416 Log.d(TAG, "No Fullscreen intent: not important enough: " + entry.key);
417 }
418 } else {
419 // Stop screensaver if the notification has a fullscreen intent.
420 // (like an incoming phone call)
421 Dependency.get(UiOffloadThread.class).submit(() -> {
422 try {
423 mDreamManager.awaken();
424 } catch (RemoteException e) {
425 e.printStackTrace();
426 }
427 });
428
429 // not immersive & a fullscreen alert should be shown
430 if (DEBUG) {
431 Log.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent");
432 }
433 try {
434 EventLog.writeEvent(EventLogTags.SYSUI_FULLSCREEN_NOTIFICATION,
435 entry.key);
436 entry.notification.getNotification().fullScreenIntent.send();
437 entry.notifyFullScreenIntentLaunched();
438 mMetricsLogger.count("note_fullscreen", 1);
439 } catch (PendingIntent.CanceledException e) {
440 // ignore
441 }
442 }
443 }
444 }
445
Gus Prevas21437b32018-12-05 10:36:13 -0500446 @Override
447 public boolean isCollapsingToShowActivityOverLockscreen() {
448 return mIsCollapsingToShowActivityOverLockscreen;
449 }
450
451 private static boolean shouldAutoCancel(StatusBarNotification sbn) {
452 int flags = sbn.getNotification().flags;
453 if ((flags & Notification.FLAG_AUTO_CANCEL) != Notification.FLAG_AUTO_CANCEL) {
454 return false;
455 }
456 if ((flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
457 return false;
458 }
459 return true;
460 }
461
462 private void collapseOnMainThread() {
463 if (Looper.getMainLooper().isCurrentThread()) {
464 mShadeController.collapsePanel();
465 } else {
Mark Renouf6b2331c2019-03-21 13:40:08 -0400466 mMainThreadHandler.post(mShadeController::collapsePanel);
Gus Prevas21437b32018-12-05 10:36:13 -0500467 }
468 }
469
470 private boolean shouldCollapse() {
471 return mStatusBarStateController.getState() != StatusBarState.SHADE
472 || !mActivityLaunchAnimator.isAnimationPending();
473 }
474
Ned Burnsf81c4c42019-01-07 14:10:43 -0500475 private boolean shouldSuppressFullScreenIntent(NotificationEntry entry) {
Gus Prevasd65c2db2018-12-18 17:13:38 -0500476 if (mPresenter.isDeviceInVrMode()) {
477 return true;
478 }
479
480 return entry.shouldSuppressFullScreenIntent();
481 }
482
Gus Prevas21437b32018-12-05 10:36:13 -0500483 private void removeNotification(StatusBarNotification notification) {
484 // We have to post it to the UI thread for synchronization
Mark Renouf6b2331c2019-03-21 13:40:08 -0400485 mMainThreadHandler.post(() -> {
Gus Prevas21437b32018-12-05 10:36:13 -0500486 Runnable removeRunnable =
Mady Mellorc2ff0112019-03-28 14:18:06 -0700487 () -> mEntryManager.performRemoveNotification(notification, REASON_CLICK);
Gus Prevas21437b32018-12-05 10:36:13 -0500488 if (mPresenter.isCollapsing()) {
489 // To avoid lags we're only performing the remove
490 // after the shade was collapsed
491 mShadeController.addPostCollapseAction(removeRunnable);
492 } else {
493 removeRunnable.run();
494 }
495 });
496 }
497}