Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 366757bd authored by Yining Liu's avatar Yining Liu
Browse files

Inactive NSSL for touch when blurred out on lockscreen

Disable NSSL from handling touch events when it's blurred out on
lockscreen. Instead, we want the flexi scene container to handle
the touches. Note that we need to make further changes if we
decide to show HUNs on this state as currently we disabled all
notifications from being clickable at this state.

When interactive is false, NSSL and descendants will not be
focusable or selectable by a11y.

Fix: 420601264
Test: manual
Flag: com.android.systemui.scene_container
Change-Id: Id5d6eebd4490cd4c68a91e0981bf427aa4e7093e
parent 705beb0e
Loading
Loading
Loading
Loading
+35 −1
Original line number Diff line number Diff line
@@ -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()) {
@@ -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) {
@@ -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);
@@ -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;
        }
+11 −0
Original line number Diff line number Diff line
@@ -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
@@ -105,6 +115,7 @@ class ScrollViewFields {
            pw.println("negativeClippingShape", negativeClippingShape)
            pw.println("scrollState", scrollState)
            pw.println("intrinsicStackHeight", intrinsicStackHeight)
            pw.println("interactive", interactive)
        }
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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)

+1 −0
Original line number Diff line number Diff line
@@ -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 {
+7 −0
Original line number Diff line number Diff line
@@ -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