Merge "[Split shade] Fix QS actions footer border visible on shade expansion" into tm-qpr-dev am: 910d009002
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19570009 Change-Id: I3876de17d23f2ef922664a85b902d66017c69d6f Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
package com.android.systemui.qs
|
package com.android.systemui.qs
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.content.res.Configuration
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.UserManager
|
import android.os.UserManager
|
||||||
import android.provider.Settings
|
import android.provider.Settings
|
||||||
@@ -38,9 +39,11 @@ import com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED
|
|||||||
import com.android.systemui.qs.dagger.QSScope
|
import com.android.systemui.qs.dagger.QSScope
|
||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.statusbar.phone.MultiUserSwitchController
|
import com.android.systemui.statusbar.phone.MultiUserSwitchController
|
||||||
|
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
||||||
import com.android.systemui.statusbar.policy.UserInfoController
|
import com.android.systemui.statusbar.policy.UserInfoController
|
||||||
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener
|
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener
|
||||||
|
import com.android.systemui.util.LargeScreenUtils
|
||||||
import com.android.systemui.util.ViewController
|
import com.android.systemui.util.ViewController
|
||||||
import com.android.systemui.util.settings.GlobalSettings
|
import com.android.systemui.util.settings.GlobalSettings
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -69,18 +72,43 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
private val uiEventLogger: UiEventLogger,
|
private val uiEventLogger: UiEventLogger,
|
||||||
@Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
|
@Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
|
||||||
private val globalSetting: GlobalSettings,
|
private val globalSetting: GlobalSettings,
|
||||||
private val handler: Handler
|
private val handler: Handler,
|
||||||
|
private val configurationController: ConfigurationController,
|
||||||
) : ViewController<FooterActionsView>(view) {
|
) : ViewController<FooterActionsView>(view) {
|
||||||
|
|
||||||
private var globalActionsDialog: GlobalActionsDialogLite? = null
|
private var globalActionsDialog: GlobalActionsDialogLite? = null
|
||||||
|
|
||||||
private var lastExpansion = -1f
|
private var lastExpansion = -1f
|
||||||
private var listening: Boolean = false
|
private var listening: Boolean = false
|
||||||
|
private var inSplitShade = false
|
||||||
|
|
||||||
private val alphaAnimator = TouchAnimator.Builder()
|
private val singleShadeAnimator by lazy {
|
||||||
.addFloat(mView, "alpha", 0f, 1f)
|
// In single shade, the actions footer should only appear at the end of the expansion,
|
||||||
.setStartDelay(0.9f)
|
// so that it doesn't overlap with the notifications panel.
|
||||||
|
TouchAnimator.Builder().addFloat(mView, "alpha", 0f, 1f).setStartDelay(0.9f).build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val splitShadeAnimator by lazy {
|
||||||
|
// The Actions footer view has its own background which is the same color as the qs panel's
|
||||||
|
// background.
|
||||||
|
// We don't want it to fade in at the same time as the rest of the panel, otherwise it is
|
||||||
|
// more opaque than the rest of the panel's background. Only applies to split shade.
|
||||||
|
val alphaAnimator = TouchAnimator.Builder().addFloat(mView, "alpha", 0f, 1f).build()
|
||||||
|
val bgAlphaAnimator =
|
||||||
|
TouchAnimator.Builder()
|
||||||
|
.addFloat(mView, "backgroundAlpha", 0f, 1f)
|
||||||
|
.setStartDelay(0.9f)
|
||||||
|
.build()
|
||||||
|
// In split shade, we want the actions footer to fade in exactly at the same time as the
|
||||||
|
// rest of the shade, as there is no overlap.
|
||||||
|
TouchAnimator.Builder()
|
||||||
|
.addFloat(alphaAnimator, "position", 0f, 1f)
|
||||||
|
.addFloat(bgAlphaAnimator, "position", 0f, 1f)
|
||||||
.build()
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
private val animators: TouchAnimator
|
||||||
|
get() = if (inSplitShade) splitShadeAnimator else singleShadeAnimator
|
||||||
|
|
||||||
var visible = true
|
var visible = true
|
||||||
set(value) {
|
set(value) {
|
||||||
@@ -95,9 +123,7 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
private val multiUserSwitchController = multiUserSwitchControllerFactory.create(view)
|
private val multiUserSwitchController = multiUserSwitchControllerFactory.create(view)
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal val securityFootersSeparator = View(context).apply {
|
internal val securityFootersSeparator = View(context).apply { visibility = View.GONE }
|
||||||
visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
private val onUserInfoChangedListener = OnUserInfoChangedListener { _, picture, _ ->
|
private val onUserInfoChangedListener = OnUserInfoChangedListener { _, picture, _ ->
|
||||||
val isGuestUser: Boolean = userManager.isGuestUser(KeyguardUpdateMonitor.getCurrentUser())
|
val isGuestUser: Boolean = userManager.isGuestUser(KeyguardUpdateMonitor.getCurrentUser())
|
||||||
@@ -133,6 +159,17 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val configurationListener =
|
||||||
|
object : ConfigurationController.ConfigurationListener {
|
||||||
|
override fun onConfigChanged(newConfig: Configuration?) {
|
||||||
|
updateResources()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateResources() {
|
||||||
|
inSplitShade = LargeScreenUtils.shouldUseSplitNotificationShade(resources)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onInit() {
|
override fun onInit() {
|
||||||
multiUserSwitchController.init()
|
multiUserSwitchController.init()
|
||||||
securityFooterController.init()
|
securityFooterController.init()
|
||||||
@@ -189,6 +226,9 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
securityFooterController.setOnVisibilityChangedListener(visibilityListener)
|
securityFooterController.setOnVisibilityChangedListener(visibilityListener)
|
||||||
fgsManagerFooterController.setOnVisibilityChangedListener(visibilityListener)
|
fgsManagerFooterController.setOnVisibilityChangedListener(visibilityListener)
|
||||||
|
|
||||||
|
configurationController.addCallback(configurationListener)
|
||||||
|
|
||||||
|
updateResources()
|
||||||
updateView()
|
updateView()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,6 +241,7 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
globalActionsDialog = null
|
globalActionsDialog = null
|
||||||
setListening(false)
|
setListening(false)
|
||||||
multiUserSetting.isListening = false
|
multiUserSetting.isListening = false
|
||||||
|
configurationController.removeCallback(configurationListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setListening(listening: Boolean) {
|
fun setListening(listening: Boolean) {
|
||||||
@@ -224,7 +265,7 @@ internal class FooterActionsController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setExpansion(headerExpansionFraction: Float) {
|
fun setExpansion(headerExpansionFraction: Float) {
|
||||||
alphaAnimator.setPosition(headerExpansionFraction)
|
animators.setPosition(headerExpansionFraction)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setKeyguardShowing(showing: Boolean) {
|
fun setKeyguardShowing(showing: Boolean) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.view.MotionEvent
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
|
import androidx.annotation.Keep
|
||||||
import com.android.settingslib.Utils
|
import com.android.settingslib.Utils
|
||||||
import com.android.settingslib.drawable.UserIconDrawable
|
import com.android.settingslib.drawable.UserIconDrawable
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
@@ -45,6 +46,19 @@ class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(
|
|||||||
private var qsDisabled = false
|
private var qsDisabled = false
|
||||||
private var expansionAmount = 0f
|
private var expansionAmount = 0f
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the alpha of the background of this view.
|
||||||
|
*
|
||||||
|
* Used from a [TouchAnimator] in the controller.
|
||||||
|
*/
|
||||||
|
var backgroundAlpha: Float = 1f
|
||||||
|
@Keep
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
background?.alpha = (value * 255).toInt()
|
||||||
|
}
|
||||||
|
@Keep get
|
||||||
|
|
||||||
override fun onFinishInflate() {
|
override fun onFinishInflate() {
|
||||||
super.onFinishInflate()
|
super.onFinishInflate()
|
||||||
settingsContainer = findViewById(R.id.settings_button_container)
|
settingsContainer = findViewById(R.id.settings_button_container)
|
||||||
@@ -117,4 +131,4 @@ class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(
|
|||||||
private const val TAG = "FooterActionsView"
|
private const val TAG = "FooterActionsView"
|
||||||
private val VERBOSE = Log.isLoggable(TAG, Log.VERBOSE)
|
private val VERBOSE = Log.isLoggable(TAG, Log.VERBOSE)
|
||||||
private val MotionEvent.string
|
private val MotionEvent.string
|
||||||
get() = "($id): ($x,$y)"
|
get() = "($id): ($x,$y)"
|
||||||
|
|||||||
@@ -557,9 +557,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
|||||||
public void setQsExpansion(float expansion, float panelExpansionFraction,
|
public void setQsExpansion(float expansion, float panelExpansionFraction,
|
||||||
float proposedTranslation, float squishinessFraction) {
|
float proposedTranslation, float squishinessFraction) {
|
||||||
float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation;
|
float headerTranslation = mTransitioningToFullShade ? 0 : proposedTranslation;
|
||||||
float progress = mTransitioningToFullShade || mState == StatusBarState.KEYGUARD
|
float alphaProgress = mTransitioningToFullShade || mState == StatusBarState.KEYGUARD
|
||||||
? mFullShadeProgress : panelExpansionFraction;
|
? mFullShadeProgress : panelExpansionFraction;
|
||||||
setAlphaAnimationProgress(mInSplitShade ? progress : 1);
|
setAlphaAnimationProgress(mInSplitShade ? alphaProgress : 1);
|
||||||
mContainer.setExpansion(expansion);
|
mContainer.setExpansion(expansion);
|
||||||
final float translationScaleY = (mInSplitShade
|
final float translationScaleY = (mInSplitShade
|
||||||
? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
|
? 1 : QSAnimator.SHORT_PARALLAX_AMOUNT) * (expansion - 1);
|
||||||
@@ -600,7 +600,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
|||||||
}
|
}
|
||||||
mQSPanelController.setIsOnKeyguard(onKeyguard);
|
mQSPanelController.setIsOnKeyguard(onKeyguard);
|
||||||
mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
|
mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
|
||||||
mQSFooterActionController.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
|
float footerActionsExpansion =
|
||||||
|
onKeyguardAndExpanded ? 1 : mInSplitShade ? alphaProgress : expansion;
|
||||||
|
mQSFooterActionController.setExpansion(footerActionsExpansion);
|
||||||
mQSPanelController.setRevealExpansion(expansion);
|
mQSPanelController.setRevealExpansion(expansion);
|
||||||
mQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
|
mQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
|
||||||
mQuickQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
|
mQuickQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
|
||||||
|
|||||||
@@ -22,13 +22,17 @@ import com.android.systemui.plugins.ActivityStarter
|
|||||||
import com.android.systemui.settings.UserTracker
|
import com.android.systemui.settings.UserTracker
|
||||||
import com.android.systemui.statusbar.phone.MultiUserSwitchController
|
import com.android.systemui.statusbar.phone.MultiUserSwitchController
|
||||||
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
import com.android.systemui.statusbar.policy.DeviceProvisionedController
|
||||||
|
import com.android.systemui.statusbar.policy.FakeConfigurationController
|
||||||
import com.android.systemui.statusbar.policy.UserInfoController
|
import com.android.systemui.statusbar.policy.UserInfoController
|
||||||
import com.android.systemui.util.mockito.capture
|
import com.android.systemui.util.mockito.capture
|
||||||
import com.android.systemui.util.settings.FakeSettings
|
import com.android.systemui.util.settings.FakeSettings
|
||||||
import com.android.systemui.utils.leaks.LeakCheckedTest
|
import com.android.systemui.utils.leaks.LeakCheckedTest
|
||||||
|
import com.google.common.truth.Expect
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
|
import javax.inject.Provider
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.ArgumentCaptor
|
import org.mockito.ArgumentCaptor
|
||||||
@@ -42,47 +46,38 @@ import org.mockito.Mockito.clearInvocations
|
|||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.reset
|
import org.mockito.Mockito.reset
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.MockitoAnnotations
|
|
||||||
import javax.inject.Provider
|
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
import org.mockito.MockitoAnnotations
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||||
@RunWith(AndroidTestingRunner::class)
|
@RunWith(AndroidTestingRunner::class)
|
||||||
class FooterActionsControllerTest : LeakCheckedTest() {
|
class FooterActionsControllerTest : LeakCheckedTest() {
|
||||||
@Mock
|
|
||||||
private lateinit var userManager: UserManager
|
@get:Rule var expect: Expect = Expect.create()
|
||||||
@Mock
|
|
||||||
private lateinit var userTracker: UserTracker
|
@Mock private lateinit var userManager: UserManager
|
||||||
@Mock
|
@Mock private lateinit var userTracker: UserTracker
|
||||||
private lateinit var activityStarter: ActivityStarter
|
@Mock private lateinit var activityStarter: ActivityStarter
|
||||||
@Mock
|
@Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
|
||||||
private lateinit var deviceProvisionedController: DeviceProvisionedController
|
@Mock private lateinit var userInfoController: UserInfoController
|
||||||
@Mock
|
@Mock private lateinit var multiUserSwitchControllerFactory: MultiUserSwitchController.Factory
|
||||||
private lateinit var userInfoController: UserInfoController
|
@Mock private lateinit var multiUserSwitchController: MultiUserSwitchController
|
||||||
@Mock
|
@Mock private lateinit var globalActionsDialogProvider: Provider<GlobalActionsDialogLite>
|
||||||
private lateinit var multiUserSwitchControllerFactory: MultiUserSwitchController.Factory
|
@Mock private lateinit var globalActionsDialog: GlobalActionsDialogLite
|
||||||
@Mock
|
@Mock private lateinit var uiEventLogger: UiEventLogger
|
||||||
private lateinit var multiUserSwitchController: MultiUserSwitchController
|
@Mock private lateinit var securityFooterController: QSSecurityFooter
|
||||||
@Mock
|
@Mock private lateinit var fgsManagerController: QSFgsManagerFooter
|
||||||
private lateinit var globalActionsDialogProvider: Provider<GlobalActionsDialogLite>
|
|
||||||
@Mock
|
|
||||||
private lateinit var globalActionsDialog: GlobalActionsDialogLite
|
|
||||||
@Mock
|
|
||||||
private lateinit var uiEventLogger: UiEventLogger
|
|
||||||
@Mock
|
|
||||||
private lateinit var securityFooterController: QSSecurityFooter
|
|
||||||
@Mock
|
|
||||||
private lateinit var fgsManagerController: QSFgsManagerFooter
|
|
||||||
@Captor
|
@Captor
|
||||||
private lateinit var visibilityChangedCaptor:
|
private lateinit var visibilityChangedCaptor:
|
||||||
ArgumentCaptor<VisibilityChangedDispatcher.OnVisibilityChangedListener>
|
ArgumentCaptor<VisibilityChangedDispatcher.OnVisibilityChangedListener>
|
||||||
|
|
||||||
private lateinit var controller: FooterActionsController
|
private lateinit var controller: FooterActionsController
|
||||||
|
|
||||||
|
private val configurationController = FakeConfigurationController()
|
||||||
private val metricsLogger: MetricsLogger = FakeMetricsLogger()
|
private val metricsLogger: MetricsLogger = FakeMetricsLogger()
|
||||||
private lateinit var view: FooterActionsView
|
|
||||||
private val falsingManager: FalsingManagerFake = FalsingManagerFake()
|
private val falsingManager: FalsingManagerFake = FalsingManagerFake()
|
||||||
|
private lateinit var view: FooterActionsView
|
||||||
private lateinit var testableLooper: TestableLooper
|
private lateinit var testableLooper: TestableLooper
|
||||||
private lateinit var fakeSettings: FakeSettings
|
private lateinit var fakeSettings: FakeSettings
|
||||||
private lateinit var securityFooter: View
|
private lateinit var securityFooter: View
|
||||||
@@ -90,12 +85,15 @@ class FooterActionsControllerTest : LeakCheckedTest() {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
|
// We want to make sure testable resources are always used
|
||||||
|
context.ensureTestableResources()
|
||||||
|
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
testableLooper = TestableLooper.get(this)
|
testableLooper = TestableLooper.get(this)
|
||||||
fakeSettings = FakeSettings()
|
fakeSettings = FakeSettings()
|
||||||
|
|
||||||
whenever(multiUserSwitchControllerFactory.create(any()))
|
whenever(multiUserSwitchControllerFactory.create(any()))
|
||||||
.thenReturn(multiUserSwitchController)
|
.thenReturn(multiUserSwitchController)
|
||||||
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
|
whenever(globalActionsDialogProvider.get()).thenReturn(globalActionsDialog)
|
||||||
|
|
||||||
securityFooter = View(mContext)
|
securityFooter = View(mContext)
|
||||||
@@ -135,7 +133,7 @@ class FooterActionsControllerTest : LeakCheckedTest() {
|
|||||||
view.findViewById<View>(R.id.pm_lite).performClick()
|
view.findViewById<View>(R.id.pm_lite).performClick()
|
||||||
// Verify clicks are logged
|
// Verify clicks are logged
|
||||||
verify(uiEventLogger, Mockito.times(1))
|
verify(uiEventLogger, Mockito.times(1))
|
||||||
.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -299,6 +297,86 @@ class FooterActionsControllerTest : LeakCheckedTest() {
|
|||||||
assertThat(booleanCaptor.allValues.last()).isTrue()
|
assertThat(booleanCaptor.allValues.last()).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setExpansion_inSplitShade_alphaFollowsExpansion() {
|
||||||
|
enableSplitShade()
|
||||||
|
|
||||||
|
controller.setExpansion(0f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.25f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0.25f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.5f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0.5f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.75f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0.75f)
|
||||||
|
|
||||||
|
controller.setExpansion(1f)
|
||||||
|
expect.that(view.alpha).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setExpansion_inSplitShade_backgroundAlphaFollowsExpansion_with_0_9_delay() {
|
||||||
|
enableSplitShade()
|
||||||
|
|
||||||
|
controller.setExpansion(0f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.5f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.9f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.91f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isWithin(FLOAT_TOLERANCE).of(0.1f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.95f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isWithin(FLOAT_TOLERANCE).of(0.5f)
|
||||||
|
|
||||||
|
controller.setExpansion(1f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setExpansion_inSingleShade_alphaFollowsExpansion_with_0_9_delay() {
|
||||||
|
disableSplitShade()
|
||||||
|
|
||||||
|
controller.setExpansion(0f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.5f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.9f)
|
||||||
|
expect.that(view.alpha).isEqualTo(0f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.91f)
|
||||||
|
expect.that(view.alpha).isWithin(FLOAT_TOLERANCE).of(0.1f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.95f)
|
||||||
|
expect.that(view.alpha).isWithin(FLOAT_TOLERANCE).of(0.5f)
|
||||||
|
|
||||||
|
controller.setExpansion(1f)
|
||||||
|
expect.that(view.alpha).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setExpansion_inSingleShade_backgroundAlphaAlways1() {
|
||||||
|
disableSplitShade()
|
||||||
|
|
||||||
|
controller.setExpansion(0f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(1f)
|
||||||
|
|
||||||
|
controller.setExpansion(0.5f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(1f)
|
||||||
|
|
||||||
|
controller.setExpansion(1f)
|
||||||
|
expect.that(view.backgroundAlphaFraction).isEqualTo(1f)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setVisibilities(
|
private fun setVisibilities(
|
||||||
securityFooterVisible: Boolean,
|
securityFooterVisible: Boolean,
|
||||||
fgsFooterVisible: Boolean,
|
fgsFooterVisible: Boolean,
|
||||||
@@ -311,15 +389,52 @@ class FooterActionsControllerTest : LeakCheckedTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun inflateView(): FooterActionsView {
|
private fun inflateView(): FooterActionsView {
|
||||||
return LayoutInflater.from(context)
|
return LayoutInflater.from(context).inflate(R.layout.footer_actions, null)
|
||||||
.inflate(R.layout.footer_actions, null) as FooterActionsView
|
as FooterActionsView
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun constructFooterActionsController(view: FooterActionsView): FooterActionsController {
|
private fun constructFooterActionsController(view: FooterActionsView): FooterActionsController {
|
||||||
return FooterActionsController(view, multiUserSwitchControllerFactory,
|
return FooterActionsController(
|
||||||
activityStarter, userManager, userTracker, userInfoController,
|
view,
|
||||||
deviceProvisionedController, securityFooterController, fgsManagerController,
|
multiUserSwitchControllerFactory,
|
||||||
falsingManager, metricsLogger, globalActionsDialogProvider, uiEventLogger,
|
activityStarter,
|
||||||
showPMLiteButton = true, fakeSettings, Handler(testableLooper.looper))
|
userManager,
|
||||||
|
userTracker,
|
||||||
|
userInfoController,
|
||||||
|
deviceProvisionedController,
|
||||||
|
securityFooterController,
|
||||||
|
fgsManagerController,
|
||||||
|
falsingManager,
|
||||||
|
metricsLogger,
|
||||||
|
globalActionsDialogProvider,
|
||||||
|
uiEventLogger,
|
||||||
|
showPMLiteButton = true,
|
||||||
|
fakeSettings,
|
||||||
|
Handler(testableLooper.looper),
|
||||||
|
configurationController)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun enableSplitShade() {
|
||||||
|
setSplitShadeEnabled(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun disableSplitShade() {
|
||||||
|
setSplitShadeEnabled(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setSplitShadeEnabled(enabled: Boolean) {
|
||||||
|
overrideResource(R.bool.config_use_split_notification_shade, enabled)
|
||||||
|
configurationController.notifyConfigurationChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val FLOAT_TOLERANCE = 0.01f
|
||||||
|
|
||||||
|
private val View.backgroundAlphaFraction: Float?
|
||||||
|
get() {
|
||||||
|
return if (background != null) {
|
||||||
|
background.alpha / 255f
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
@@ -204,6 +204,40 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
assertThat(mQsFragmentView.getAlpha()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setQsExpansion_inSplitShade_setsFooterActionsExpansion_basedOnPanelExpFraction() {
|
||||||
|
// Random test values without any meaning. They just have to be different from each other.
|
||||||
|
float expansion = 0.123f;
|
||||||
|
float panelExpansionFraction = 0.321f;
|
||||||
|
float proposedTranslation = 456f;
|
||||||
|
float squishinessFraction = 0.987f;
|
||||||
|
|
||||||
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
|
enableSplitShade();
|
||||||
|
|
||||||
|
fragment.setQsExpansion(expansion, panelExpansionFraction, proposedTranslation,
|
||||||
|
squishinessFraction);
|
||||||
|
|
||||||
|
verify(mQSFooterActionController).setExpansion(panelExpansionFraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setQsExpansion_notInSplitShade_setsFooterActionsExpansion_basedOnExpansion() {
|
||||||
|
// Random test values without any meaning. They just have to be different from each other.
|
||||||
|
float expansion = 0.123f;
|
||||||
|
float panelExpansionFraction = 0.321f;
|
||||||
|
float proposedTranslation = 456f;
|
||||||
|
float squishinessFraction = 0.987f;
|
||||||
|
|
||||||
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
|
disableSplitShade();
|
||||||
|
|
||||||
|
fragment.setQsExpansion(expansion, panelExpansionFraction, proposedTranslation,
|
||||||
|
squishinessFraction);
|
||||||
|
|
||||||
|
verify(mQSFooterActionController).setExpansion(expansion);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getQsMinExpansionHeight_notInSplitShade_returnsHeaderHeight() {
|
public void getQsMinExpansionHeight_notInSplitShade_returnsHeaderHeight() {
|
||||||
QSFragment fragment = resumeAndGetFragment();
|
QSFragment fragment = resumeAndGetFragment();
|
||||||
|
|||||||
Reference in New Issue
Block a user