Loading packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +29 −13 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ import com.android.systemui.flags.FeatureFlagsClassic; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder; import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; import com.android.systemui.log.dagger.KeyguardClockLog; Loading Loading @@ -95,6 +97,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private final ClockEventController mClockEventController; private final LogBuffer mLogBuffer; private final NotificationIconContainerAlwaysOnDisplayViewModel mAodIconsViewModel; private final KeyguardRootViewModel mKeyguardRootViewModel; private final ConfigurationState mConfigurationState; private final ConfigurationController mConfigurationController; private final DozeParameters mDozeParameters; Loading Loading @@ -127,7 +130,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private KeyguardInteractor mKeyguardInteractor; private final DelayableExecutor mUiExecutor; private boolean mCanShowDoubleLineClock = true; private DisposableHandle mAodIconsBindJob; private DisposableHandle mAodIconsBindHandle; @Nullable private NotificationIconContainer mAodIconContainer; @VisibleForTesting Loading Loading @@ -179,6 +182,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS ClockEventController clockEventController, @KeyguardClockLog LogBuffer logBuffer, NotificationIconContainerAlwaysOnDisplayViewModel aodIconsViewModel, KeyguardRootViewModel keyguardRootViewModel, ConfigurationState configurationState, DozeParameters dozeParameters, AlwaysOnDisplayNotificationIconViewStore aodIconViewStore, Loading @@ -199,6 +203,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mClockEventController = clockEventController; mLogBuffer = logBuffer; mAodIconsViewModel = aodIconsViewModel; mKeyguardRootViewModel = keyguardRootViewModel; mConfigurationState = configurationState; mDozeParameters = dozeParameters; mAodIconViewStore = aodIconViewStore; Loading Loading @@ -567,21 +572,32 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mView.findViewById( com.android.systemui.res.R.id.left_aligned_notification_icon_container); if (NotificationIconContainerRefactor.isEnabled()) { if (mAodIconsBindJob != null) { mAodIconsBindJob.dispose(); if (mAodIconsBindHandle != null) { mAodIconsBindHandle.dispose(); } if (nic != null) { nic.setOnLockScreen(true); mAodIconsBindJob = NotificationIconContainerViewBinder.bind( final DisposableHandle viewHandle = NotificationIconContainerViewBinder.bind( nic, mAodIconsViewModel, mConfigurationState, mConfigurationController, mDozeParameters, mAodIconViewStore); final DisposableHandle visHandle = KeyguardRootViewBinder.bindAodIconVisibility( nic, mKeyguardRootViewModel.isNotifIconContainerVisible(), mConfigurationState, mFeatureFlags, mScreenOffAnimationController, mAodIconViewStore ); mScreenOffAnimationController); if (visHandle == null) { mAodIconsBindHandle = viewHandle; } else { mAodIconsBindHandle = () -> { viewHandle.dispose(); visHandle.dispose(); }; } mAodIconContainer = nic; } } else { Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +8 −5 Original line number Diff line number Diff line Loading @@ -27,9 +27,10 @@ import com.android.keyguard.LockIconView import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardStatusViewComponent import com.android.systemui.CoreStartable import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder Loading @@ -46,7 +47,7 @@ import com.android.systemui.shade.NotificationShadeWindowView import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.KeyguardIndicationController import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import dagger.Lazy import javax.inject.Inject Loading @@ -63,14 +64,15 @@ constructor( private val keyguardRootViewModel: KeyguardRootViewModel, private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel, private val notificationShadeWindowView: NotificationShadeWindowView, private val featureFlags: FeatureFlags, private val featureFlags: FeatureFlagsClassic, private val indicationController: KeyguardIndicationController, private val keyguardStateController: KeyguardStateController, private val screenOffAnimationController: ScreenOffAnimationController, private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, private val chipbarCoordinator: ChipbarCoordinator, private val keyguardBlueprintCommandListener: KeyguardBlueprintCommandListener, private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel, private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory, private val configuration: ConfigurationState, private val context: Context, private val keyguardIndicationController: KeyguardIndicationController, private val lockIconViewController: Lazy<LockIconViewController>, Loading Loading @@ -143,10 +145,11 @@ constructor( KeyguardRootViewBinder.bind( keyguardRootView, keyguardRootViewModel, configuration, featureFlags, occludingAppDeviceEntryMessageViewModel, chipbarCoordinator, keyguardStateController, screenOffAnimationController, shadeInteractor, { keyguardStatusViewController!!.getClockController() }, interactionJankMonitor, Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +158 −6 Original line number Diff line number Diff line Loading @@ -16,25 +16,31 @@ package com.android.systemui.keyguard.ui.binder import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.annotation.DrawableRes import android.view.HapticFeedbackConstants import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup import android.view.ViewGroup.OnHierarchyChangeListener import android.view.ViewPropertyAnimator import android.view.WindowInsets import android.view.WindowInsets.Type import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.internal.jank.InteractionJankMonitor import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD import com.android.keyguard.KeyguardClockSwitch.MISSING_CLOCK_ID import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.flags.RefactorFlag import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel Loading @@ -42,29 +48,38 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.ClockController import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.CrossFadeHelper import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.ViewPriority import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo import com.android.systemui.util.ui.AnimatedValue import com.android.systemui.util.ui.isAnimating import com.android.systemui.util.ui.stopAnimating import com.android.systemui.util.ui.value import javax.inject.Provider import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch /** Bind occludingAppDeviceEntryMessageViewModel to run whenever the keyguard view is attached. */ @ExperimentalCoroutinesApi @OptIn(ExperimentalCoroutinesApi::class) object KeyguardRootViewBinder { @JvmStatic fun bind( view: ViewGroup, viewModel: KeyguardRootViewModel, featureFlags: FeatureFlags, configuration: ConfigurationState, featureFlags: FeatureFlagsClassic, occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, chipbarCoordinator: ChipbarCoordinator, keyguardStateController: KeyguardStateController, screenOffAnimationController: ScreenOffAnimationController, shadeInteractor: ShadeInteractor, clockControllerProvider: Provider<ClockController>?, interactionJankMonitor: InteractionJankMonitor?, Loading Loading @@ -149,6 +164,24 @@ object KeyguardRootViewBinder { } } if (NotificationIconContainerRefactor.isEnabled) { launch { val iconsAppearTranslationPx = configuration .getDimensionPixelSize(R.dimen.shelf_appear_translation) .stateIn(this) viewModel.isNotifIconContainerVisible.collect { isVisible -> childViews[aodNotificationIconContainerId] ?.setAodNotifIconContainerIsVisible( isVisible, featureFlags, iconsAppearTranslationPx.value, screenOffAnimationController, ) } } } interactionJankMonitor?.let { jankMonitor -> launch { viewModel.goneToAodTransition.collect { Loading Loading @@ -312,5 +345,124 @@ object KeyguardRootViewBinder { } } @JvmStatic fun bindAodIconVisibility( view: View, isVisible: Flow<AnimatedValue<Boolean>>, configuration: ConfigurationState, featureFlags: FeatureFlagsClassic, screenOffAnimationController: ScreenOffAnimationController, ): DisposableHandle? { RefactorFlag(featureFlags, Flags.MIGRATE_KEYGUARD_STATUS_VIEW).assertInLegacyMode() if (NotificationIconContainerRefactor.isUnexpectedlyInLegacyMode()) return null return view.repeatWhenAttached { lifecycleScope.launch { val iconAppearTranslationPx = configuration .getDimensionPixelSize(R.dimen.shelf_appear_translation) .stateIn(this) isVisible.collect { isVisible -> view.setAodNotifIconContainerIsVisible( isVisible, featureFlags, iconAppearTranslationPx.value, screenOffAnimationController, ) } } } } private fun View.setAodNotifIconContainerIsVisible( isVisible: AnimatedValue<Boolean>, featureFlags: FeatureFlagsClassic, iconsAppearTranslationPx: Int, screenOffAnimationController: ScreenOffAnimationController, ) { val statusViewMigrated = featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW) animate().cancel() val animatorListener = object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { isVisible.stopAnimating() } } when { !isVisible.isAnimating -> { alpha = 1f if (!statusViewMigrated) { translationY = 0f } visibility = if (isVisible.value) View.VISIBLE else View.INVISIBLE } featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> { animateInIconTranslation(statusViewMigrated) if (isVisible.value) { CrossFadeHelper.fadeIn(this, animatorListener) } else { CrossFadeHelper.fadeOut(this, animatorListener) } } !isVisible.value -> { // Let's make sure the icon are translated to 0, since we cancelled it above animateInIconTranslation(statusViewMigrated) CrossFadeHelper.fadeOut(this, animatorListener) } visibility != View.VISIBLE -> { // No fading here, let's just appear the icons instead! visibility = View.VISIBLE alpha = 1f appearIcons( animate = screenOffAnimationController.shouldAnimateAodIcons(), iconsAppearTranslationPx, statusViewMigrated, animatorListener, ) } else -> { // Let's make sure the icons are translated to 0, since we cancelled it above animateInIconTranslation(statusViewMigrated) // We were fading out, let's fade in instead CrossFadeHelper.fadeIn(this, animatorListener) } } } private fun View.appearIcons( animate: Boolean, iconAppearTranslation: Int, statusViewMigrated: Boolean, animatorListener: Animator.AnimatorListener, ) { if (animate) { if (!statusViewMigrated) { translationY = -iconAppearTranslation.toFloat() } alpha = 0f animate() .alpha(1f) .setInterpolator(Interpolators.LINEAR) .setDuration(AOD_ICONS_APPEAR_DURATION) .apply { if (statusViewMigrated) animateInIconTranslation() } .setListener(animatorListener) .start() } else { alpha = 1.0f if (!statusViewMigrated) { translationY = 0f } } } private fun View.animateInIconTranslation(statusViewMigrated: Boolean) { if (!statusViewMigrated) { animate().animateInIconTranslation().setDuration(AOD_ICONS_APPEAR_DURATION).start() } } private fun ViewPropertyAnimator.animateInIconTranslation(): ViewPropertyAnimator = setInterpolator(Interpolators.DECELERATE_QUINT).translationY(0f) private const val ID = "occluding_app_device_entry_unlock_msg" private const val AOD_ICONS_APPEAR_DURATION: Long = 200 } packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +8 −7 Original line number Diff line number Diff line Loading @@ -44,10 +44,10 @@ import com.android.keyguard.KeyguardClockSwitch import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockViewBinder import com.android.systemui.keyguard.ui.binder.KeyguardPreviewSmartspaceViewBinder Loading Loading @@ -76,7 +76,7 @@ import com.android.systemui.statusbar.KeyguardIndicationController import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController import com.android.systemui.statusbar.phone.KeyguardBottomAreaView import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import dagger.assisted.Assisted import dagger.assisted.AssistedInject Loading @@ -99,12 +99,13 @@ constructor( private val quickAffordancesCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, displayManager: DisplayManager, private val windowManager: WindowManager, private val configuration: ConfigurationState, private val clockController: ClockEventController, private val clockRegistry: ClockRegistry, private val broadcastDispatcher: BroadcastDispatcher, private val lockscreenSmartspaceController: LockscreenSmartspaceController, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val featureFlags: FeatureFlags, private val featureFlags: FeatureFlagsClassic, private val falsingManager: FalsingManager, private val vibratorHelper: VibratorHelper, private val indicationController: KeyguardIndicationController, Loading @@ -113,9 +114,8 @@ constructor( private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel, private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, private val chipbarCoordinator: ChipbarCoordinator, private val keyguardStateController: KeyguardStateController, private val screenOffAnimationController: ScreenOffAnimationController, private val shadeInteractor: ShadeInteractor, private val deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor, ) { val hostToken: IBinder? = bundle.getBinder(KEY_HOST_TOKEN) Loading Loading @@ -341,10 +341,11 @@ constructor( KeyguardRootViewBinder.bind( keyguardRootView, keyguardRootViewModel, configuration, featureFlags, occludingAppDeviceEntryMessageViewModel, chipbarCoordinator, keyguardStateController, screenOffAnimationController, shadeInteractor, null, // clock provider only needed for burn in null, // jank monitor not required for preview mode Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt +0 −6 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel Loading @@ -39,7 +38,6 @@ import com.android.systemui.statusbar.notification.shared.NotificationIconContai import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.ConfigurationController import javax.inject.Inject import kotlinx.coroutines.DisposableHandle Loading @@ -54,9 +52,7 @@ constructor( private val featureFlags: FeatureFlagsClassic, private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore, private val notificationPanelView: NotificationPanelView, private val notificationIconAreaController: NotificationIconAreaController, private val screenOffAnimationController: ScreenOffAnimationController, ) : KeyguardSection() { private var nicBindingDisposable: DisposableHandle? = null Loading Loading @@ -97,8 +93,6 @@ constructor( configurationState, configurationController, dozeParameters, featureFlags, screenOffAnimationController, nicAodIconViewStore, ) } else { Loading Loading
packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java +29 −13 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ import com.android.systemui.flags.FeatureFlagsClassic; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; import com.android.systemui.keyguard.ui.binder.KeyguardRootViewBinder; import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; import com.android.systemui.log.dagger.KeyguardClockLog; Loading Loading @@ -95,6 +97,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private final ClockEventController mClockEventController; private final LogBuffer mLogBuffer; private final NotificationIconContainerAlwaysOnDisplayViewModel mAodIconsViewModel; private final KeyguardRootViewModel mKeyguardRootViewModel; private final ConfigurationState mConfigurationState; private final ConfigurationController mConfigurationController; private final DozeParameters mDozeParameters; Loading Loading @@ -127,7 +130,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS private KeyguardInteractor mKeyguardInteractor; private final DelayableExecutor mUiExecutor; private boolean mCanShowDoubleLineClock = true; private DisposableHandle mAodIconsBindJob; private DisposableHandle mAodIconsBindHandle; @Nullable private NotificationIconContainer mAodIconContainer; @VisibleForTesting Loading Loading @@ -179,6 +182,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS ClockEventController clockEventController, @KeyguardClockLog LogBuffer logBuffer, NotificationIconContainerAlwaysOnDisplayViewModel aodIconsViewModel, KeyguardRootViewModel keyguardRootViewModel, ConfigurationState configurationState, DozeParameters dozeParameters, AlwaysOnDisplayNotificationIconViewStore aodIconViewStore, Loading @@ -199,6 +203,7 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mClockEventController = clockEventController; mLogBuffer = logBuffer; mAodIconsViewModel = aodIconsViewModel; mKeyguardRootViewModel = keyguardRootViewModel; mConfigurationState = configurationState; mDozeParameters = dozeParameters; mAodIconViewStore = aodIconViewStore; Loading Loading @@ -567,21 +572,32 @@ public class KeyguardClockSwitchController extends ViewController<KeyguardClockS mView.findViewById( com.android.systemui.res.R.id.left_aligned_notification_icon_container); if (NotificationIconContainerRefactor.isEnabled()) { if (mAodIconsBindJob != null) { mAodIconsBindJob.dispose(); if (mAodIconsBindHandle != null) { mAodIconsBindHandle.dispose(); } if (nic != null) { nic.setOnLockScreen(true); mAodIconsBindJob = NotificationIconContainerViewBinder.bind( final DisposableHandle viewHandle = NotificationIconContainerViewBinder.bind( nic, mAodIconsViewModel, mConfigurationState, mConfigurationController, mDozeParameters, mAodIconViewStore); final DisposableHandle visHandle = KeyguardRootViewBinder.bindAodIconVisibility( nic, mKeyguardRootViewModel.isNotifIconContainerVisible(), mConfigurationState, mFeatureFlags, mScreenOffAnimationController, mAodIconViewStore ); mScreenOffAnimationController); if (visHandle == null) { mAodIconsBindHandle = viewHandle; } else { mAodIconsBindHandle = () -> { viewHandle.dispose(); visHandle.dispose(); }; } mAodIconContainer = nic; } } else { Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +8 −5 Original line number Diff line number Diff line Loading @@ -27,9 +27,10 @@ import com.android.keyguard.LockIconView import com.android.keyguard.LockIconViewController import com.android.keyguard.dagger.KeyguardStatusViewComponent import com.android.systemui.CoreStartable import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.SysUISingleton import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.ui.binder.KeyguardBlueprintViewBinder import com.android.systemui.keyguard.ui.binder.KeyguardIndicationAreaBinder Loading @@ -46,7 +47,7 @@ import com.android.systemui.shade.NotificationShadeWindowView import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.KeyguardIndicationController import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import dagger.Lazy import javax.inject.Inject Loading @@ -63,14 +64,15 @@ constructor( private val keyguardRootViewModel: KeyguardRootViewModel, private val keyguardIndicationAreaViewModel: KeyguardIndicationAreaViewModel, private val notificationShadeWindowView: NotificationShadeWindowView, private val featureFlags: FeatureFlags, private val featureFlags: FeatureFlagsClassic, private val indicationController: KeyguardIndicationController, private val keyguardStateController: KeyguardStateController, private val screenOffAnimationController: ScreenOffAnimationController, private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, private val chipbarCoordinator: ChipbarCoordinator, private val keyguardBlueprintCommandListener: KeyguardBlueprintCommandListener, private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel, private val keyguardStatusViewComponentFactory: KeyguardStatusViewComponent.Factory, private val configuration: ConfigurationState, private val context: Context, private val keyguardIndicationController: KeyguardIndicationController, private val lockIconViewController: Lazy<LockIconViewController>, Loading Loading @@ -143,10 +145,11 @@ constructor( KeyguardRootViewBinder.bind( keyguardRootView, keyguardRootViewModel, configuration, featureFlags, occludingAppDeviceEntryMessageViewModel, chipbarCoordinator, keyguardStateController, screenOffAnimationController, shadeInteractor, { keyguardStatusViewController!!.getClockController() }, interactionJankMonitor, Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +158 −6 Original line number Diff line number Diff line Loading @@ -16,25 +16,31 @@ package com.android.systemui.keyguard.ui.binder import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.annotation.DrawableRes import android.view.HapticFeedbackConstants import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup import android.view.ViewGroup.OnHierarchyChangeListener import android.view.ViewPropertyAnimator import android.view.WindowInsets import android.view.WindowInsets.Type import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.android.app.animation.Interpolators import com.android.internal.jank.InteractionJankMonitor import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD import com.android.keyguard.KeyguardClockSwitch.MISSING_CLOCK_ID import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.flags.RefactorFlag import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel Loading @@ -42,29 +48,38 @@ import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.ClockController import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor import com.android.systemui.statusbar.CrossFadeHelper import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.notification.shared.NotificationIconContainerRefactor import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.ViewPriority import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo import com.android.systemui.util.ui.AnimatedValue import com.android.systemui.util.ui.isAnimating import com.android.systemui.util.ui.stopAnimating import com.android.systemui.util.ui.value import javax.inject.Provider import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch /** Bind occludingAppDeviceEntryMessageViewModel to run whenever the keyguard view is attached. */ @ExperimentalCoroutinesApi @OptIn(ExperimentalCoroutinesApi::class) object KeyguardRootViewBinder { @JvmStatic fun bind( view: ViewGroup, viewModel: KeyguardRootViewModel, featureFlags: FeatureFlags, configuration: ConfigurationState, featureFlags: FeatureFlagsClassic, occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, chipbarCoordinator: ChipbarCoordinator, keyguardStateController: KeyguardStateController, screenOffAnimationController: ScreenOffAnimationController, shadeInteractor: ShadeInteractor, clockControllerProvider: Provider<ClockController>?, interactionJankMonitor: InteractionJankMonitor?, Loading Loading @@ -149,6 +164,24 @@ object KeyguardRootViewBinder { } } if (NotificationIconContainerRefactor.isEnabled) { launch { val iconsAppearTranslationPx = configuration .getDimensionPixelSize(R.dimen.shelf_appear_translation) .stateIn(this) viewModel.isNotifIconContainerVisible.collect { isVisible -> childViews[aodNotificationIconContainerId] ?.setAodNotifIconContainerIsVisible( isVisible, featureFlags, iconsAppearTranslationPx.value, screenOffAnimationController, ) } } } interactionJankMonitor?.let { jankMonitor -> launch { viewModel.goneToAodTransition.collect { Loading Loading @@ -312,5 +345,124 @@ object KeyguardRootViewBinder { } } @JvmStatic fun bindAodIconVisibility( view: View, isVisible: Flow<AnimatedValue<Boolean>>, configuration: ConfigurationState, featureFlags: FeatureFlagsClassic, screenOffAnimationController: ScreenOffAnimationController, ): DisposableHandle? { RefactorFlag(featureFlags, Flags.MIGRATE_KEYGUARD_STATUS_VIEW).assertInLegacyMode() if (NotificationIconContainerRefactor.isUnexpectedlyInLegacyMode()) return null return view.repeatWhenAttached { lifecycleScope.launch { val iconAppearTranslationPx = configuration .getDimensionPixelSize(R.dimen.shelf_appear_translation) .stateIn(this) isVisible.collect { isVisible -> view.setAodNotifIconContainerIsVisible( isVisible, featureFlags, iconAppearTranslationPx.value, screenOffAnimationController, ) } } } } private fun View.setAodNotifIconContainerIsVisible( isVisible: AnimatedValue<Boolean>, featureFlags: FeatureFlagsClassic, iconsAppearTranslationPx: Int, screenOffAnimationController: ScreenOffAnimationController, ) { val statusViewMigrated = featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW) animate().cancel() val animatorListener = object : AnimatorListenerAdapter() { override fun onAnimationEnd(animation: Animator) { isVisible.stopAnimating() } } when { !isVisible.isAnimating -> { alpha = 1f if (!statusViewMigrated) { translationY = 0f } visibility = if (isVisible.value) View.VISIBLE else View.INVISIBLE } featureFlags.isEnabled(Flags.NEW_AOD_TRANSITION) -> { animateInIconTranslation(statusViewMigrated) if (isVisible.value) { CrossFadeHelper.fadeIn(this, animatorListener) } else { CrossFadeHelper.fadeOut(this, animatorListener) } } !isVisible.value -> { // Let's make sure the icon are translated to 0, since we cancelled it above animateInIconTranslation(statusViewMigrated) CrossFadeHelper.fadeOut(this, animatorListener) } visibility != View.VISIBLE -> { // No fading here, let's just appear the icons instead! visibility = View.VISIBLE alpha = 1f appearIcons( animate = screenOffAnimationController.shouldAnimateAodIcons(), iconsAppearTranslationPx, statusViewMigrated, animatorListener, ) } else -> { // Let's make sure the icons are translated to 0, since we cancelled it above animateInIconTranslation(statusViewMigrated) // We were fading out, let's fade in instead CrossFadeHelper.fadeIn(this, animatorListener) } } } private fun View.appearIcons( animate: Boolean, iconAppearTranslation: Int, statusViewMigrated: Boolean, animatorListener: Animator.AnimatorListener, ) { if (animate) { if (!statusViewMigrated) { translationY = -iconAppearTranslation.toFloat() } alpha = 0f animate() .alpha(1f) .setInterpolator(Interpolators.LINEAR) .setDuration(AOD_ICONS_APPEAR_DURATION) .apply { if (statusViewMigrated) animateInIconTranslation() } .setListener(animatorListener) .start() } else { alpha = 1.0f if (!statusViewMigrated) { translationY = 0f } } } private fun View.animateInIconTranslation(statusViewMigrated: Boolean) { if (!statusViewMigrated) { animate().animateInIconTranslation().setDuration(AOD_ICONS_APPEAR_DURATION).start() } } private fun ViewPropertyAnimator.animateInIconTranslation(): ViewPropertyAnimator = setInterpolator(Interpolators.DECELERATE_QUINT).translationY(0f) private const val ID = "occluding_app_device_entry_unlock_msg" private const val AOD_ICONS_APPEAR_DURATION: Long = 200 }
packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +8 −7 Original line number Diff line number Diff line Loading @@ -44,10 +44,10 @@ import com.android.keyguard.KeyguardClockSwitch import com.android.systemui.animation.view.LaunchableImageView import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.common.ui.ConfigurationState import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.deviceentry.domain.interactor.DeviceEntryHapticsInteractor import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.ui.binder.KeyguardPreviewClockViewBinder import com.android.systemui.keyguard.ui.binder.KeyguardPreviewSmartspaceViewBinder Loading Loading @@ -76,7 +76,7 @@ import com.android.systemui.statusbar.KeyguardIndicationController import com.android.systemui.statusbar.VibratorHelper import com.android.systemui.statusbar.lockscreen.LockscreenSmartspaceController import com.android.systemui.statusbar.phone.KeyguardBottomAreaView import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator import dagger.assisted.Assisted import dagger.assisted.AssistedInject Loading @@ -99,12 +99,13 @@ constructor( private val quickAffordancesCombinedViewModel: KeyguardQuickAffordancesCombinedViewModel, displayManager: DisplayManager, private val windowManager: WindowManager, private val configuration: ConfigurationState, private val clockController: ClockEventController, private val clockRegistry: ClockRegistry, private val broadcastDispatcher: BroadcastDispatcher, private val lockscreenSmartspaceController: LockscreenSmartspaceController, private val udfpsOverlayInteractor: UdfpsOverlayInteractor, private val featureFlags: FeatureFlags, private val featureFlags: FeatureFlagsClassic, private val falsingManager: FalsingManager, private val vibratorHelper: VibratorHelper, private val indicationController: KeyguardIndicationController, Loading @@ -113,9 +114,8 @@ constructor( private val keyguardBlueprintViewModel: KeyguardBlueprintViewModel, private val occludingAppDeviceEntryMessageViewModel: OccludingAppDeviceEntryMessageViewModel, private val chipbarCoordinator: ChipbarCoordinator, private val keyguardStateController: KeyguardStateController, private val screenOffAnimationController: ScreenOffAnimationController, private val shadeInteractor: ShadeInteractor, private val deviceEntryHapticsInteractor: DeviceEntryHapticsInteractor, ) { val hostToken: IBinder? = bundle.getBinder(KEY_HOST_TOKEN) Loading Loading @@ -341,10 +341,11 @@ constructor( KeyguardRootViewBinder.bind( keyguardRootView, keyguardRootViewModel, configuration, featureFlags, occludingAppDeviceEntryMessageViewModel, chipbarCoordinator, keyguardStateController, screenOffAnimationController, shadeInteractor, null, // clock provider only needed for burn in null, // jank monitor not required for preview mode Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/view/layout/sections/AodNotificationIconsSection.kt +0 −6 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ import com.android.systemui.flags.FeatureFlagsClassic import com.android.systemui.flags.Flags import com.android.systemui.keyguard.shared.model.KeyguardSection import com.android.systemui.res.R import com.android.systemui.shade.NotificationPanelView import com.android.systemui.statusbar.notification.icon.ui.viewbinder.AlwaysOnDisplayNotificationIconViewStore import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder import com.android.systemui.statusbar.notification.icon.ui.viewmodel.NotificationIconContainerAlwaysOnDisplayViewModel Loading @@ -39,7 +38,6 @@ import com.android.systemui.statusbar.notification.shared.NotificationIconContai import com.android.systemui.statusbar.phone.DozeParameters import com.android.systemui.statusbar.phone.NotificationIconAreaController import com.android.systemui.statusbar.phone.NotificationIconContainer import com.android.systemui.statusbar.phone.ScreenOffAnimationController import com.android.systemui.statusbar.policy.ConfigurationController import javax.inject.Inject import kotlinx.coroutines.DisposableHandle Loading @@ -54,9 +52,7 @@ constructor( private val featureFlags: FeatureFlagsClassic, private val nicAodViewModel: NotificationIconContainerAlwaysOnDisplayViewModel, private val nicAodIconViewStore: AlwaysOnDisplayNotificationIconViewStore, private val notificationPanelView: NotificationPanelView, private val notificationIconAreaController: NotificationIconAreaController, private val screenOffAnimationController: ScreenOffAnimationController, ) : KeyguardSection() { private var nicBindingDisposable: DisposableHandle? = null Loading Loading @@ -97,8 +93,6 @@ constructor( configurationState, configurationController, dozeParameters, featureFlags, screenOffAnimationController, nicAodIconViewStore, ) } else { Loading