Merge "Showing brightness slider in collapsed QS in split shade" into sc-v2-dev am: 9314834982
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15301454 Change-Id: I169313fefd23c01771de3342829530d0c48453ab
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
android:paddingStart="0dp"
|
||||
android:elevation="4dp" >
|
||||
|
||||
<!-- Date and privacy. Only visible in QS -->
|
||||
<!-- Date and privacy. Only visible in QS when not in split shade -->
|
||||
<include layout="@layout/quick_status_bar_header_date_privacy"/>
|
||||
|
||||
<RelativeLayout
|
||||
@@ -42,7 +42,7 @@
|
||||
android:layout_gravity="top"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false">
|
||||
<!-- Time, icons and Carrier (only in QS) -->
|
||||
<!-- Time, icons and Carrier (only in QS when not in split shade) -->
|
||||
<include layout="@layout/quick_qs_status_icons"/>
|
||||
|
||||
<com.android.systemui.qs.QuickQSPanel
|
||||
|
||||
@@ -88,11 +88,14 @@ public abstract class QSPanelControllerBase<T extends QSPanel> extends ViewContr
|
||||
Utils.shouldUseSplitNotificationShade(mFeatureFlags, getResources());
|
||||
if (newConfig.orientation != mLastOrientation) {
|
||||
mLastOrientation = newConfig.orientation;
|
||||
onScreenRotated();
|
||||
switchTileLayout(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
protected void onScreenRotated() { }
|
||||
|
||||
private final Function1<Boolean, Unit> mMediaHostVisibilityListener = (visible) -> {
|
||||
if (mMediaVisibilityChangedListener != null) {
|
||||
mMediaVisibilityChangedListener.accept(visible);
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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.qs
|
||||
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.systemui.settings.brightness.BrightnessController
|
||||
import com.android.systemui.settings.brightness.BrightnessSlider
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Controls brightness slider in QQS, which is visible only in split shade. It's responsible for
|
||||
* showing/hiding it when appropriate and (un)registering listeners
|
||||
*/
|
||||
class QuickQSBrightnessController @VisibleForTesting constructor(
|
||||
private val brightnessControllerFactory: () -> BrightnessController
|
||||
) {
|
||||
|
||||
@Inject constructor(
|
||||
brightnessControllerFactory: BrightnessController.Factory,
|
||||
brightnessSliderFactory: BrightnessSlider.Factory,
|
||||
quickQSPanel: QuickQSPanel
|
||||
) : this(brightnessControllerFactory = {
|
||||
val slider = brightnessSliderFactory.create(quickQSPanel.context, quickQSPanel)
|
||||
slider.init()
|
||||
quickQSPanel.setBrightnessView(slider.rootView)
|
||||
brightnessControllerFactory.create(slider)
|
||||
})
|
||||
|
||||
private var isListening = false
|
||||
private var brightnessController: BrightnessController? = null
|
||||
|
||||
fun init(shouldUseSplitNotificationShade: Boolean) {
|
||||
refreshVisibility(shouldUseSplitNotificationShade)
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts/Stops listening for brightness changing events.
|
||||
* It's fine to call this function even if slider is not visible (which would be the case for
|
||||
* all small screen devices), it will just do nothing in that case
|
||||
*/
|
||||
fun setListening(listening: Boolean) {
|
||||
if (listening) {
|
||||
// controller can be null when slider was never shown
|
||||
if (!isListening && brightnessController != null) {
|
||||
brightnessController?.registerCallbacks()
|
||||
isListening = true
|
||||
}
|
||||
} else {
|
||||
brightnessController?.unregisterCallbacks()
|
||||
isListening = false
|
||||
}
|
||||
}
|
||||
|
||||
fun checkRestrictionAndSetEnabled() {
|
||||
brightnessController?.checkRestrictionAndSetEnabled()
|
||||
}
|
||||
|
||||
fun refreshVisibility(shouldUseSplitNotificationShade: Boolean) {
|
||||
if (shouldUseSplitNotificationShade) {
|
||||
showBrightnessSlider()
|
||||
} else {
|
||||
hideBrightnessSlider()
|
||||
}
|
||||
}
|
||||
|
||||
private fun hideBrightnessSlider() {
|
||||
brightnessController?.hideSlider()
|
||||
}
|
||||
|
||||
private fun showBrightnessSlider() {
|
||||
if (brightnessController == null) {
|
||||
brightnessController = brightnessControllerFactory()
|
||||
}
|
||||
brightnessController?.showSlider()
|
||||
if (!isListening) {
|
||||
brightnessController?.registerCallbacks()
|
||||
isListening = true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,11 +45,6 @@ public class QuickQSPanel extends QSPanel {
|
||||
mMaxTiles = getResources().getInteger(R.integer.quick_qs_panel_max_tiles);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBrightnessView(View view) {
|
||||
// Don't add brightness view
|
||||
}
|
||||
|
||||
@Override
|
||||
void initialize() {
|
||||
super.initialize();
|
||||
|
||||
@@ -49,16 +49,21 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
|
||||
}
|
||||
};
|
||||
|
||||
// brightness is visible only in split shade
|
||||
private final QuickQSBrightnessController mBrightnessController;
|
||||
|
||||
@Inject
|
||||
QuickQSPanelController(QuickQSPanel view, QSTileHost qsTileHost,
|
||||
QSCustomizerController qsCustomizerController,
|
||||
@Named(QS_USING_MEDIA_PLAYER) boolean usingMediaPlayer,
|
||||
@Named(QUICK_QS_PANEL) MediaHost mediaHost,
|
||||
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
|
||||
DumpManager dumpManager, FeatureFlags featureFlags
|
||||
DumpManager dumpManager, FeatureFlags featureFlags,
|
||||
QuickQSBrightnessController quickQSBrightnessController
|
||||
) {
|
||||
super(view, qsTileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
|
||||
uiEventLogger, qsLogger, dumpManager, featureFlags);
|
||||
mBrightnessController = quickQSBrightnessController;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -67,6 +72,7 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
|
||||
mMediaHost.setExpansion(0.0f);
|
||||
mMediaHost.setShowsOnlyActiveMedia(true);
|
||||
mMediaHost.init(MediaHierarchyManager.LOCATION_QQS);
|
||||
mBrightnessController.init(mShouldUseSplitNotificationShade);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,6 +87,12 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
|
||||
mView.removeOnConfigurationChangedListener(mOnConfigurationChangedListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
void setListening(boolean listening) {
|
||||
super.setListening(listening);
|
||||
mBrightnessController.setListening(listening);
|
||||
}
|
||||
|
||||
public boolean isListening() {
|
||||
return mView.isListening();
|
||||
}
|
||||
@@ -90,6 +102,17 @@ public class QuickQSPanelController extends QSPanelControllerBase<QuickQSPanel>
|
||||
setTiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshAllTiles() {
|
||||
mBrightnessController.checkRestrictionAndSetEnabled();
|
||||
super.refreshAllTiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onScreenRotated() {
|
||||
mBrightnessController.refreshVisibility(mShouldUseSplitNotificationShade);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTiles() {
|
||||
List<QSTile> tiles = new ArrayList<>();
|
||||
|
||||
@@ -59,7 +59,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
private final ActivityStarter mActivityStarter;
|
||||
private final UiEventLogger mUiEventLogger;
|
||||
private final QSCarrierGroupController mQSCarrierGroupController;
|
||||
private final QuickQSPanelController mHeaderQsPanelController;
|
||||
private final QuickQSPanelController mQuickQSPanelController;
|
||||
private final OngoingPrivacyChip mPrivacyChip;
|
||||
private final Clock mClockView;
|
||||
private final StatusBarIconController mStatusBarIconController;
|
||||
@@ -140,7 +140,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
mUiEventLogger = uiEventLogger;
|
||||
mStatusBarIconController = statusBarIconController;
|
||||
mDemoModeController = demoModeController;
|
||||
mHeaderQsPanelController = quickQSPanelController;
|
||||
mQuickQSPanelController = quickQSPanelController;
|
||||
mPrivacyLogger = privacyLogger;
|
||||
mPrivacyDialogController = privacyDialogController;
|
||||
mQSExpansionPathInterpolator = qsExpansionPathInterpolator;
|
||||
@@ -201,12 +201,12 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
}
|
||||
mListening = listening;
|
||||
|
||||
mHeaderQsPanelController.setListening(listening);
|
||||
if (mHeaderQsPanelController.isListening()) {
|
||||
mHeaderQsPanelController.refreshAllTiles();
|
||||
mQuickQSPanelController.setListening(listening);
|
||||
if (mQuickQSPanelController.isListening()) {
|
||||
mQuickQSPanelController.refreshAllTiles();
|
||||
}
|
||||
|
||||
if (mHeaderQsPanelController.switchTileLayout(false)) {
|
||||
if (mQuickQSPanelController.switchTileLayout(false)) {
|
||||
mView.updateResources();
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
|
||||
}
|
||||
|
||||
public void setContentMargins(int marginStart, int marginEnd) {
|
||||
mHeaderQsPanelController.setContentMargins(marginStart, marginEnd);
|
||||
mQuickQSPanelController.setContentMargins(marginStart, marginEnd);
|
||||
}
|
||||
|
||||
private static class ClockDemoModeReceiver implements DemoMode {
|
||||
|
||||
@@ -385,6 +385,14 @@ public class BrightnessController implements ToggleSlider.Listener {
|
||||
});
|
||||
}
|
||||
|
||||
public void hideSlider() {
|
||||
mControl.hideView();
|
||||
}
|
||||
|
||||
public void showSlider() {
|
||||
mControl.showView();
|
||||
}
|
||||
|
||||
private void setBrightness(float brightness) {
|
||||
mDisplayManager.setTemporaryBrightness(mDisplayId, brightness);
|
||||
}
|
||||
|
||||
@@ -180,6 +180,16 @@ public class BrightnessSlider extends ViewController<BrightnessSliderView> imple
|
||||
return mView.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideView() {
|
||||
mView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showView() {
|
||||
mView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
private final SeekBar.OnSeekBarChangeListener mSeekListener =
|
||||
new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
|
||||
@@ -35,4 +35,7 @@ public interface ToggleSlider {
|
||||
int getMax();
|
||||
void setValue(int value);
|
||||
int getValue();
|
||||
|
||||
void showView();
|
||||
void hideView();
|
||||
}
|
||||
|
||||
@@ -89,8 +89,8 @@ public interface StatusBarComponent {
|
||||
AuthRippleController getAuthRippleController();
|
||||
|
||||
/**
|
||||
* Creates a SplitShadeStatusBarController.
|
||||
* Creates a SplitShadeHeaderController.
|
||||
*/
|
||||
@StatusBarScope
|
||||
SplitShadeHeaderController getSplitShadeStatusBarController();
|
||||
SplitShadeHeaderController getSplitShadeHeaderController();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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.qs
|
||||
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.settings.brightness.BrightnessController
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
|
||||
@SmallTest
|
||||
class QuickQSBrightnessControllerTest : SysuiTestCase() {
|
||||
|
||||
@Mock
|
||||
lateinit var brightnessController: BrightnessController
|
||||
@get:Rule
|
||||
val mockito = MockitoJUnit.rule()
|
||||
|
||||
lateinit var quickQSBrightnessController: QuickQSBrightnessController
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
quickQSBrightnessController = QuickQSBrightnessController(
|
||||
brightnessControllerFactory = { brightnessController })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSliderIsShownWhenInitializedInSplitShade() {
|
||||
quickQSBrightnessController.init(shouldUseSplitNotificationShade = true)
|
||||
|
||||
verify(brightnessController).showSlider()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSliderIsShownWhenRefreshedInSplitShade() {
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
|
||||
verify(brightnessController, times(1)).showSlider()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSliderIsHiddenWhenRefreshedInNonSplitShade() {
|
||||
// needs to be shown first
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
|
||||
|
||||
verify(brightnessController).hideSlider()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSliderChangesVisibilityWhenRotating() {
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
verify(brightnessController, times(1)).showSlider()
|
||||
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
|
||||
verify(brightnessController, times(1)).hideSlider()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCallbacksAreRegisteredOnlyOnce() {
|
||||
// this flow simulates expanding shade in portrait...
|
||||
quickQSBrightnessController.setListening(true)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
|
||||
// ... and rotating to landscape/split shade where slider is visible
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
|
||||
verify(brightnessController, times(1)).registerCallbacks()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCallbacksAreRegisteredOnlyOnceWhenRotatingPhone() {
|
||||
quickQSBrightnessController.setListening(true)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = true)
|
||||
|
||||
verify(brightnessController, times(1)).registerCallbacks()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCallbacksAreNotRegisteredWhenSliderNotVisible() {
|
||||
quickQSBrightnessController.setListening(true)
|
||||
quickQSBrightnessController.refreshVisibility(shouldUseSplitNotificationShade = false)
|
||||
|
||||
verify(brightnessController, never()).registerCallbacks()
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,8 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
|
||||
private lateinit var tileView: QSTileView
|
||||
@Mock
|
||||
private lateinit var featureFlags: FeatureFlags
|
||||
@Mock
|
||||
private lateinit var quickQsBrightnessController: QuickQSBrightnessController
|
||||
|
||||
private lateinit var controller: QuickQSPanelController
|
||||
|
||||
@@ -87,7 +89,8 @@ class QuickQSPanelControllerTest : SysuiTestCase() {
|
||||
uiEventLogger,
|
||||
qsLogger,
|
||||
dumpManager,
|
||||
featureFlags
|
||||
featureFlags,
|
||||
quickQsBrightnessController
|
||||
)
|
||||
|
||||
controller.init()
|
||||
|
||||
Reference in New Issue
Block a user