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

Commit 3cd40e06 authored by Fabian Kozynski's avatar Fabian Kozynski
Browse files

Fix some entrance animations for new QSHeaders

* Use qsVisible to indicate whether the shade is visible and the header
should be shown.
* When in lockscreen, use
LockscreenShadeTransitionController#dragProgress to track shade
expansion.
* Use this shade expansion to fade out the KeyguardStatusBarView

Test: manual, with and without flag, handheld and split shade
Test: atest SystemUITests
Bug: 202847414
Change-Id: Id57adff2fd75eba86832e8790816ef2d9afcf83d
parent 3555ebc8
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -23,11 +23,22 @@
        app:constraintSetEnd="@id/qs_header_constraint"
        app:constraintSetStart="@id/qqs_header_constraint">
        <KeyFrameSet>
            <!-- These positions are to prevent visual movement of @id/date -->
            <KeyPosition
                app:keyPositionType="pathRelative"
                app:percentX="0"
                app:framePosition="50"
                app:framePosition="49"
                app:motionTarget="@id/date" />
            <KeyPosition
                app:keyPositionType="pathRelative"
                app:percentX="1"
                app:framePosition="51"
                app:motionTarget="@id/date" />
            <KeyAttribute
                app:motionTarget="@id/date"
                app:framePosition="50"
                android:alpha="0"
                />
        </KeyFrameSet>
    </Transition>

+5 −2
Original line number Diff line number Diff line
@@ -298,8 +298,8 @@ class LockscreenShadeTransitionController @Inject constructor(
                    nsslController.setTransitionToFullShadeAmount(field)
                    notificationPanelController.setTransitionToFullShadeAmount(field,
                            false /* animate */, 0 /* delay */)
                    val progress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
                    qS.setTransitionToFullShadeAmount(field, progress)
                    dragProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
                    qS.setTransitionToFullShadeAmount(field, dragProgress)
                    // TODO: appear media also in split shade
                    val mediaAmount = if (useSplitShade) 0f else field
                    mediaHierarchyManager.setTransitionToFullShadeAmount(mediaAmount)
@@ -308,6 +308,9 @@ class LockscreenShadeTransitionController @Inject constructor(
            }
        }

    var dragProgress = 0f
        private set

    private fun transitionToShadeAmountCommon(dragDownAmount: Float) {
        val scrimProgress = MathUtils.saturate(dragDownAmount / scrimTransitionDistance)
        scrimController.setTransitionToFullShadeProgress(scrimProgress)
+1 −1
Original line number Diff line number Diff line
@@ -392,7 +392,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
        }

        float alphaQsExpansion = 1 - Math.min(
                1, mNotificationPanelViewStateProvider.getQsExpansionFraction() * 2);
                1, mNotificationPanelViewStateProvider.getLockscreenShadeDragProgress() * 2);
        float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
                * mKeyguardStatusBarAnimateAlpha
                * (1.0f - mKeyguardHeadsUpShowingAmount);
+37 −10
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;

import static android.view.View.GONE;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;

import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
@@ -33,7 +34,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
import static com.android.systemui.statusbar.StatusBarState.SHADE;
import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.ROWS_ALL;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD;
import static com.android.systemui.statusbar.phone.panelstate.PanelExpansionStateManagerKt.STATE_CLOSED;
@@ -466,6 +466,9 @@ public class NotificationPanelViewController extends PanelViewController {
    private boolean mIsFullWidth;
    private boolean mBlockingExpansionForCurrentTouch;

    // TODO (b/204204226): no longer needed once refactor is complete
    private final boolean mUseCombinedQSHeaders;

    /**
     * Following variables maintain state of events when input focus transfer may occur.
     */
@@ -913,6 +916,8 @@ public class NotificationPanelViewController extends PanelViewController {
        mQsFrameTranslateController = qsFrameTranslateController;
        updateUserSwitcherFlags();
        onFinishInflate();

        mUseCombinedQSHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS);
    }

    private void onFinishInflate() {
@@ -1142,6 +1147,9 @@ public class NotificationPanelViewController extends PanelViewController {
        } else {
            constraintSet.connect(R.id.qs_frame, END, PARENT_ID, END);
            constraintSet.connect(R.id.notification_stack_scroller, START, PARENT_ID, START);
            if (mUseCombinedQSHeaders) {
                constraintSet.constrainHeight(R.id.split_shade_status_bar, WRAP_CONTENT);
            }
        }
        constraintSet.getConstraint(R.id.notification_stack_scroller).layout.mWidth = panelWidth;
        constraintSet.getConstraint(R.id.qs_frame).layout.mWidth = qsWidth;
@@ -1392,7 +1400,6 @@ public class NotificationPanelViewController extends PanelViewController {
            stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
        }

        mSplitShadeHeaderController.setShadeExpandedFraction(getExpandedFraction());
        mNotificationStackScrollLayoutController.setIntrinsicPadding(stackScrollerPadding);
        mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX);

