diff options
| author | 2023-12-26 13:33:27 +0000 | |
|---|---|---|
| committer | 2023-12-26 13:33:27 +0000 | |
| commit | 91487ebd89d54aae12d0485ed321c1a4ce6f38a6 (patch) | |
| tree | d02a1f60a9167ab2c7af1e6da91447d4cec4e658 | |
| parent | 13961f6fe5a190e712f5d7da6208685febc374e6 (diff) | |
| parent | 1bc217c6e86d1a92a91615d49f964d2591f517df (diff) | |
Merge changes I771230c1,I460dfc11 into main
* changes:
Support media on splitshade with constraints
Fix NSSL flicker when going to/from OCCLUDED
8 files changed, 192 insertions, 28 deletions
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml index 557fbf21d5c4..e6122a094707 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml @@ -43,7 +43,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> <FrameLayout - android:id="@+id/status_view_media_container" + android:id="@id/status_view_media_container" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="@dimen/qs_media_padding" diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml index d511caba941b..80725c2bd4b5 100644 --- a/packages/SystemUI/res/values/ids.xml +++ b/packages/SystemUI/res/values/ids.xml @@ -225,6 +225,8 @@ <item type="id" name="communal_tutorial_indicator" /> <item type="id" name="nssl_placeholder_barrier_bottom" /> <item type="id" name="ambient_indication_container" /> + <item type="id" name="status_view_media_container" /> + <item type="id" name="smart_space_barrier_bottom" /> <!-- Privacy dialog --> <item type="id" name="privacy_dialog_close_app_button" /> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt index 16539db648bc..5344696b92fe 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/blueprints/SplitShadeKeyguardBlueprint.kt @@ -33,6 +33,7 @@ import com.android.systemui.keyguard.ui.view.layout.sections.KeyguardSectionsMod import com.android.systemui.keyguard.ui.view.layout.sections.SmartspaceSection import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeClockSection import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeGuidelines +import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeMediaSection import com.android.systemui.keyguard.ui.view.layout.sections.SplitShadeNotificationStackScrollLayoutSection import com.android.systemui.util.kotlin.getOrNull import java.util.Optional @@ -63,6 +64,7 @@ constructor( communalTutorialIndicatorSection: CommunalTutorialIndicatorSection, smartspaceSection: SmartspaceSection, clockSection: SplitShadeClockSection, + mediaSection: SplitShadeMediaSection, ) : KeyguardBlueprint { override val id: String = ID @@ -81,6 +83,7 @@ constructor( aodBurnInSection, communalTutorialIndicatorSection, clockSection, + mediaSection, defaultDeviceEntrySection, // Add LAST: Intentionally has z-order above other views. ) diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt new file mode 100644 index 000000000000..5afdbaa47d95 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/SplitShadeMediaSection.kt @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2023 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.keyguard.ui.view.layout.sections + +import android.content.Context +import android.view.View +import android.view.ViewGroup.LayoutParams.WRAP_CONTENT +import android.widget.FrameLayout +import androidx.constraintlayout.widget.Barrier +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.constraintlayout.widget.ConstraintSet +import androidx.constraintlayout.widget.ConstraintSet.BOTTOM +import androidx.constraintlayout.widget.ConstraintSet.END +import androidx.constraintlayout.widget.ConstraintSet.MATCH_CONSTRAINT +import androidx.constraintlayout.widget.ConstraintSet.PARENT_ID +import androidx.constraintlayout.widget.ConstraintSet.START +import androidx.constraintlayout.widget.ConstraintSet.TOP +import com.android.systemui.Flags.migrateClocksToBlueprint +import com.android.systemui.keyguard.shared.model.KeyguardSection +import com.android.systemui.keyguard.ui.viewmodel.KeyguardSmartspaceViewModel +import com.android.systemui.media.controls.ui.KeyguardMediaController +import com.android.systemui.res.R +import com.android.systemui.shade.NotificationPanelView +import javax.inject.Inject + +/** Aligns media on left side for split shade, below smartspace, date, and weather. */ +class SplitShadeMediaSection +@Inject +constructor( + private val context: Context, + private val notificationPanelView: NotificationPanelView, + private val keyguardSmartspaceViewModel: KeyguardSmartspaceViewModel, + private val keyguardMediaController: KeyguardMediaController +) : KeyguardSection() { + private val mediaContainerId = R.id.status_view_media_container + private val smartSpaceBarrier = R.id.smart_space_barrier_bottom + + override fun addViews(constraintLayout: ConstraintLayout) { + if (!migrateClocksToBlueprint()) { + return + } + + notificationPanelView.findViewById<View>(mediaContainerId)?.let { + notificationPanelView.removeView(it) + } + + val mediaFrame = + FrameLayout(context, null).apply { + id = mediaContainerId + val padding = context.resources.getDimensionPixelSize(R.dimen.qs_media_padding) + val horizontalPadding = + padding + + context.resources.getDimensionPixelSize( + R.dimen.status_view_margin_horizontal + ) + + setPaddingRelative(horizontalPadding, padding, horizontalPadding, padding) + } + constraintLayout.addView(mediaFrame) + keyguardMediaController.attachSplitShadeContainer(mediaFrame) + } + + override fun bindData(constraintLayout: ConstraintLayout) {} + + override fun applyConstraints(constraintSet: ConstraintSet) { + if (!migrateClocksToBlueprint()) { + return + } + + constraintSet.apply { + constrainWidth(mediaContainerId, MATCH_CONSTRAINT) + constrainHeight(mediaContainerId, WRAP_CONTENT) + + createBarrier( + smartSpaceBarrier, + Barrier.BOTTOM, + 0, + *intArrayOf( + keyguardSmartspaceViewModel.smartspaceViewId, + keyguardSmartspaceViewModel.dateId, + keyguardSmartspaceViewModel.weatherId, + ) + ) + connect(mediaContainerId, TOP, smartSpaceBarrier, BOTTOM) + connect(mediaContainerId, START, PARENT_ID, START) + connect(mediaContainerId, END, R.id.split_shade_guideline, END) + } + } + + override fun removeViews(constraintLayout: ConstraintLayout) { + if (!migrateClocksToBlueprint()) { + return + } + + constraintLayout.removeView(mediaContainerId) + } +} diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt index 945bf9a5c0b2..e15e03822610 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/KeyguardMediaController.kt @@ -27,6 +27,7 @@ import android.view.View import android.view.ViewGroup import androidx.annotation.VisibleForTesting import com.android.systemui.Dumpable +import com.android.systemui.Flags.migrateClocksToBlueprint import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager @@ -180,7 +181,11 @@ constructor( /** Called whenever the media hosts visibility changes */ private fun onMediaHostVisibilityChanged(visible: Boolean) { refreshMediaPosition(reason = "onMediaHostVisibilityChanged") + if (visible) { + if (migrateClocksToBlueprint() && useSplitShade) { + return + } mediaHost.hostView.layoutParams.apply { height = ViewGroup.LayoutParams.WRAP_CONTENT width = ViewGroup.LayoutParams.MATCH_PARENT diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 17eb3c83fefe..286037ef1961 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1160,9 +1160,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump // Occluded->Lockscreen collectFlow(mView, mKeyguardTransitionInteractor.getOccludedToLockscreenTransition(), mOccludedToLockscreenTransition, mMainDispatcher); - if (!KeyguardShadeMigrationNssl.isEnabled()) { - collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(), + collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); + if (!KeyguardShadeMigrationNssl.isEnabled()) { collectFlow(mView, mOccludedToLockscreenTransitionViewModel.getLockscreenTranslationY(), setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher); @@ -1192,8 +1192,10 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mLockscreenToOccludedTransition, mMainDispatcher); collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenAlpha(), setTransitionAlpha(mNotificationStackScrollLayoutController), mMainDispatcher); - collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenTranslationY(), - setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher); + if (!KeyguardShadeMigrationNssl.isEnabled()) { + collectFlow(mView, mLockscreenToOccludedTransitionViewModel.getLockscreenTranslationY(), + setTransitionY(mNotificationStackScrollLayoutController), mMainDispatcher); + } // Primary bouncer->Gone (ensures lockscreen content is not visible on successful auth) collectFlow(mView, mPrimaryBouncerToGoneTransitionViewModel.getLockscreenAlpha(), @@ -1463,6 +1465,9 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } private void attachSplitShadeMediaPlayerContainer(FrameLayout container) { + if (migrateClocksToBlueprint()) { + return; + } mKeyguardMediaController.attachSplitShadeContainer(container); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt index eff91e55d9a8..5ee38bebc99b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt @@ -25,6 +25,8 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED +import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING +import com.android.systemui.keyguard.shared.model.TransitionState.STARTED import com.android.systemui.keyguard.ui.viewmodel.LockscreenToOccludedTransitionViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludedToLockscreenTransitionViewModel import com.android.systemui.shade.domain.interactor.ShadeInteractor @@ -71,6 +73,20 @@ constructor( KeyguardState.PRIMARY_BOUNCER ) + private val lockscreenToOccludedRunning = + keyguardTransitionInteractor + .transition(KeyguardState.LOCKSCREEN, KeyguardState.OCCLUDED) + .map { it.transitionState == STARTED || it.transitionState == RUNNING } + .distinctUntilChanged() + .onStart { emit(false) } + + private val occludedToLockscreenRunning = + keyguardTransitionInteractor + .transition(KeyguardState.OCCLUDED, KeyguardState.LOCKSCREEN) + .map { it.transitionState == STARTED || it.transitionState == RUNNING } + .distinctUntilChanged() + .onStart { emit(false) } + val shadeCollapseFadeInComplete = MutableStateFlow(false) val configurationBasedDimensions: Flow<ConfigurationBasedDimensions> = @@ -122,7 +138,11 @@ constructor( ) { isKeyguard, isShadeVisible, qsExpansion -> isKeyguard && !(isShadeVisible || qsExpansion) } - .distinctUntilChanged() + .stateIn( + scope = applicationScope, + started = SharingStarted.Eagerly, + initialValue = false, + ) /** Fade in only for use after the shade collapses */ val shadeCollpaseFadeIn: Flow<Boolean> = @@ -182,26 +202,37 @@ constructor( ) val alpha: Flow<Float> = - isOnLockscreenWithoutShade - .flatMapLatest { isOnLockscreenWithoutShade -> - combineTransform( - merge( - occludedToLockscreenTransitionViewModel.lockscreenAlpha, - lockscreenToOccludedTransitionViewModel.lockscreenAlpha, - keyguardInteractor.keyguardAlpha, - ), - shadeCollpaseFadeIn, - ) { alpha, shadeCollpaseFadeIn -> - if (isOnLockscreenWithoutShade) { - if (!shadeCollpaseFadeIn) { - emit(alpha) - } + // Due to issues with the legacy shade, some shade expansion events are sent incorrectly, + // such as when the shade resets. This can happen while the LOCKSCREEN<->OCCLUDED transition + // is running. Therefore use a series of flatmaps to prevent unwanted interruptions while + // those transitions are in progress. Without this, the alpha value will produce a visible + // flicker. + lockscreenToOccludedRunning.flatMapLatest { isLockscreenToOccludedRunning -> + if (isLockscreenToOccludedRunning) { + lockscreenToOccludedTransitionViewModel.lockscreenAlpha + } else { + occludedToLockscreenRunning.flatMapLatest { isOccludedToLockscreenRunning -> + if (isOccludedToLockscreenRunning) { + occludedToLockscreenTransitionViewModel.lockscreenAlpha.onStart { emit(0f) } } else { - emit(1f) + isOnLockscreenWithoutShade.flatMapLatest { isOnLockscreenWithoutShade -> + combineTransform( + keyguardInteractor.keyguardAlpha, + shadeCollpaseFadeIn, + ) { alpha, shadeCollpaseFadeIn -> + if (isOnLockscreenWithoutShade) { + if (!shadeCollpaseFadeIn) { + emit(alpha) + } + } else { + emit(1f) + } + } + } } } } - .distinctUntilChanged() + } /** * Under certain scenarios, such as swiping up on the lockscreen, the container will need to be diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt index 36a471238c8a..20020f23b2df 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt @@ -43,6 +43,7 @@ import com.android.systemui.statusbar.notification.stack.domain.interactor.share import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest import org.junit.Before @@ -418,13 +419,13 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { } @Test - fun shadeCollpaseFadeIn() = + fun shadeCollapseFadeIn() = testScope.runTest { + val fadeIn by collectLastValue(underTest.shadeCollpaseFadeIn) + // Start on lockscreen without the shade underTest.setShadeCollapseFadeInComplete(false) showLockscreen() - - val fadeIn by collectLastValue(underTest.shadeCollpaseFadeIn) assertThat(fadeIn).isEqualTo(false) // ... then the shade expands @@ -440,10 +441,12 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { assertThat(fadeIn).isEqualTo(false) } - private suspend fun showLockscreen() { + private suspend fun TestScope.showLockscreen() { shadeRepository.setLockscreenShadeExpansion(0f) shadeRepository.setQsExpansion(0f) + runCurrent() keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD) + runCurrent() keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN, @@ -451,10 +454,12 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { ) } - private suspend fun showLockscreenWithShadeExpanded() { + private suspend fun TestScope.showLockscreenWithShadeExpanded() { shadeRepository.setLockscreenShadeExpansion(1f) shadeRepository.setQsExpansion(0f) + runCurrent() keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED) + runCurrent() keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN, @@ -462,10 +467,12 @@ class SharedNotificationContainerViewModelTest : SysuiTestCase() { ) } - private suspend fun showLockscreenWithQSExpanded() { + private suspend fun TestScope.showLockscreenWithQSExpanded() { shadeRepository.setLockscreenShadeExpansion(0f) shadeRepository.setQsExpansion(1f) + runCurrent() keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED) + runCurrent() keyguardTransitionRepository.sendTransitionSteps( from = KeyguardState.AOD, to = KeyguardState.LOCKSCREEN, |