1 /* 2 * Copyright (C) 2019 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.shade; 18 19 import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED; 20 import static com.android.systemui.flags.Flags.TRACKPAD_GESTURE_COMMON; 21 import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; 22 23 import android.app.StatusBarManager; 24 import android.os.PowerManager; 25 import android.util.Log; 26 import android.view.GestureDetector; 27 import android.view.InputDevice; 28 import android.view.KeyEvent; 29 import android.view.MotionEvent; 30 import android.view.View; 31 import android.view.ViewGroup; 32 33 import com.android.internal.annotations.VisibleForTesting; 34 import com.android.keyguard.AuthKeyguardMessageArea; 35 import com.android.keyguard.KeyguardMessageAreaController; 36 import com.android.keyguard.LockIconViewController; 37 import com.android.keyguard.dagger.KeyguardBouncerComponent; 38 import com.android.systemui.R; 39 import com.android.systemui.animation.ActivityLaunchAnimator; 40 import com.android.systemui.back.domain.interactor.BackActionInteractor; 41 import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor; 42 import com.android.systemui.bouncer.ui.binder.KeyguardBouncerViewBinder; 43 import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel; 44 import com.android.systemui.classifier.FalsingCollector; 45 import com.android.systemui.dagger.SysUISingleton; 46 import com.android.systemui.dock.DockManager; 47 import com.android.systemui.flags.FeatureFlags; 48 import com.android.systemui.flags.Flags; 49 import com.android.systemui.keyevent.domain.interactor.KeyEventInteractor; 50 import com.android.systemui.keyguard.KeyguardUnlockAnimationController; 51 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; 52 import com.android.systemui.keyguard.shared.model.TransitionState; 53 import com.android.systemui.keyguard.shared.model.TransitionStep; 54 import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; 55 import com.android.systemui.log.BouncerLogger; 56 import com.android.systemui.power.domain.interactor.PowerInteractor; 57 import com.android.systemui.shared.animation.DisableSubpixelTextTransitionListener; 58 import com.android.systemui.statusbar.DragDownHelper; 59 import com.android.systemui.statusbar.LockscreenShadeTransitionController; 60 import com.android.systemui.statusbar.NotificationInsetsController; 61 import com.android.systemui.statusbar.NotificationShadeDepthController; 62 import com.android.systemui.statusbar.NotificationShadeWindowController; 63 import com.android.systemui.statusbar.SysuiStatusBarStateController; 64 import com.android.systemui.statusbar.notification.data.repository.NotificationExpansionRepository; 65 import com.android.systemui.statusbar.notification.stack.AmbientState; 66 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout; 67 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; 68 import com.android.systemui.statusbar.phone.CentralSurfaces; 69 import com.android.systemui.statusbar.phone.PhoneStatusBarViewController; 70 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; 71 import com.android.systemui.statusbar.window.StatusBarWindowStateController; 72 import com.android.systemui.unfold.UnfoldTransitionProgressProvider; 73 import com.android.systemui.util.time.SystemClock; 74 75 import java.io.PrintWriter; 76 import java.util.Optional; 77 import java.util.function.Consumer; 78 79 import javax.inject.Inject; 80 81 /** 82 * Controller for {@link NotificationShadeWindowView}. 83 */ 84 @SysUISingleton 85 public class NotificationShadeWindowViewController { 86 private static final String TAG = "NotifShadeWindowVC"; 87 private final FalsingCollector mFalsingCollector; 88 private final SysuiStatusBarStateController mStatusBarStateController; 89 private final NotificationShadeWindowView mView; 90 private final NotificationShadeDepthController mDepthController; 91 private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController; 92 private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; 93 private final LockIconViewController mLockIconViewController; 94 private final ShadeLogger mShadeLogger; 95 private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; 96 private final StatusBarWindowStateController mStatusBarWindowStateController; 97 private final KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; 98 private final AmbientState mAmbientState; 99 private final PulsingGestureListener mPulsingGestureListener; 100 private final LockscreenHostedDreamGestureListener mLockscreenHostedDreamGestureListener; 101 private final NotificationInsetsController mNotificationInsetsController; 102 private final boolean mIsTrackpadCommonEnabled; 103 private final FeatureFlags mFeatureFlags; 104 private final KeyEventInteractor mKeyEventInteractor; 105 private GestureDetector mPulsingWakeupGestureHandler; 106 private GestureDetector mDreamingWakeupGestureHandler; 107 private View mBrightnessMirror; 108 private boolean mTouchActive; 109 private boolean mTouchCancelled; 110 private MotionEvent mDownEvent; 111 // TODO rename to mLaunchAnimationRunning 112 private boolean mExpandAnimationRunning; 113 /** 114 * When mExpandAnimationRunning is true and the touch dispatcher receives a down even after 115 * uptime exceeds this, the dispatcher will stop blocking touches for the launch animation, 116 * which has presumabely not completed due to an error. 117 */ 118 private long mLaunchAnimationTimeout; 119 private NotificationStackScrollLayout mStackScrollLayout; 120 private PhoneStatusBarViewController mStatusBarViewController; 121 private final CentralSurfaces mService; 122 private final BackActionInteractor mBackActionInteractor; 123 private final PowerInteractor mPowerInteractor; 124 private final NotificationShadeWindowController mNotificationShadeWindowController; 125 private DragDownHelper mDragDownHelper; 126 private boolean mExpandingBelowNotch; 127 private final DockManager mDockManager; 128 private final NotificationPanelViewController mNotificationPanelViewController; 129 private final ShadeExpansionStateManager mShadeExpansionStateManager; 130 131 private boolean mIsTrackingBarGesture = false; 132 private boolean mIsOcclusionTransitionRunning = false; 133 private DisableSubpixelTextTransitionListener mDisableSubpixelTextTransitionListener; 134 private final Consumer<TransitionStep> mLockscreenToDreamingTransition = 135 (TransitionStep step) -> { 136 mIsOcclusionTransitionRunning = 137 step.getTransitionState() == TransitionState.RUNNING; 138 }; 139 private final SystemClock mClock; 140 141 @Inject NotificationShadeWindowViewController( LockscreenShadeTransitionController transitionController, FalsingCollector falsingCollector, SysuiStatusBarStateController statusBarStateController, DockManager dockManager, NotificationShadeDepthController depthController, NotificationShadeWindowView notificationShadeWindowView, NotificationPanelViewController notificationPanelViewController, ShadeExpansionStateManager shadeExpansionStateManager, NotificationStackScrollLayoutController notificationStackScrollLayoutController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, StatusBarWindowStateController statusBarWindowStateController, LockIconViewController lockIconViewController, CentralSurfaces centralSurfaces, BackActionInteractor backActionInteractor, PowerInteractor powerInteractor, NotificationShadeWindowController controller, Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider, KeyguardUnlockAnimationController keyguardUnlockAnimationController, NotificationInsetsController notificationInsetsController, AmbientState ambientState, ShadeLogger shadeLogger, PulsingGestureListener pulsingGestureListener, LockscreenHostedDreamGestureListener lockscreenHostedDreamGestureListener, KeyguardBouncerViewModel keyguardBouncerViewModel, KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory, KeyguardMessageAreaController.Factory messageAreaControllerFactory, KeyguardTransitionInteractor keyguardTransitionInteractor, PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel, NotificationExpansionRepository notificationExpansionRepository, FeatureFlags featureFlags, SystemClock clock, BouncerMessageInteractor bouncerMessageInteractor, BouncerLogger bouncerLogger, KeyEventInteractor keyEventInteractor)142 public NotificationShadeWindowViewController( 143 LockscreenShadeTransitionController transitionController, 144 FalsingCollector falsingCollector, 145 SysuiStatusBarStateController statusBarStateController, 146 DockManager dockManager, 147 NotificationShadeDepthController depthController, 148 NotificationShadeWindowView notificationShadeWindowView, 149 NotificationPanelViewController notificationPanelViewController, 150 ShadeExpansionStateManager shadeExpansionStateManager, 151 NotificationStackScrollLayoutController notificationStackScrollLayoutController, 152 StatusBarKeyguardViewManager statusBarKeyguardViewManager, 153 StatusBarWindowStateController statusBarWindowStateController, 154 LockIconViewController lockIconViewController, 155 CentralSurfaces centralSurfaces, 156 BackActionInteractor backActionInteractor, 157 PowerInteractor powerInteractor, 158 NotificationShadeWindowController controller, 159 Optional<UnfoldTransitionProgressProvider> unfoldTransitionProgressProvider, 160 KeyguardUnlockAnimationController keyguardUnlockAnimationController, 161 NotificationInsetsController notificationInsetsController, 162 AmbientState ambientState, 163 ShadeLogger shadeLogger, 164 PulsingGestureListener pulsingGestureListener, 165 LockscreenHostedDreamGestureListener lockscreenHostedDreamGestureListener, 166 KeyguardBouncerViewModel keyguardBouncerViewModel, 167 KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory, 168 KeyguardMessageAreaController.Factory messageAreaControllerFactory, 169 KeyguardTransitionInteractor keyguardTransitionInteractor, 170 PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel, 171 NotificationExpansionRepository notificationExpansionRepository, 172 FeatureFlags featureFlags, 173 SystemClock clock, 174 BouncerMessageInteractor bouncerMessageInteractor, 175 BouncerLogger bouncerLogger, 176 KeyEventInteractor keyEventInteractor) { 177 mLockscreenShadeTransitionController = transitionController; 178 mFalsingCollector = falsingCollector; 179 mStatusBarStateController = statusBarStateController; 180 mView = notificationShadeWindowView; 181 mDockManager = dockManager; 182 mNotificationPanelViewController = notificationPanelViewController; 183 mShadeExpansionStateManager = shadeExpansionStateManager; 184 mDepthController = depthController; 185 mNotificationStackScrollLayoutController = notificationStackScrollLayoutController; 186 mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; 187 mStatusBarWindowStateController = statusBarWindowStateController; 188 mLockIconViewController = lockIconViewController; 189 mBackActionInteractor = backActionInteractor; 190 mShadeLogger = shadeLogger; 191 mLockIconViewController.init(); 192 mService = centralSurfaces; 193 mPowerInteractor = powerInteractor; 194 mNotificationShadeWindowController = controller; 195 mKeyguardUnlockAnimationController = keyguardUnlockAnimationController; 196 mAmbientState = ambientState; 197 mPulsingGestureListener = pulsingGestureListener; 198 mLockscreenHostedDreamGestureListener = lockscreenHostedDreamGestureListener; 199 mNotificationInsetsController = notificationInsetsController; 200 mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON); 201 mFeatureFlags = featureFlags; 202 mKeyEventInteractor = keyEventInteractor; 203 204 // This view is not part of the newly inflated expanded status bar. 205 mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container); 206 mDisableSubpixelTextTransitionListener = new DisableSubpixelTextTransitionListener(mView); 207 KeyguardBouncerViewBinder.bind( 208 mView.findViewById(R.id.keyguard_bouncer_container), 209 keyguardBouncerViewModel, 210 primaryBouncerToGoneTransitionViewModel, 211 keyguardBouncerComponentFactory, 212 messageAreaControllerFactory, 213 bouncerMessageInteractor, 214 bouncerLogger, 215 featureFlags); 216 217 collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(), 218 mLockscreenToDreamingTransition); 219 collectFlow( 220 mView, 221 notificationExpansionRepository.isExpandAnimationRunning(), 222 this::setExpandAnimationRunning); 223 224 mClock = clock; 225 if (featureFlags.isEnabled(Flags.SPLIT_SHADE_SUBPIXEL_OPTIMIZATION)) { 226 unfoldTransitionProgressProvider.ifPresent( 227 progressProvider -> progressProvider.addCallback( 228 mDisableSubpixelTextTransitionListener)); 229 } 230 } 231 232 /** 233 * @return Location where to place the KeyguardMessageArea 234 */ getKeyguardMessageArea()235 public AuthKeyguardMessageArea getKeyguardMessageArea() { 236 return mView.findViewById(R.id.keyguard_message_area); 237 } 238 logDownDispatch(MotionEvent ev, String msg, Boolean result)239 private Boolean logDownDispatch(MotionEvent ev, String msg, Boolean result) { 240 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 241 mShadeLogger.logShadeWindowDispatch(ev, msg, result); 242 } 243 return result; 244 } 245 246 /** Inflates the {@link R.layout#status_bar_expanded} layout and sets it up. */ setupExpandedStatusBar()247 public void setupExpandedStatusBar() { 248 mStackScrollLayout = mView.findViewById(R.id.notification_stack_scroller); 249 mPulsingWakeupGestureHandler = new GestureDetector(mView.getContext(), 250 mPulsingGestureListener); 251 if (mFeatureFlags.isEnabled(LOCKSCREEN_WALLPAPER_DREAM_ENABLED)) { 252 mDreamingWakeupGestureHandler = new GestureDetector(mView.getContext(), 253 mLockscreenHostedDreamGestureListener); 254 } 255 mView.setLayoutInsetsController(mNotificationInsetsController); 256 mView.setInteractionEventHandler(new NotificationShadeWindowView.InteractionEventHandler() { 257 @Override 258 public Boolean handleDispatchTouchEvent(MotionEvent ev) { 259 if (mStatusBarViewController == null) { // Fix for b/192490822 260 return logDownDispatch(ev, 261 "Ignoring touch while statusBarView not yet set", false); 262 } 263 boolean isDown = ev.getActionMasked() == MotionEvent.ACTION_DOWN; 264 boolean isUp = ev.getActionMasked() == MotionEvent.ACTION_UP; 265 boolean isCancel = ev.getActionMasked() == MotionEvent.ACTION_CANCEL; 266 267 boolean expandingBelowNotch = mExpandingBelowNotch; 268 if (isUp || isCancel) { 269 mExpandingBelowNotch = false; 270 } 271 272 // Reset manual touch dispatch state here but make sure the UP/CANCEL event still 273 // gets delivered. 274 if (!isCancel && mService.shouldIgnoreTouch()) { 275 return logDownDispatch(ev, "touch ignored by CS", false); 276 } 277 278 if (isDown) { 279 mTouchActive = true; 280 mTouchCancelled = false; 281 mDownEvent = ev; 282 } else if (ev.getActionMasked() == MotionEvent.ACTION_UP 283 || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) { 284 mTouchActive = false; 285 mDownEvent = null; 286 } 287 if (mTouchCancelled) { 288 return logDownDispatch(ev, "touch cancelled", false); 289 } 290 if (mExpandAnimationRunning) { 291 if (isDown && mClock.uptimeMillis() > mLaunchAnimationTimeout) { 292 Log.wtf(TAG, "NSWVC: launch animation timed out"); 293 setExpandAnimationRunning(false); 294 } else { 295 return logDownDispatch(ev, "expand animation running", false); 296 } 297 } 298 299 if (mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) { 300 // If the user was sliding their finger across the lock screen, 301 // we may have been intercepting the touch and forwarding it to the 302 // UDFPS affordance via mStatusBarKeyguardViewManager.onTouch (see below). 303 // If this touch ended up unlocking the device, we want to cancel the touch 304 // immediately, so we don't cause swipe or expand animations afterwards. 305 cancelCurrentTouch(); 306 return true; 307 } 308 309 if (mIsOcclusionTransitionRunning) { 310 return logDownDispatch(ev, "occlusion transition running", false); 311 } 312 313 mFalsingCollector.onTouchEvent(ev); 314 mPulsingWakeupGestureHandler.onTouchEvent(ev); 315 if (mDreamingWakeupGestureHandler != null 316 && mDreamingWakeupGestureHandler.onTouchEvent(ev)) { 317 return logDownDispatch(ev, "dream wakeup gesture handled", true); 318 } 319 if (mStatusBarKeyguardViewManager.dispatchTouchEvent(ev)) { 320 return logDownDispatch(ev, "dispatched to Keyguard", true); 321 } 322 if (mBrightnessMirror != null 323 && mBrightnessMirror.getVisibility() == View.VISIBLE) { 324 // Disallow new pointers while the brightness mirror is visible. This is so that 325 // you can't touch anything other than the brightness slider while the mirror is 326 // showing and the rest of the panel is transparent. 327 if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { 328 return logDownDispatch(ev, "disallowed new pointer", false); 329 } 330 } 331 if (isDown) { 332 mNotificationStackScrollLayoutController.closeControlsIfOutsideTouch(ev); 333 } 334 335 if (mStatusBarStateController.isDozing()) { 336 mService.extendDozePulse(); 337 } 338 mLockIconViewController.onTouchEvent( 339 ev, 340 /* onGestureDetectedRunnable */ 341 () -> { 342 mService.userActivity(); 343 mPowerInteractor.wakeUpIfDozing( 344 "LOCK_ICON_TOUCH", 345 PowerManager.WAKE_REASON_GESTURE); 346 } 347 ); 348 349 // In case we start outside of the view bounds (below the status bar), we need to 350 // dispatch 351 // the touch manually as the view system can't accommodate for touches outside of 352 // the 353 // regular view bounds. 354 if (isDown && ev.getY() >= mView.getBottom()) { 355 mExpandingBelowNotch = true; 356 expandingBelowNotch = true; 357 } 358 if (expandingBelowNotch) { 359 return logDownDispatch(ev, 360 "expand below notch. sending touch to status bar", 361 mStatusBarViewController.sendTouchToView(ev)); 362 } 363 364 if (!mIsTrackingBarGesture && isDown 365 && mNotificationPanelViewController.isFullyCollapsed()) { 366 float x = ev.getRawX(); 367 float y = ev.getRawY(); 368 if (mStatusBarViewController.touchIsWithinView(x, y)) { 369 if (mStatusBarWindowStateController.windowIsShowing()) { 370 mIsTrackingBarGesture = true; 371 return logDownDispatch(ev, "sending touch to status bar", 372 mStatusBarViewController.sendTouchToView(ev)); 373 } else { 374 return logDownDispatch(ev, "hidden or hiding", true); 375 } 376 } 377 } else if (mIsTrackingBarGesture) { 378 final boolean sendToStatusBar = mStatusBarViewController.sendTouchToView(ev); 379 if (isUp || isCancel) { 380 mIsTrackingBarGesture = false; 381 } 382 return logDownDispatch(ev, "sending bar gesture to status bar", 383 sendToStatusBar); 384 } 385 return logDownDispatch(ev, "no custom touch dispatch of down event", null); 386 } 387 388 @Override 389 public void dispatchTouchEventComplete() { 390 mFalsingCollector.onMotionEventComplete(); 391 } 392 393 @Override 394 public boolean shouldInterceptTouchEvent(MotionEvent ev) { 395 if (mStatusBarStateController.isDozing() && !mService.isPulsing() 396 && !mDockManager.isDocked()) { 397 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 398 mShadeLogger.d("NSWVC: capture all touch events in always-on"); 399 } 400 return true; 401 } 402 403 if (mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(ev)) { 404 // Don't allow touches to proceed to underlying views if alternate 405 // bouncer is showing 406 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 407 mShadeLogger.d("NSWVC: alt bouncer showing"); 408 } 409 return true; 410 } 411 412 if (mLockIconViewController.onInterceptTouchEvent(ev)) { 413 // immediately return true; don't send the touch to the drag down helper 414 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 415 mShadeLogger.d("NSWVC: don't send touch to drag down helper"); 416 } 417 return true; 418 } 419 420 if (mNotificationPanelViewController.isFullyExpanded() 421 && mDragDownHelper.isDragDownEnabled() 422 && !mService.isBouncerShowing() 423 && !mStatusBarStateController.isDozing()) { 424 boolean result = mDragDownHelper.onInterceptTouchEvent(ev); 425 if (result) { 426 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 427 mShadeLogger.d("NSWVC: drag down helper intercepted"); 428 } 429 } 430 return result; 431 } else { 432 return false; 433 } 434 } 435 436 @Override 437 public void didIntercept(MotionEvent ev) { 438 MotionEvent cancellation = MotionEvent.obtain(ev); 439 cancellation.setAction(MotionEvent.ACTION_CANCEL); 440 mStackScrollLayout.onInterceptTouchEvent(cancellation); 441 mNotificationPanelViewController.handleExternalInterceptTouch(cancellation); 442 cancellation.recycle(); 443 } 444 445 @Override 446 public boolean handleTouchEvent(MotionEvent ev) { 447 boolean handled = false; 448 if (mStatusBarStateController.isDozing()) { 449 handled = !mService.isPulsing(); 450 } 451 452 if (mStatusBarKeyguardViewManager.onTouch(ev)) { 453 return true; 454 } 455 456 if (mDragDownHelper.isDragDownEnabled() 457 || mDragDownHelper.isDraggingDown()) { 458 // we still want to finish our drag down gesture when locking the screen 459 return mDragDownHelper.onTouchEvent(ev) || handled; 460 } else { 461 return handled; 462 } 463 } 464 465 @Override 466 public void didNotHandleTouchEvent(MotionEvent ev) { 467 final int action = ev.getActionMasked(); 468 if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { 469 mService.setInteracting(StatusBarManager.WINDOW_STATUS_BAR, false); 470 } 471 } 472 473 @Override 474 public boolean interceptMediaKey(KeyEvent event) { 475 return mKeyEventInteractor.interceptMediaKey(event); 476 } 477 478 @Override 479 public boolean dispatchKeyEventPreIme(KeyEvent event) { 480 return mKeyEventInteractor.dispatchKeyEventPreIme(event); 481 } 482 483 @Override 484 public boolean dispatchKeyEvent(KeyEvent event) { 485 return mKeyEventInteractor.dispatchKeyEvent(event); 486 } 487 }); 488 489 mView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() { 490 @Override 491 public void onChildViewAdded(View parent, View child) { 492 if (child.getId() == R.id.brightness_mirror_container) { 493 mBrightnessMirror = child; 494 } 495 } 496 497 @Override 498 public void onChildViewRemoved(View parent, View child) { 499 } 500 }); 501 502 setDragDownHelper(mLockscreenShadeTransitionController.getTouchHelper()); 503 504 mDepthController.setRoot(mView); 505 ShadeExpansionChangeEvent currentState = 506 mShadeExpansionStateManager.addExpansionListener(mDepthController); 507 mDepthController.onPanelExpansionChanged(currentState); 508 } 509 getView()510 public NotificationShadeWindowView getView() { 511 return mView; 512 } 513 cancelCurrentTouch()514 public void cancelCurrentTouch() { 515 mShadeLogger.d("NSWVC: cancelling current touch"); 516 if (mTouchActive) { 517 final long now = mClock.uptimeMillis(); 518 final MotionEvent event; 519 if (mIsTrackpadCommonEnabled) { 520 event = MotionEvent.obtain(mDownEvent); 521 event.setDownTime(now); 522 event.setAction(MotionEvent.ACTION_CANCEL); 523 event.setLocation(0.0f, 0.0f); 524 } else { 525 event = MotionEvent.obtain(now, now, 526 MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0); 527 event.setSource(InputDevice.SOURCE_TOUCHSCREEN); 528 } 529 Log.w(TAG, "Canceling current touch event (should be very rare)"); 530 mView.dispatchTouchEvent(event); 531 event.recycle(); 532 mTouchCancelled = true; 533 } 534 mAmbientState.setSwipingUp(false); 535 } 536 dump(PrintWriter pw, String[] args)537 public void dump(PrintWriter pw, String[] args) { 538 pw.print(" mExpandAnimationRunning="); 539 pw.println(mExpandAnimationRunning); 540 pw.print(" mTouchCancelled="); 541 pw.println(mTouchCancelled); 542 pw.print(" mTouchActive="); 543 pw.println(mTouchActive); 544 } 545 546 @VisibleForTesting setExpandAnimationRunning(boolean running)547 void setExpandAnimationRunning(boolean running) { 548 if (mExpandAnimationRunning != running) { 549 // TODO(b/288507023): Remove this log. 550 if (ActivityLaunchAnimator.DEBUG_LAUNCH_ANIMATION) { 551 Log.d(TAG, "Setting mExpandAnimationRunning=" + running); 552 } 553 if (running) { 554 mLaunchAnimationTimeout = mClock.uptimeMillis() + 5000; 555 } 556 mExpandAnimationRunning = running; 557 mNotificationShadeWindowController.setLaunchingActivity(mExpandAnimationRunning); 558 } 559 } 560 cancelExpandHelper()561 public void cancelExpandHelper() { 562 if (mStackScrollLayout != null) { 563 mStackScrollLayout.cancelExpandHelper(); 564 } 565 } 566 setStatusBarViewController(PhoneStatusBarViewController statusBarViewController)567 public void setStatusBarViewController(PhoneStatusBarViewController statusBarViewController) { 568 mStatusBarViewController = statusBarViewController; 569 } 570 571 @VisibleForTesting setDragDownHelper(DragDownHelper dragDownHelper)572 void setDragDownHelper(DragDownHelper dragDownHelper) { 573 mDragDownHelper = dragDownHelper; 574 } 575 } 576