diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml
index 1f10e5dfeed83..405863dc9d92c 100644
--- a/packages/SystemUI/res/layout/combined_qs_header.xml
+++ b/packages/SystemUI/res/layout/combined_qs_header.xml
@@ -101,4 +101,16 @@
app:layout_constraintBottom_toBottomOf="parent"
/>
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/combined_qs_header_scene.xml b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
index d61e4a95bb680..91607d2f9bea6 100644
--- a/packages/SystemUI/res/xml/combined_qs_header_scene.xml
+++ b/packages/SystemUI/res/xml/combined_qs_header_scene.xml
@@ -23,11 +23,22 @@
app:constraintSetEnd="@id/qs_header_constraint"
app:constraintSetStart="@id/qqs_header_constraint">
+
+
+
diff --git a/packages/SystemUI/res/xml/qqs_header.xml b/packages/SystemUI/res/xml/qqs_header.xml
index 3d7b549fc54b8..c5b4c5d776b9a 100644
--- a/packages/SystemUI/res/xml/qqs_header.xml
+++ b/packages/SystemUI/res/xml/qqs_header.xml
@@ -48,6 +48,14 @@
/>
+
+
+
+
+
+
-
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/qs_header.xml b/packages/SystemUI/res/xml/qs_header.xml
index 6a0ab866966ce..8248fcdb50fb9 100644
--- a/packages/SystemUI/res/xml/qs_header.xml
+++ b/packages/SystemUI/res/xml/qs_header.xml
@@ -58,5 +58,14 @@
/>
-
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/res/xml/split_header.xml b/packages/SystemUI/res/xml/split_header.xml
index 44d42a05cd46e..03401b3d51d1f 100644
--- a/packages/SystemUI/res/xml/split_header.xml
+++ b/packages/SystemUI/res/xml/split_header.xml
@@ -53,5 +53,29 @@
/>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 0fb08e4034838..491a1750a93e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -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)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index e7d5724fa9bf1..81871634fbaf8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -392,7 +392,7 @@ public class KeyguardStatusBarViewController extends ViewController 0
+ ? mLockscreenShadeTransitionController.getDragProgress()
+ : getExpandedFraction();
+ mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction);
+ mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction);
+ mSplitShadeHeaderController.setShadeExpanded(mQsVisible);
+
+
if (mCommunalViewController != null) {
mCommunalViewController.updateQsExpansion(qsExpansionFraction);
}
@@ -3629,11 +3646,15 @@ public class NotificationPanelViewController extends PanelViewController {
return !isFullWidth() || !mShowIconsWhenExpanded;
}
- public final QS.ScrollListener mScrollListener = 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();
+ 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();
+ }
}
};
@@ -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();
+ }
};
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
index 8cf7288c9cd5e..a1be5acdac134 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt
@@ -19,17 +19,22 @@ package com.android.systemui.statusbar.phone
import android.view.View
import androidx.constraintlayout.motion.widget.MotionLayout
import com.android.settingslib.Utils
+import com.android.systemui.Dumpable
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
import com.android.systemui.qs.HeaderPrivacyIconsController
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
@@ -40,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)
@@ -97,16 +113,37 @@ 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(QQS_HEADER_CONSTRAINT).apply {
+ setAlpha(R.id.statusIcons, if (visible) 0f else 1f)
+ setAlpha(R.id.batteryRemainingIcon, if (visible) 0f else 1f)
+ }
+ statusBar.updateState(QQS_HEADER_CONSTRAINT, state)
+ }
+ }
+ }
+
init {
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
}
}
@@ -134,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()
@@ -149,7 +195,7 @@ class SplitShadeHeaderController @Inject constructor(
}
private fun onSplitShadeModeChanged() {
- if (splitShadeMode) {
+ if (splitShadeMode || combinedHeaders) {
privacyIconsController.onParentVisible()
} else {
privacyIconsController.onParentInvisible()
@@ -183,6 +229,7 @@ class SplitShadeHeaderController @Inject constructor(
statusBar.setTransition(HEADER_TRANSITION_ID)
statusBar.transitionToStart()
updatePosition()
+ updateScrollY()
}
}
@@ -211,4 +258,17 @@ class SplitShadeHeaderController @Inject constructor(
iconContainer.addIgnoredSlots(carrierIconSlots)
}
}
+
+ override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array) {
+ 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()}")
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
index 8d05e6693e334..37cf7485b8ab7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.java
@@ -278,11 +278,11 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
}
@Test
- public void updateViewState_qsExpansionOne_viewHidden() {
+ public void updateViewState_dragProgressOne_viewHidden() {
mController.onViewAttached();
updateStateToKeyguard();
- mNotificationPanelViewStateProvider.setQsExpansionFraction(1f);
+ mNotificationPanelViewStateProvider.setLockscreenShadeDragProgress(1f);
mController.updateViewState();
@@ -356,6 +356,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
private float mPanelViewExpandedHeight = 100f;
private float mQsExpansionFraction = 0f;
private boolean mShouldHeadsUpBeVisible = false;
+ private float mLockscreenShadeDragProgress = 0f;
@Override
public float getPanelViewExpandedHeight() {
@@ -372,6 +373,11 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
return mShouldHeadsUpBeVisible;
}
+ @Override
+ public float getLockscreenShadeDragProgress() {
+ return mLockscreenShadeDragProgress;
+ }
+
public void setPanelViewExpandedHeight(float panelViewExpandedHeight) {
this.mPanelViewExpandedHeight = panelViewExpandedHeight;
}
@@ -383,5 +389,9 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
public void setShouldHeadsUpBeVisible(boolean shouldHeadsUpBeVisible) {
this.mShouldHeadsUpBeVisible = shouldHeadsUpBeVisible;
}
+
+ public void setLockscreenShadeDragProgress(float lockscreenShadeDragProgress) {
+ this.mLockscreenShadeDragProgress = lockscreenShadeDragProgress;
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt
index a8544a9a15e4c..2b1826eab5aae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt
@@ -8,6 +8,7 @@ import com.android.systemui.SysuiTestCase
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.HeaderPrivacyIconsController
@@ -37,6 +38,7 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() {
@Mock private lateinit var batteryMeterView: BatteryMeterView
@Mock private lateinit var batteryMeterViewController: BatteryMeterViewController
@Mock private lateinit var privacyIconsController: HeaderPrivacyIconsController
+ @Mock private lateinit var dumpManager: DumpManager
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
var viewVisibility = View.GONE
@@ -66,7 +68,8 @@ class SplitShadeHeaderControllerTest : SysuiTestCase() {
privacyIconsController,
qsCarrierGroupControllerBuilder,
featureFlags,
- batteryMeterViewController
+ batteryMeterViewController,
+ dumpManager
)
carrierIconSlots = listOf(
context.getString(com.android.internal.R.string.status_bar_mobile))