@@ -2401,7 +2408,6 @@ public class NotificationPanelViewController extends PanelViewController {
                ? 1f : computeQsExpansionFraction();
        mQs.setQsExpansion(adjustedExpansionFraction, getExpandedFraction(), getHeaderTranslation(),
                squishiness);
        mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
        mMediaHierarchyManager.setQsExpansion(qsExpansionFraction);
        int qsPanelBottomY = calculateQsBottomPosition(qsExpansionFraction);
        mScrimController.setQsPosition(qsExpansionFraction, qsPanelBottomY);
@@ -2415,6 +2421,17 @@ public class NotificationPanelViewController extends PanelViewController {

        mDepthController.setQsPanelExpansion(qsExpansionFraction);

        // updateQsExpansion will get called whenever mTransitionToFullShadeProgress or
        // mLockscreenShadeTransitionController.getDragProgress change.
        // When in lockscreen, getDragProgress indicates the true expanded fraction of QS
        float shadeExpandedFraction = mTransitioningToFullShadeProgress > 0
                ? mLockscreenShadeTransitionController.getDragProgress()
                : getExpandedFraction();
        mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
        mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
        mSplitShadeHeaderController.setShadeExpanded(mQsVisible);


        if (mCommunalViewController != null) {
            mCommunalViewController.updateQsExpansion(qsExpansionFraction);
        }
@@ -3629,12 +3646,16 @@ public class NotificationPanelViewController extends PanelViewController {
        return !isFullWidth() || !mShowIconsWhenExpanded;
    }

    public final QS.ScrollListener mScrollListener = scrollY -> {
    public final QS.ScrollListener mScrollListener = new QS.ScrollListener() {
        @Override
        public void onQsPanelScrollChanged(int scrollY) {
            mSplitShadeHeaderController.setQsScrollY(scrollY);
            if (scrollY > 0 && !mQsFullyExpanded) {
                if (DEBUG) Log.d(TAG, "Scrolling while not expanded. Forcing expand");
                // If we are scrolling QS, we should be fully expanded.
                expandWithQs();
            }
        }
    };

    private final FragmentListener mFragmentListener = new FragmentListener() {
@@ -4684,8 +4705,6 @@ public class NotificationPanelViewController extends PanelViewController {
            // would reset
            maybeAnimateBottomAreaAlpha();
            updateQsState();
            mSplitShadeHeaderController.setShadeExpanded(
                    mBarState == SHADE || mBarState == SHADE_LOCKED);
        }

        @Override
@@ -4715,6 +4734,9 @@ public class NotificationPanelViewController extends PanelViewController {
         * {@link KeyguardStatusBarViewController} and remove this method.
         */
        boolean shouldHeadsUpBeVisible();

        /** Return the fraction of the shade that's expanded, when in lockscreen. */
        float getLockscreenShadeDragProgress();
    }

    private final NotificationPanelViewStateProvider mNotificationPanelViewStateProvider =
@@ -4733,6 +4755,11 @@ public class NotificationPanelViewController extends PanelViewController {
                public boolean shouldHeadsUpBeVisible() {
                    return mHeadsUpAppearanceController.shouldBeVisible();
                }

                @Override
                public float getLockscreenShadeDragProgress() {
                    return mLockscreenShadeTransitionController.getDragProgress();
                }
            };

    /**
+52 −7
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import com.android.systemui.R
import com.android.systemui.animation.ShadeInterpolation
import com.android.systemui.battery.BatteryMeterView
import com.android.systemui.battery.BatteryMeterViewController
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.qs.ChipVisibilityListener
@@ -32,6 +33,8 @@ import com.android.systemui.qs.carrier.QSCarrierGroupController
import com.android.systemui.statusbar.phone.dagger.StatusBarComponent.StatusBarScope
import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_BATTERY_CONTROLLER
import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.SPLIT_SHADE_HEADER
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
import javax.inject.Named

@@ -42,12 +45,23 @@ class SplitShadeHeaderController @Inject constructor(
    private val privacyIconsController: HeaderPrivacyIconsController,
    qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder,
    featureFlags: FeatureFlags,
    @Named(SPLIT_SHADE_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController
) {
    @Named(SPLIT_SHADE_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController,
    dumpManager: DumpManager
) : Dumpable {

    companion object {
        private val HEADER_TRANSITION_ID = R.id.header_transition
        private val SPLIT_HEADER_TRANSITION_ID = R.id.split_header_transition
        private val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint
        private val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint
        private val SPLIT_HEADER_CONSTRAINT = R.id.split_header_constraint

        private fun Int.stateToString() = when (this) {
            QQS_HEADER_CONSTRAINT -> "QQS Header"
            QS_HEADER_CONSTRAINT -> "QS Header"
            SPLIT_HEADER_CONSTRAINT -> "Split Header"
            else -> "Unknown state"
        }
    }

    private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)
@@ -99,14 +113,22 @@ class SplitShadeHeaderController @Inject constructor(
            }
        }

    var qsScrollY = 0
        set(value) {
            if (field != value) {
                field = value
                updateScrollY()
            }
        }

    private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener {
        override fun onChipVisibilityRefreshed(visible: Boolean) {
            if (statusBar is MotionLayout) {
                val state = statusBar.getConstraintSet(R.id.qqs_header_constraint).apply {
                val state = statusBar.getConstraintSet(QQS_HEADER_CONSTRAINT).apply {
                    setAlpha(R.id.statusIcons, if (visible) 0f else 1f)
                    setAlpha(R.id.batteryRemainingIcon, if (visible) 0f else 1f)
                }
                statusBar.updateState(R.id.qqs_header_constraint, state)
                statusBar.updateState(QQS_HEADER_CONSTRAINT, state)
            }
        }
    }
@@ -115,11 +137,11 @@ class SplitShadeHeaderController @Inject constructor(
        if (statusBar is MotionLayout) {
            val context = statusBar.context
            val resources = statusBar.resources
            statusBar.getConstraintSet(R.id.qqs_header_constraint)
            statusBar.getConstraintSet(QQS_HEADER_CONSTRAINT)
                    .load(context, resources.getXml(R.xml.qqs_header))
            statusBar.getConstraintSet(R.id.qs_header_constraint)
            statusBar.getConstraintSet(QS_HEADER_CONSTRAINT)
                    .load(context, resources.getXml(R.xml.qs_header))
            statusBar.getConstraintSet(R.id.split_header_constraint)
            statusBar.getConstraintSet(SPLIT_HEADER_CONSTRAINT)
                    .load(context, resources.getXml(R.xml.split_header))
            privacyIconsController.chipVisibilityListener = chipVisibilityListener
        }
@@ -149,10 +171,19 @@ class SplitShadeHeaderController @Inject constructor(
        qsCarrierGroupController = qsCarrierGroupControllerBuilder
                .setQSCarrierGroup(statusBar.findViewById(R.id.carrier_group))
                .build()

        dumpManager.registerDumpable(this)

        updateVisibility()
        updateConstraints()
    }

    private fun updateScrollY() {
        if (!splitShadeMode && combinedHeaders) {
            statusBar.scrollY = qsScrollY
        }
    }

    private fun onShadeExpandedChanged() {
        if (shadeExpanded) {
            privacyIconsController.startListening()
@@ -198,6 +229,7 @@ class SplitShadeHeaderController @Inject constructor(
            statusBar.setTransition(HEADER_TRANSITION_ID)
            statusBar.transitionToStart()
            updatePosition()
            updateScrollY()
        }
    }

@@ -226,4 +258,17 @@ class SplitShadeHeaderController @Inject constructor(
            iconContainer.addIgnoredSlots(carrierIconSlots)
        }
    }

    override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
        pw.println("visible: $visible")
        pw.println("shadeExpanded: $shadeExpanded")
        pw.println("shadeExpandedFraction: $shadeExpandedFraction")
        pw.println("splitShadeMode: $splitShadeMode")
        pw.println("qsExpandedFraction: $qsExpandedFraction")
        pw.println("qsScrollY: $qsScrollY")
        if (combinedHeaders) {
            statusBar as MotionLayout
            pw.println("currentState: ${statusBar.currentState.stateToString()}")
        }
    }
}
Loading