Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +35 −1 Original line number Diff line number Diff line Loading @@ -1241,6 +1241,29 @@ public class NotificationStackScrollLayout this.setVisibility(isOccluded ? View.INVISIBLE : View.VISIBLE); } @Override public void setInteractive(boolean interactive) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode() || mScrollViewFields.interactive == interactive) { return; } mScrollViewFields.interactive = interactive; setImportantForAccessibility( mScrollViewFields.interactive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS ); setDescendantFocusability( mScrollViewFields.interactive ? FOCUS_AFTER_DESCENDANTS : FOCUS_BLOCK_DESCENDANTS ); // We don't want the NSSL to be focusable unless both mScrollViewFields.interactive and // mScrollable are true setFocusable(mScrollViewFields.interactive && mScrollable); } @Override public void setScrollState(@NonNull ShadeScrollState scrollState) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { Loading Loading @@ -3850,6 +3873,9 @@ public class NotificationStackScrollLayout @Override public boolean onTouchEvent(MotionEvent ev) { // When NSSL is not active for touch if (SceneContainerFlag.isEnabled() && !mScrollViewFields.interactive) return false; if (mTouchHandler != null) { boolean touchHandled = mTouchHandler.onTouchEvent(ev); if (SceneContainerFlag.isEnabled() || touchHandled) { Loading @@ -3870,7 +3896,8 @@ public class NotificationStackScrollLayout if (action == MotionEvent.ACTION_DOWN && !isTouchInGuts) { mController.closeControlsDueToOutsideTouch(); } if (mIsBeingDragged || mExpandingNotification) { if (mIsBeingDragged || mExpandingNotification || !mScrollViewFields.interactive) { // Dispatch TouchEvent to the scene framework boolean isUpOrCancel = action == ACTION_UP || action == ACTION_CANCEL; if (mSendingTouchesToSceneFramework) { MotionEvent adjustedEvent = MotionEvent.obtain(ev); Loading Loading @@ -4225,6 +4252,13 @@ public class NotificationStackScrollLayout @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!mScrollViewFields.interactive) { // When mScrollViewFields.interactive is false, NSSL will intercept TouchEvents to // prevent its children from handling touches. NSSL#onTouchEvent() will return false so // that neither NSSL or its children consume TouchEvents. Instead, the SceneContainer // Framework will handle. return true; } if (mTouchHandler != null && mTouchHandler.onInterceptTouchEvent(ev)) { return true; } Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt +11 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,16 @@ class ScrollViewFields { */ @JvmField var intrinsicStackHeight: Int = 0 /** * Whether the NSSL is interactive for touch-handling. When false, neither NSSL or its * descendants handle touches. NSSL will dispatch TouchEvents to the scene container framework. * This is achieved by NSSL intercepting TouchEvents and returning false in onTouchEvent(). * * When mIsInteractive is false, NSSL and its child are not focusable or selectable by * accessibility. */ @JvmField var interactive = true /** * When internal NSSL expansion requires the stack to be scrolled (e.g. to keep an expanding * notification in view), that scroll amount can be sent here and it will be handled by the Loading Loading @@ -105,6 +115,7 @@ class ScrollViewFields { pw.println("negativeClippingShape", negativeClippingShape) pw.println("scrollState", scrollState) pw.println("intrinsicStackHeight", intrinsicStackHeight) pw.println("interactive", interactive) } } } packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt +5 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,11 @@ interface NotificationScrollView { */ fun setBlurRadius(radius: Float) /** Set whether this view is active for touch, focus, and accessibility. */ fun setInteractive(blurredOut: Boolean) fun setEnabled(enabled: Boolean) /** set the y position in px of the top of the stack in this view's coordinates */ fun setStackTop(stackTop: Float) Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ constructor( launch { viewModel.qsExpandFraction.collectTraced { view.setQsExpandFraction(it) } } if (Flags.notificationShadeBlur()) { launch { viewModel.blurRadius(maxBlurRadius).collect(view::setBlurRadius) } launch { viewModel.interactive.collectTraced(view::setInteractive) } } launch { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt +7 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,13 @@ constructor( flowOf(0f) } /** * Whether the Notifications are interactive for touches, accessibility, and focus. When false, * scene container will handle touches. */ val interactive: Flow<Boolean> = blurFraction.map { it != 1f }.distinctUntilChanged().dumpWhileCollecting("interactive") /** Whether we should close any open notification guts. */ val shouldCloseGuts: Flow<Boolean> = stackAppearanceInteractor.shouldCloseGuts Loading Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java +35 −1 Original line number Diff line number Diff line Loading @@ -1241,6 +1241,29 @@ public class NotificationStackScrollLayout this.setVisibility(isOccluded ? View.INVISIBLE : View.VISIBLE); } @Override public void setInteractive(boolean interactive) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode() || mScrollViewFields.interactive == interactive) { return; } mScrollViewFields.interactive = interactive; setImportantForAccessibility( mScrollViewFields.interactive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES : View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS ); setDescendantFocusability( mScrollViewFields.interactive ? FOCUS_AFTER_DESCENDANTS : FOCUS_BLOCK_DESCENDANTS ); // We don't want the NSSL to be focusable unless both mScrollViewFields.interactive and // mScrollable are true setFocusable(mScrollViewFields.interactive && mScrollable); } @Override public void setScrollState(@NonNull ShadeScrollState scrollState) { if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) { Loading Loading @@ -3850,6 +3873,9 @@ public class NotificationStackScrollLayout @Override public boolean onTouchEvent(MotionEvent ev) { // When NSSL is not active for touch if (SceneContainerFlag.isEnabled() && !mScrollViewFields.interactive) return false; if (mTouchHandler != null) { boolean touchHandled = mTouchHandler.onTouchEvent(ev); if (SceneContainerFlag.isEnabled() || touchHandled) { Loading @@ -3870,7 +3896,8 @@ public class NotificationStackScrollLayout if (action == MotionEvent.ACTION_DOWN && !isTouchInGuts) { mController.closeControlsDueToOutsideTouch(); } if (mIsBeingDragged || mExpandingNotification) { if (mIsBeingDragged || mExpandingNotification || !mScrollViewFields.interactive) { // Dispatch TouchEvent to the scene framework boolean isUpOrCancel = action == ACTION_UP || action == ACTION_CANCEL; if (mSendingTouchesToSceneFramework) { MotionEvent adjustedEvent = MotionEvent.obtain(ev); Loading Loading @@ -4225,6 +4252,13 @@ public class NotificationStackScrollLayout @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!mScrollViewFields.interactive) { // When mScrollViewFields.interactive is false, NSSL will intercept TouchEvents to // prevent its children from handling touches. NSSL#onTouchEvent() will return false so // that neither NSSL or its children consume TouchEvents. Instead, the SceneContainer // Framework will handle. return true; } if (mTouchHandler != null && mTouchHandler.onInterceptTouchEvent(ev)) { return true; } Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ScrollViewFields.kt +11 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,16 @@ class ScrollViewFields { */ @JvmField var intrinsicStackHeight: Int = 0 /** * Whether the NSSL is interactive for touch-handling. When false, neither NSSL or its * descendants handle touches. NSSL will dispatch TouchEvents to the scene container framework. * This is achieved by NSSL intercepting TouchEvents and returning false in onTouchEvent(). * * When mIsInteractive is false, NSSL and its child are not focusable or selectable by * accessibility. */ @JvmField var interactive = true /** * When internal NSSL expansion requires the stack to be scrolled (e.g. to keep an expanding * notification in view), that scroll amount can be sent here and it will be handled by the Loading Loading @@ -105,6 +115,7 @@ class ScrollViewFields { pw.println("negativeClippingShape", negativeClippingShape) pw.println("scrollState", scrollState) pw.println("intrinsicStackHeight", intrinsicStackHeight) pw.println("interactive", interactive) } } }
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt +5 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,11 @@ interface NotificationScrollView { */ fun setBlurRadius(radius: Float) /** Set whether this view is active for touch, focus, and accessibility. */ fun setInteractive(blurredOut: Boolean) fun setEnabled(enabled: Boolean) /** set the y position in px of the top of the stack in this view's coordinates */ fun setStackTop(stackTop: Float) Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt +1 −0 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ constructor( launch { viewModel.qsExpandFraction.collectTraced { view.setQsExpandFraction(it) } } if (Flags.notificationShadeBlur()) { launch { viewModel.blurRadius(maxBlurRadius).collect(view::setBlurRadius) } launch { viewModel.interactive.collectTraced(view::setInteractive) } } launch { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt +7 −0 Original line number Diff line number Diff line Loading @@ -237,6 +237,13 @@ constructor( flowOf(0f) } /** * Whether the Notifications are interactive for touches, accessibility, and focus. When false, * scene container will handle touches. */ val interactive: Flow<Boolean> = blurFraction.map { it != 1f }.distinctUntilChanged().dumpWhileCollecting("interactive") /** Whether we should close any open notification guts. */ val shouldCloseGuts: Flow<Boolean> = stackAppearanceInteractor.shouldCloseGuts Loading