From 193baa3ab35d137ad5fb8695ce5ba87d254d6cd0 Mon Sep 17 00:00:00 2001 From: Michal Brzezinski Date: Tue, 22 Mar 2022 11:23:39 +0000 Subject: Renaming SplitShadeHeader to LargeScreenShadeHeader Bug: 222472794 Test: code compiles and works Change-Id: Ifcd1f11546cfb84a4760fb8c2cd134bdf366f8c2 --- .../SystemUI/res/layout/combined_qs_header.xml | 10 +- .../res/layout/large_screen_shade_header.xml | 100 ++++++++ .../SystemUI/res/layout/split_shade_header.xml | 100 -------- packages/SystemUI/res/values-sw600dp/dimens.xml | 2 +- packages/SystemUI/res/values-sw720dp/dimens.xml | 2 +- packages/SystemUI/res/values/dimens.xml | 4 +- .../SystemUI/res/xml/combined_qs_header_scene.xml | 8 +- .../SystemUI/res/xml/large_screen_shade_header.xml | 81 ++++++ packages/SystemUI/res/xml/split_header.xml | 81 ------ .../phone/KeyguardClockPositionAlgorithm.java | 2 +- .../phone/LargeScreenShadeHeaderController.kt | 274 +++++++++++++++++++++ .../phone/NotificationPanelViewController.java | 18 +- .../phone/NotificationsQSContainerController.kt | 2 +- .../statusbar/phone/SplitShadeHeaderController.kt | 274 --------------------- .../phone/dagger/CentralSurfacesComponent.java | 6 +- .../phone/dagger/StatusBarViewModule.java | 19 +- .../com/android/systemui/util/LargeScreenUtils.kt | 2 +- .../phone/KeyguardClockPositionAlgorithmTest.java | 2 +- .../phone/LargeScreenShadeHeaderControllerTest.kt | 123 +++++++++ .../phone/NotificationPanelViewControllerTest.java | 8 +- .../phone/NotificationQSContainerControllerTest.kt | 2 +- .../phone/SplitShadeHeaderControllerTest.kt | 123 --------- 22 files changed, 622 insertions(+), 621 deletions(-) create mode 100644 packages/SystemUI/res/layout/large_screen_shade_header.xml delete mode 100644 packages/SystemUI/res/layout/split_shade_header.xml create mode 100644 packages/SystemUI/res/xml/large_screen_shade_header.xml delete mode 100644 packages/SystemUI/res/xml/split_header.xml create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt delete mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt delete mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt diff --git a/packages/SystemUI/res/layout/combined_qs_header.xml b/packages/SystemUI/res/layout/combined_qs_header.xml index 405863dc9d92..ec82ccf2022e 100644 --- a/packages/SystemUI/res/layout/combined_qs_header.xml +++ b/packages/SystemUI/res/layout/combined_qs_header.xml @@ -20,7 +20,7 @@ android:id="@+id/split_shade_status_bar" android:layout_width="match_parent" android:layout_height="wrap_content" - android:minHeight="@dimen/split_shade_header_min_height" + android:minHeight="@dimen/large_screen_shade_header_min_height" android:clickable="false" android:focusable="true" android:paddingLeft="@dimen/qs_panel_padding" @@ -61,8 +61,8 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/SystemUI/res/layout/split_shade_header.xml b/packages/SystemUI/res/layout/split_shade_header.xml deleted file mode 100644 index b6e96ceeaf20..000000000000 --- a/packages/SystemUI/res/layout/split_shade_header.xml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 59c55d877c9a..2264671e5067 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -68,5 +68,5 @@ 472dp - 42dp + 42dp diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml index be2893fa1e22..07050171470a 100644 --- a/packages/SystemUI/res/values-sw720dp/dimens.xml +++ b/packages/SystemUI/res/values-sw720dp/dimens.xml @@ -21,6 +21,6 @@ 75dp - 56dp + 56dp diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index aeec1331f9cf..a309cc4ff1f5 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -368,8 +368,8 @@ -1px - @*android:dimen/quick_qs_offset_height - @dimen/qs_header_row_min_height + @*android:dimen/quick_qs_offset_height + @dimen/qs_header_row_min_height + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/SystemUI/res/xml/split_header.xml b/packages/SystemUI/res/xml/split_header.xml deleted file mode 100644 index 03401b3d51d1..000000000000 --- a/packages/SystemUI/res/xml/split_header.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index 602d075b167d..83970dc15e61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -148,7 +148,7 @@ public class KeyguardClockPositionAlgorithm { mStatusViewBottomMargin = res.getDimensionPixelSize( R.dimen.keyguard_status_view_bottom_margin); mSplitShadeTopNotificationsMargin = - res.getDimensionPixelSize(R.dimen.split_shade_header_height); + res.getDimensionPixelSize(R.dimen.large_screen_shade_header_height); mSplitShadeTargetTopMargin = res.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt new file mode 100644 index 000000000000..a5fcea789d3a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderController.kt @@ -0,0 +1,274 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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.CentralSurfacesComponent.CentralSurfacesScope +import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_BATTERY_CONTROLLER +import com.android.systemui.statusbar.phone.dagger.StatusBarViewModule.LARGE_SCREEN_SHADE_HEADER +import java.io.FileDescriptor +import java.io.PrintWriter +import javax.inject.Inject +import javax.inject.Named + +@CentralSurfacesScope +class LargeScreenShadeHeaderController @Inject constructor( + @Named(LARGE_SCREEN_SHADE_HEADER) private val header: View, + private val statusBarIconController: StatusBarIconController, + private val privacyIconsController: HeaderPrivacyIconsController, + qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder, + featureFlags: FeatureFlags, + @Named(LARGE_SCREEN_BATTERY_CONTROLLER) batteryMeterViewController: BatteryMeterViewController, + dumpManager: DumpManager +) : Dumpable { + + companion object { + private val HEADER_TRANSITION_ID = R.id.header_transition + private val LARGE_SCREEN_HEADER_TRANSITION_ID = R.id.large_screen_header_transition + private val QQS_HEADER_CONSTRAINT = R.id.qqs_header_constraint + private val QS_HEADER_CONSTRAINT = R.id.qs_header_constraint + private val LARGE_SCREEN_HEADER_CONSTRAINT = R.id.large_screen_header_constraint + + private fun Int.stateToString() = when (this) { + QQS_HEADER_CONSTRAINT -> "QQS Header" + QS_HEADER_CONSTRAINT -> "QS Header" + LARGE_SCREEN_HEADER_CONSTRAINT -> "Large Screen Header" + else -> "Unknown state" + } + } + + private val combinedHeaders = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS) + private val iconManager: StatusBarIconController.TintedIconManager + private val iconContainer: StatusIconContainer + private val carrierIconSlots: List + private val qsCarrierGroupController: QSCarrierGroupController + private var visible = false + set(value) { + if (field == value) { + return + } + field = value + updateListeners() + } + + var shadeExpanded = false + set(value) { + if (field == value) { + return + } + field = value + onShadeExpandedChanged() + } + + var active = false + set(value) { + if (field == value) { + return + } + field = value + onHeaderStateChanged() + } + + var shadeExpandedFraction = -1f + set(value) { + if (visible && field != value) { + header.alpha = ShadeInterpolation.getContentAlpha(value) + field = value + } + } + + var qsExpandedFraction = -1f + set(value) { + if (visible && field != value) { + field = value + updateVisibility() + updatePosition() + } + } + + var qsScrollY = 0 + set(value) { + if (field != value) { + field = value + updateScrollY() + } + } + + private val chipVisibilityListener: ChipVisibilityListener = object : ChipVisibilityListener { + override fun onChipVisibilityRefreshed(visible: Boolean) { + if (header is MotionLayout) { + val state = header.getConstraintSet(QQS_HEADER_CONSTRAINT).apply { + setAlpha(R.id.statusIcons, if (visible) 0f else 1f) + setAlpha(R.id.batteryRemainingIcon, if (visible) 0f else 1f) + } + header.updateState(QQS_HEADER_CONSTRAINT, state) + } + } + } + + init { + if (header is MotionLayout) { + val context = header.context + val resources = header.resources + header.getConstraintSet(QQS_HEADER_CONSTRAINT) + .load(context, resources.getXml(R.xml.qqs_header)) + header.getConstraintSet(QS_HEADER_CONSTRAINT) + .load(context, resources.getXml(R.xml.qs_header)) + header.getConstraintSet(LARGE_SCREEN_HEADER_CONSTRAINT) + .load(context, resources.getXml(R.xml.large_screen_shade_header)) + privacyIconsController.chipVisibilityListener = chipVisibilityListener + } + } + + init { + batteryMeterViewController.init() + val batteryIcon: BatteryMeterView = header.findViewById(R.id.batteryRemainingIcon) + + // battery settings same as in QS icons + batteryMeterViewController.ignoreTunerUpdates() + batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) + + iconContainer = header.findViewById(R.id.statusIcons) + iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags) + iconManager.setTint(Utils.getColorAttrDefaultColor(header.context, + android.R.attr.textColorPrimary)) + + carrierIconSlots = if (featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) { + listOf( + header.context.getString(com.android.internal.R.string.status_bar_no_calling), + header.context.getString(com.android.internal.R.string.status_bar_call_strength) + ) + } else { + listOf(header.context.getString(com.android.internal.R.string.status_bar_mobile)) + } + qsCarrierGroupController = qsCarrierGroupControllerBuilder + .setQSCarrierGroup(header.findViewById(R.id.carrier_group)) + .build() + + dumpManager.registerDumpable(this) + + updateVisibility() + updateConstraints() + } + + private fun updateScrollY() { + if (!active && combinedHeaders) { + header.scrollY = qsScrollY + } + } + + private fun onShadeExpandedChanged() { + if (shadeExpanded) { + privacyIconsController.startListening() + } else { + privacyIconsController.stopListening() + } + updateVisibility() + updatePosition() + } + + private fun onHeaderStateChanged() { + if (active || combinedHeaders) { + privacyIconsController.onParentVisible() + } else { + privacyIconsController.onParentInvisible() + } + updateVisibility() + updateConstraints() + } + + private fun updateVisibility() { + val visibility = if (!active && !combinedHeaders) { + View.GONE + } else if (shadeExpanded) { + View.VISIBLE + } else { + View.INVISIBLE + } + if (header.visibility != visibility) { + header.visibility = visibility + visible = visibility == View.VISIBLE + } + } + + private fun updateConstraints() { + if (!combinedHeaders) { + return + } + header as MotionLayout + if (active) { + header.setTransition(LARGE_SCREEN_HEADER_TRANSITION_ID) + } else { + header.setTransition(HEADER_TRANSITION_ID) + header.transitionToStart() + updatePosition() + updateScrollY() + } + } + + private fun updatePosition() { + if (header is MotionLayout && !active && visible) { + header.setProgress(qsExpandedFraction) + } + } + + private fun updateListeners() { + qsCarrierGroupController.setListening(visible) + if (visible) { + updateSingleCarrier(qsCarrierGroupController.isSingleCarrier) + qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) } + statusBarIconController.addIconGroup(iconManager) + } else { + qsCarrierGroupController.setOnSingleCarrierChangedListener(null) + statusBarIconController.removeIconGroup(iconManager) + } + } + + private fun updateSingleCarrier(singleCarrier: Boolean) { + if (singleCarrier) { + iconContainer.removeIgnoredSlots(carrierIconSlots) + } else { + 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("active: $active") + pw.println("qsExpandedFraction: $qsExpandedFraction") + pw.println("qsScrollY: $qsScrollY") + if (combinedHeaders) { + header as MotionLayout + pw.println("currentState: ${header.currentState.stateToString()}") + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java index e1a2e56dcff1..ebdd257a9fc5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java @@ -312,7 +312,7 @@ public class NotificationPanelViewController extends PanelViewController { private final LockscreenShadeTransitionController mLockscreenShadeTransitionController; private final TapAgainViewController mTapAgainViewController; - private final SplitShadeHeaderController mSplitShadeHeaderController; + private final LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; private final RecordingController mRecordingController; private final PanelEventsEmitter mPanelEventsEmitter; private boolean mShouldUseSplitNotificationShade; @@ -734,7 +734,7 @@ public class NotificationPanelViewController extends PanelViewController { RecordingController recordingController, @Main Executor uiExecutor, SecureSettings secureSettings, - SplitShadeHeaderController splitShadeHeaderController, + LargeScreenShadeHeaderController largeScreenShadeHeaderController, ScreenOffAnimationController screenOffAnimationController, LockscreenGestureLogger lockscreenGestureLogger, PanelExpansionStateManager panelExpansionStateManager, @@ -794,7 +794,7 @@ public class NotificationPanelViewController extends PanelViewController { mShouldUseSplitNotificationShade = LargeScreenUtils.shouldUseSplitNotificationShade(mResources); mView.setWillNotDraw(!DEBUG); - mSplitShadeHeaderController = splitShadeHeaderController; + mLargeScreenShadeHeaderController = largeScreenShadeHeaderController; mLayoutInflater = layoutInflater; mFeatureFlags = featureFlags; mFalsingManager = falsingManager; @@ -1088,12 +1088,12 @@ public class NotificationPanelViewController extends PanelViewController { mQs.setInSplitShade(mShouldUseSplitNotificationShade); } mLargeScreenShadeHeaderHeight = - mResources.getDimensionPixelSize(R.dimen.split_shade_header_height); + mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height); mQuickQsHeaderHeight = useLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : SystemBarUtils.getQuickQsOffsetHeight(mView.getContext()); int topMargin = useLargeScreenShadeHeader ? mLargeScreenShadeHeaderHeight : mResources.getDimensionPixelSize(R.dimen.notification_panel_margin_top); - mSplitShadeHeaderController.setActive(useLargeScreenShadeHeader); + mLargeScreenShadeHeaderController.setActive(useLargeScreenShadeHeader); mAmbientState.setStackTopMargin(topMargin); mNotificationsQSContainerController.updateResources(); @@ -2273,9 +2273,9 @@ public class NotificationPanelViewController extends PanelViewController { float shadeExpandedFraction = mTransitioningToFullShadeProgress > 0 ? mLockscreenShadeTransitionController.getQSDragProgress() : getExpandedFraction(); - mSplitShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction); - mSplitShadeHeaderController.setQsExpandedFraction(qsExpansionFraction); - mSplitShadeHeaderController.setShadeExpanded(mQsVisible); + mLargeScreenShadeHeaderController.setShadeExpandedFraction(shadeExpandedFraction); + mLargeScreenShadeHeaderController.setQsExpandedFraction(qsExpansionFraction); + mLargeScreenShadeHeaderController.setShadeExpanded(mQsVisible); } private void onStackYChanged(boolean shouldAnimate) { @@ -3538,7 +3538,7 @@ public class NotificationPanelViewController extends PanelViewController { public final QS.ScrollListener mScrollListener = new QS.ScrollListener() { @Override public void onQsPanelScrollChanged(int scrollY) { - mSplitShadeHeaderController.setQsScrollY(scrollY); + mLargeScreenShadeHeaderController.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. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt index dac688f25f02..745228e72596 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt @@ -123,7 +123,7 @@ class NotificationsQSContainerController @Inject constructor( notificationsBottomMargin = resources.getDimensionPixelSize( R.dimen.notification_panel_margin_bottom) largeScreenShadeHeaderHeight = - resources.getDimensionPixelSize(R.dimen.split_shade_header_height) + resources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height) panelMarginHorizontal = resources.getDimensionPixelSize( R.dimen.notification_panel_margin_horizontal) topMargin = if (largeScreenShadeHeaderActive) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt deleted file mode 100644 index b40e369c6954..000000000000 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SplitShadeHeaderController.kt +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -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.CentralSurfacesComponent.CentralSurfacesScope -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 - -@CentralSurfacesScope -class SplitShadeHeaderController @Inject constructor( - @Named(SPLIT_SHADE_HEADER) private val statusBar: View, - private val statusBarIconController: StatusBarIconController, - private val privacyIconsController: HeaderPrivacyIconsController, - qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder, - featureFlags: FeatureFlags, - @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) - private val iconManager: StatusBarIconController.TintedIconManager - private val iconContainer: StatusIconContainer - private val carrierIconSlots: List - private val qsCarrierGroupController: QSCarrierGroupController - private var visible = false - set(value) { - if (field == value) { - return - } - field = value - updateListeners() - } - - var shadeExpanded = false - set(value) { - if (field == value) { - return - } - field = value - onShadeExpandedChanged() - } - - var active = false - set(value) { - if (field == value) { - return - } - field = value - onHeaderStateChanged() - } - - var shadeExpandedFraction = -1f - set(value) { - if (visible && field != value) { - statusBar.alpha = ShadeInterpolation.getContentAlpha(value) - field = value - } - } - - var qsExpandedFraction = -1f - set(value) { - if (visible && field != value) { - field = value - updateVisibility() - updatePosition() - } - } - - 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(QQS_HEADER_CONSTRAINT) - .load(context, resources.getXml(R.xml.qqs_header)) - statusBar.getConstraintSet(QS_HEADER_CONSTRAINT) - .load(context, resources.getXml(R.xml.qs_header)) - statusBar.getConstraintSet(SPLIT_HEADER_CONSTRAINT) - .load(context, resources.getXml(R.xml.split_header)) - privacyIconsController.chipVisibilityListener = chipVisibilityListener - } - } - - init { - batteryMeterViewController.init() - val batteryIcon: BatteryMeterView = statusBar.findViewById(R.id.batteryRemainingIcon) - - // battery settings same as in QS icons - batteryMeterViewController.ignoreTunerUpdates() - batteryIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE) - - iconContainer = statusBar.findViewById(R.id.statusIcons) - iconManager = StatusBarIconController.TintedIconManager(iconContainer, featureFlags) - iconManager.setTint(Utils.getColorAttrDefaultColor(statusBar.context, - android.R.attr.textColorPrimary)) - - carrierIconSlots = if (featureFlags.isEnabled(Flags.COMBINED_STATUS_BAR_SIGNAL_ICONS)) { - listOf( - statusBar.context.getString(com.android.internal.R.string.status_bar_no_calling), - statusBar.context.getString(com.android.internal.R.string.status_bar_call_strength) - ) - } else { - listOf(statusBar.context.getString(com.android.internal.R.string.status_bar_mobile)) - } - qsCarrierGroupController = qsCarrierGroupControllerBuilder - .setQSCarrierGroup(statusBar.findViewById(R.id.carrier_group)) - .build() - - dumpManager.registerDumpable(this) - - updateVisibility() - updateConstraints() - } - - private fun updateScrollY() { - if (!active && combinedHeaders) { - statusBar.scrollY = qsScrollY - } - } - - private fun onShadeExpandedChanged() { - if (shadeExpanded) { - privacyIconsController.startListening() - } else { - privacyIconsController.stopListening() - } - updateVisibility() - updatePosition() - } - - private fun onHeaderStateChanged() { - if (active || combinedHeaders) { - privacyIconsController.onParentVisible() - } else { - privacyIconsController.onParentInvisible() - } - updateVisibility() - updateConstraints() - } - - private fun updateVisibility() { - val visibility = if (!active && !combinedHeaders) { - View.GONE - } else if (shadeExpanded) { - View.VISIBLE - } else { - View.INVISIBLE - } - if (statusBar.visibility != visibility) { - statusBar.visibility = visibility - visible = visibility == View.VISIBLE - } - } - - private fun updateConstraints() { - if (!combinedHeaders) { - return - } - statusBar as MotionLayout - if (active) { - statusBar.setTransition(SPLIT_HEADER_TRANSITION_ID) - } else { - statusBar.setTransition(HEADER_TRANSITION_ID) - statusBar.transitionToStart() - updatePosition() - updateScrollY() - } - } - - private fun updatePosition() { - if (statusBar is MotionLayout && !active && visible) { - statusBar.setProgress(qsExpandedFraction) - } - } - - private fun updateListeners() { - qsCarrierGroupController.setListening(visible) - if (visible) { - updateSingleCarrier(qsCarrierGroupController.isSingleCarrier) - qsCarrierGroupController.setOnSingleCarrierChangedListener { updateSingleCarrier(it) } - statusBarIconController.addIconGroup(iconManager) - } else { - qsCarrierGroupController.setOnSingleCarrierChangedListener(null) - statusBarIconController.removeIconGroup(iconManager) - } - } - - private fun updateSingleCarrier(singleCarrier: Boolean) { - if (singleCarrier) { - iconContainer.removeIgnoredSlots(carrierIconSlots) - } else { - 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("active: $active") - pw.println("qsExpandedFraction: $qsExpandedFraction") - pw.println("qsScrollY: $qsScrollY") - if (combinedHeaders) { - statusBar as MotionLayout - pw.println("currentState: ${statusBar.currentState.stateToString()}") - } - } -} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java index a86ad6bc7012..5d38eea15723 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/CentralSurfacesComponent.java @@ -31,10 +31,10 @@ import com.android.systemui.statusbar.notification.stack.NotificationListContain import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController; import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutListContainerModule; import com.android.systemui.statusbar.phone.CentralSurfacesCommandQueueCallbacks; +import com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController; import com.android.systemui.statusbar.phone.NotificationPanelViewController; import com.android.systemui.statusbar.phone.NotificationShadeWindowView; import com.android.systemui.statusbar.phone.NotificationShadeWindowViewController; -import com.android.systemui.statusbar.phone.SplitShadeHeaderController; import com.android.systemui.statusbar.phone.StatusBarHeadsUpChangeListener; import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarterModule; import com.android.systemui.statusbar.phone.StatusBarNotificationPresenterModule; @@ -133,9 +133,9 @@ public interface CentralSurfacesComponent { CentralSurfacesCommandQueueCallbacks getCentralSurfacesCommandQueueCallbacks(); /** - * Creates a SplitShadeHeaderController. + * Creates a {@link LargeScreenShadeHeaderController}. */ - SplitShadeHeaderController getSplitShadeHeaderController(); + LargeScreenShadeHeaderController getLargeScreenShadeHeaderController(); /** * Creates a new {@link CollapsedStatusBarFragment} each time it's called. See diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java index 79fe700191f7..6c6ec192646d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarViewModule.java @@ -73,9 +73,9 @@ import dagger.Provides; @Module(subcomponents = StatusBarFragmentComponent.class) public abstract class StatusBarViewModule { - public static final String SPLIT_SHADE_HEADER = "split_shade_header"; + public static final String LARGE_SCREEN_SHADE_HEADER = "large_screen_shade_header"; private static final String SPLIT_SHADE_BATTERY_VIEW = "split_shade_battery_view"; - public static final String SPLIT_SHADE_BATTERY_CONTROLLER = "split_shade_battery_controller"; + public static final String LARGE_SCREEN_BATTERY_CONTROLLER = "split_shade_battery_controller"; public static final String STATUS_BAR_FRAGMENT = "status_bar_fragment"; /** */ @@ -159,15 +159,15 @@ public abstract class StatusBarViewModule { /** */ @Provides - @Named(SPLIT_SHADE_HEADER) + @Named(LARGE_SCREEN_SHADE_HEADER) @CentralSurfacesComponent.CentralSurfacesScope - public static View getSplitShadeStatusBarView( + public static View getLargeScreenShadeHeaderBarView( NotificationShadeWindowView notificationShadeWindowView, FeatureFlags featureFlags) { ViewStub stub = notificationShadeWindowView.findViewById(R.id.qs_header_stub); int layoutId = featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS) ? R.layout.combined_qs_header - : R.layout.split_shade_header; + : R.layout.large_screen_shade_header; stub.setLayoutResource(layoutId); View v = stub.inflate(); return v; @@ -177,14 +177,15 @@ public abstract class StatusBarViewModule { @Provides @CentralSurfacesComponent.CentralSurfacesScope public static OngoingPrivacyChip getSplitShadeOngoingPrivacyChip( - @Named(SPLIT_SHADE_HEADER) View header) { + @Named(LARGE_SCREEN_SHADE_HEADER) View header) { return header.findViewById(R.id.privacy_chip); } /** */ @Provides @CentralSurfacesComponent.CentralSurfacesScope - static StatusIconContainer providesStatusIconContainer(@Named(SPLIT_SHADE_HEADER) View header) { + static StatusIconContainer providesStatusIconContainer( + @Named(LARGE_SCREEN_SHADE_HEADER) View header) { return header.findViewById(R.id.statusIcons); } @@ -192,13 +193,13 @@ public abstract class StatusBarViewModule { @Provides @CentralSurfacesComponent.CentralSurfacesScope @Named(SPLIT_SHADE_BATTERY_VIEW) - static BatteryMeterView getBatteryMeterView(@Named(SPLIT_SHADE_HEADER) View view) { + static BatteryMeterView getBatteryMeterView(@Named(LARGE_SCREEN_SHADE_HEADER) View view) { return view.findViewById(R.id.batteryRemainingIcon); } @Provides @CentralSurfacesComponent.CentralSurfacesScope - @Named(SPLIT_SHADE_BATTERY_CONTROLLER) + @Named(LARGE_SCREEN_BATTERY_CONTROLLER) static BatteryMeterViewController getBatteryMeterViewController( @Named(SPLIT_SHADE_BATTERY_VIEW) BatteryMeterView batteryMeterView, ConfigurationController configurationController, diff --git a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt index 978936f8cf41..8b29310cf1c5 100644 --- a/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt +++ b/packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt @@ -16,7 +16,7 @@ object LargeScreenUtils { /** * Returns true if we should use large screen shade header: - * [com.android.systemui.statusbar.phone.SplitShadeHeaderController] + * [com.android.systemui.statusbar.phone.LargeScreenShadeHeaderController] * That should be true when we have enough horizontal space to show all info in one row. */ @JvmStatic diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java index 1827c7f0c0a6..6d3a5fecc826 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java @@ -279,7 +279,7 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase { public void notifPaddingMakesUpToFullMarginInSplitShade() { when(mResources.getDimensionPixelSize(R.dimen.keyguard_split_shade_top_margin)) .thenReturn(100); - when(mResources.getDimensionPixelSize(R.dimen.split_shade_header_height)) + when(mResources.getDimensionPixelSize(R.dimen.large_screen_shade_header_height)) .thenReturn(70); mClockPositionAlgorithm.loadDimens(mResources); givenLockScreen(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt new file mode 100644 index 000000000000..b086d681adf5 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LargeScreenShadeHeaderControllerTest.kt @@ -0,0 +1,123 @@ +package com.android.systemui.statusbar.phone + +import android.testing.AndroidTestingRunner +import android.view.View +import androidx.test.filters.SmallTest +import com.android.systemui.R +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 +import com.android.systemui.qs.carrier.QSCarrierGroupController +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyInt +import org.mockito.Mock +import org.mockito.Mockito.verify +import org.mockito.junit.MockitoJUnit +import org.mockito.Mockito.`when` as whenever + +@SmallTest +@RunWith(AndroidTestingRunner::class) +class LargeScreenShadeHeaderControllerTest : SysuiTestCase() { + + @Mock private lateinit var view: View + @Mock private lateinit var statusIcons: StatusIconContainer + @Mock private lateinit var statusBarIconController: StatusBarIconController + @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController + @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder + @Mock private lateinit var featureFlags: FeatureFlags + @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 + + private lateinit var mLargeScreenShadeHeaderController: LargeScreenShadeHeaderController + private lateinit var carrierIconSlots: List + + @Before + fun setup() { + whenever(view.findViewById(R.id.batteryRemainingIcon)) + .thenReturn(batteryMeterView) + whenever(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons) + whenever(view.context).thenReturn(context) + whenever(statusIcons.context).thenReturn(context) + whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any())) + .thenReturn(qsCarrierGroupControllerBuilder) + whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) + whenever(view.setVisibility(anyInt())).then { + viewVisibility = it.arguments[0] as Int + null + } + whenever(view.visibility).thenAnswer { _ -> viewVisibility } + whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false) + mLargeScreenShadeHeaderController = LargeScreenShadeHeaderController( + view, + statusBarIconController, + privacyIconsController, + qsCarrierGroupControllerBuilder, + featureFlags, + batteryMeterViewController, + dumpManager + ) + carrierIconSlots = listOf( + context.getString(com.android.internal.R.string.status_bar_mobile)) + } + + @Test + fun setVisible_onlyWhenActive() { + makeShadeVisible() + assertThat(viewVisibility).isEqualTo(View.VISIBLE) + + mLargeScreenShadeHeaderController.active = false + assertThat(viewVisibility).isEqualTo(View.GONE) + } + + @Test + fun updateListeners_registersWhenVisible() { + makeShadeVisible() + verify(qsCarrierGroupController).setListening(true) + verify(statusBarIconController).addIconGroup(any()) + } + + @Test + fun shadeExpandedFraction_updatesAlpha() { + makeShadeVisible() + mLargeScreenShadeHeaderController.shadeExpandedFraction = 0.5f + verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f)) + } + + @Test + fun singleCarrier_enablesCarrierIconsInStatusIcons() { + whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true) + + makeShadeVisible() + + verify(statusIcons).removeIgnoredSlots(carrierIconSlots) + } + + @Test + fun dualCarrier_disablesCarrierIconsInStatusIcons() { + whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false) + + makeShadeVisible() + + verify(statusIcons).addIgnoredSlots(carrierIconSlots) + } + + private fun makeShadeVisible() { + mLargeScreenShadeHeaderController.active = true + mLargeScreenShadeHeaderController.shadeExpanded = true + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java index 1bdc6be11f47..21d03adb64ef 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewControllerTest.java @@ -288,7 +288,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Mock private SecureSettings mSecureSettings; @Mock - private SplitShadeHeaderController mSplitShadeHeaderController; + private LargeScreenShadeHeaderController mLargeScreenShadeHeaderController; @Mock private ContentResolver mContentResolver; @Mock @@ -498,7 +498,7 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mRecordingController, mExecutor, mSecureSettings, - mSplitShadeHeaderController, + mLargeScreenShadeHeaderController, mScreenOffAnimationController, mLockscreenGestureLogger, new PanelExpansionStateManager(), @@ -923,11 +923,11 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { mStatusBarStateController.setState(SHADE); when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(true); mNotificationPanelViewController.updateResources(); - verify(mSplitShadeHeaderController).setActive(true); + verify(mLargeScreenShadeHeaderController).setActive(true); when(mResources.getBoolean(R.bool.config_use_large_screen_shade_header)).thenReturn(false); mNotificationPanelViewController.updateResources(); - verify(mSplitShadeHeaderController).setActive(false); + verify(mLargeScreenShadeHeaderController).setActive(false); } private void triggerPositionClockAndNotifications() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt index 8e7674e49922..05a21db310fc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt @@ -471,7 +471,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() { fun testLargeScreenLayout_qsAndNotifsTopMarginIsOfHeaderHeight() { setLargeScreen() val largeScreenHeaderHeight = 100 - overrideResource(R.dimen.split_shade_header_height, largeScreenHeaderHeight) + overrideResource(R.dimen.large_screen_shade_header_height, largeScreenHeaderHeight) controller.updateResources() 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 deleted file mode 100644 index 22f295e5547f..000000000000 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SplitShadeHeaderControllerTest.kt +++ /dev/null @@ -1,123 +0,0 @@ -package com.android.systemui.statusbar.phone - -import android.testing.AndroidTestingRunner -import android.view.View -import androidx.test.filters.SmallTest -import com.android.systemui.R -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 -import com.android.systemui.qs.carrier.QSCarrierGroupController -import com.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyInt -import org.mockito.Mock -import org.mockito.Mockito.verify -import org.mockito.junit.MockitoJUnit -import org.mockito.Mockito.`when` as whenever - -@SmallTest -@RunWith(AndroidTestingRunner::class) -class SplitShadeHeaderControllerTest : SysuiTestCase() { - - @Mock private lateinit var view: View - @Mock private lateinit var statusIcons: StatusIconContainer - @Mock private lateinit var statusBarIconController: StatusBarIconController - @Mock private lateinit var qsCarrierGroupController: QSCarrierGroupController - @Mock private lateinit var qsCarrierGroupControllerBuilder: QSCarrierGroupController.Builder - @Mock private lateinit var featureFlags: FeatureFlags - @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 - - private lateinit var splitShadeHeaderController: SplitShadeHeaderController - private lateinit var carrierIconSlots: List - - @Before - fun setup() { - whenever(view.findViewById(R.id.batteryRemainingIcon)) - .thenReturn(batteryMeterView) - whenever(view.findViewById(R.id.statusIcons)).thenReturn(statusIcons) - whenever(view.context).thenReturn(context) - whenever(statusIcons.context).thenReturn(context) - whenever(qsCarrierGroupControllerBuilder.setQSCarrierGroup(any())) - .thenReturn(qsCarrierGroupControllerBuilder) - whenever(qsCarrierGroupControllerBuilder.build()).thenReturn(qsCarrierGroupController) - whenever(view.setVisibility(anyInt())).then { - viewVisibility = it.arguments[0] as Int - null - } - whenever(view.visibility).thenAnswer { _ -> viewVisibility } - whenever(featureFlags.isEnabled(Flags.COMBINED_QS_HEADERS)).thenReturn(false) - splitShadeHeaderController = SplitShadeHeaderController( - view, - statusBarIconController, - privacyIconsController, - qsCarrierGroupControllerBuilder, - featureFlags, - batteryMeterViewController, - dumpManager - ) - carrierIconSlots = listOf( - context.getString(com.android.internal.R.string.status_bar_mobile)) - } - - @Test - fun setVisible_onlyWhenActive() { - makeShadeVisible() - assertThat(viewVisibility).isEqualTo(View.VISIBLE) - - splitShadeHeaderController.active = false - assertThat(viewVisibility).isEqualTo(View.GONE) - } - - @Test - fun updateListeners_registersWhenVisible() { - makeShadeVisible() - verify(qsCarrierGroupController).setListening(true) - verify(statusBarIconController).addIconGroup(any()) - } - - @Test - fun shadeExpandedFraction_updatesAlpha() { - makeShadeVisible() - splitShadeHeaderController.shadeExpandedFraction = 0.5f - verify(view).setAlpha(ShadeInterpolation.getContentAlpha(0.5f)) - } - - @Test - fun singleCarrier_enablesCarrierIconsInStatusIcons() { - whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(true) - - makeShadeVisible() - - verify(statusIcons).removeIgnoredSlots(carrierIconSlots) - } - - @Test - fun dualCarrier_disablesCarrierIconsInStatusIcons() { - whenever(qsCarrierGroupController.isSingleCarrier).thenReturn(false) - - makeShadeVisible() - - verify(statusIcons).addIgnoredSlots(carrierIconSlots) - } - - private fun makeShadeVisible() { - splitShadeHeaderController.active = true - splitShadeHeaderController.shadeExpanded = true - } -} -- cgit v1.2.3-59-g8ed1b