Merge "[Status bar] Delay showing the status bar during dream transition." into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
e0ff509876
@@ -53,6 +53,7 @@ import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
|
|||||||
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
|
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
|
||||||
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
|
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
|
||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder;
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel;
|
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||||
@@ -158,6 +159,7 @@ public abstract class StatusBarViewModule {
|
|||||||
StatusBarIconController statusBarIconController,
|
StatusBarIconController statusBarIconController,
|
||||||
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
|
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
|
||||||
CollapsedStatusBarViewModel collapsedStatusBarViewModel,
|
CollapsedStatusBarViewModel collapsedStatusBarViewModel,
|
||||||
|
CollapsedStatusBarViewBinder collapsedStatusBarViewBinder,
|
||||||
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
|
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
ShadeViewController shadeViewController,
|
ShadeViewController shadeViewController,
|
||||||
@@ -182,6 +184,7 @@ public abstract class StatusBarViewModule {
|
|||||||
statusBarIconController,
|
statusBarIconController,
|
||||||
darkIconManagerFactory,
|
darkIconManagerFactory,
|
||||||
collapsedStatusBarViewModel,
|
collapsedStatusBarViewModel,
|
||||||
|
collapsedStatusBarViewBinder,
|
||||||
statusBarHideIconsForBouncerManager,
|
statusBarHideIconsForBouncerManager,
|
||||||
keyguardStateController,
|
keyguardStateController,
|
||||||
shadeViewController,
|
shadeViewController,
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.phone.fragment;
|
package com.android.systemui.statusbar.phone.fragment;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
|
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.IDLE;
|
||||||
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
|
import static com.android.systemui.statusbar.events.SystemStatusAnimationSchedulerKt.SHOWING_PERSISTENT_DOT;
|
||||||
|
|
||||||
@@ -69,6 +67,7 @@ import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentCom
|
|||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallListener;
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder;
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder;
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener;
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel;
|
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||||
@@ -131,6 +130,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
private final StatusBarIconController mStatusBarIconController;
|
private final StatusBarIconController mStatusBarIconController;
|
||||||
private final CarrierConfigTracker mCarrierConfigTracker;
|
private final CarrierConfigTracker mCarrierConfigTracker;
|
||||||
private final CollapsedStatusBarViewModel mCollapsedStatusBarViewModel;
|
private final CollapsedStatusBarViewModel mCollapsedStatusBarViewModel;
|
||||||
|
private final CollapsedStatusBarViewBinder mCollapsedStatusBarViewBinder;
|
||||||
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
||||||
private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory;
|
private final StatusBarIconController.DarkIconManager.Factory mDarkIconManagerFactory;
|
||||||
private final SecureSettings mSecureSettings;
|
private final SecureSettings mSecureSettings;
|
||||||
@@ -182,12 +182,22 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
*/
|
*/
|
||||||
private boolean mWaitingForWindowStateChangeAfterCameraLaunch = false;
|
private boolean mWaitingForWindowStateChangeAfterCameraLaunch = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* True when a transition from lockscreen to dream has started, but haven't yet received a
|
||||||
|
* status bar window state change afterward.
|
||||||
|
*
|
||||||
|
* Similar to [mWaitingForWindowStateChangeAfterCameraLaunch].
|
||||||
|
*/
|
||||||
|
private boolean mTransitionFromLockscreenToDreamStarted = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listener that updates {@link #mWaitingForWindowStateChangeAfterCameraLaunch} when it receives
|
* Listener that updates {@link #mWaitingForWindowStateChangeAfterCameraLaunch} when it receives
|
||||||
* a new status bar window state.
|
* a new status bar window state.
|
||||||
*/
|
*/
|
||||||
private final StatusBarWindowStateListener mStatusBarWindowStateListener = state ->
|
private final StatusBarWindowStateListener mStatusBarWindowStateListener = state -> {
|
||||||
mWaitingForWindowStateChangeAfterCameraLaunch = false;
|
mWaitingForWindowStateChangeAfterCameraLaunch = false;
|
||||||
|
mTransitionFromLockscreenToDreamStarted = false;
|
||||||
|
};
|
||||||
|
|
||||||
@SuppressLint("ValidFragment")
|
@SuppressLint("ValidFragment")
|
||||||
public CollapsedStatusBarFragment(
|
public CollapsedStatusBarFragment(
|
||||||
@@ -201,6 +211,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
StatusBarIconController statusBarIconController,
|
StatusBarIconController statusBarIconController,
|
||||||
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
|
StatusBarIconController.DarkIconManager.Factory darkIconManagerFactory,
|
||||||
CollapsedStatusBarViewModel collapsedStatusBarViewModel,
|
CollapsedStatusBarViewModel collapsedStatusBarViewModel,
|
||||||
|
CollapsedStatusBarViewBinder collapsedStatusBarViewBinder,
|
||||||
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
|
StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
|
||||||
KeyguardStateController keyguardStateController,
|
KeyguardStateController keyguardStateController,
|
||||||
ShadeViewController shadeViewController,
|
ShadeViewController shadeViewController,
|
||||||
@@ -224,6 +235,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
mFeatureFlags = featureFlags;
|
mFeatureFlags = featureFlags;
|
||||||
mStatusBarIconController = statusBarIconController;
|
mStatusBarIconController = statusBarIconController;
|
||||||
mCollapsedStatusBarViewModel = collapsedStatusBarViewModel;
|
mCollapsedStatusBarViewModel = collapsedStatusBarViewModel;
|
||||||
|
mCollapsedStatusBarViewBinder = collapsedStatusBarViewBinder;
|
||||||
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
|
mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
|
||||||
mDarkIconManagerFactory = darkIconManagerFactory;
|
mDarkIconManagerFactory = darkIconManagerFactory;
|
||||||
mKeyguardStateController = keyguardStateController;
|
mKeyguardStateController = keyguardStateController;
|
||||||
@@ -296,8 +308,8 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
mCarrierConfigTracker.addCallback(mCarrierConfigCallback);
|
mCarrierConfigTracker.addCallback(mCarrierConfigCallback);
|
||||||
mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
|
mCarrierConfigTracker.addDefaultDataSubscriptionChangedListener(mDefaultDataListener);
|
||||||
|
|
||||||
CollapsedStatusBarViewBinder.bind(
|
mCollapsedStatusBarViewBinder.bind(
|
||||||
mStatusBar, mCollapsedStatusBarViewModel, this::updateStatusBarVisibilities);
|
mStatusBar, mCollapsedStatusBarViewModel, mStatusBarVisibilityChangeListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -411,6 +423,19 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
return mStatusBarFragmentComponent;
|
return mStatusBarFragmentComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StatusBarVisibilityChangeListener mStatusBarVisibilityChangeListener =
|
||||||
|
new StatusBarVisibilityChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onStatusBarVisibilityMaybeChanged() {
|
||||||
|
updateStatusBarVisibilities(/* animate= */ true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionFromLockscreenToDreamStarted() {
|
||||||
|
mTransitionFromLockscreenToDreamStarted = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disable(int displayId, int state1, int state2, boolean animate) {
|
public void disable(int displayId, int state1, int state2, boolean animate) {
|
||||||
if (displayId != getContext().getDisplayId()) {
|
if (displayId != getContext().getDisplayId()) {
|
||||||
@@ -423,10 +448,6 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
updateStatusBarVisibilities(animate);
|
updateStatusBarVisibilities(animate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStatusBarVisibilities() {
|
|
||||||
updateStatusBarVisibilities(/* animate= */ true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateStatusBarVisibilities(boolean animate) {
|
private void updateStatusBarVisibilities(boolean animate) {
|
||||||
StatusBarVisibilityModel previousModel = mLastModifiedVisibility;
|
StatusBarVisibilityModel previousModel = mLastModifiedVisibility;
|
||||||
StatusBarVisibilityModel newModel = calculateInternalModel(mLastSystemVisibility);
|
StatusBarVisibilityModel newModel = calculateInternalModel(mLastSystemVisibility);
|
||||||
@@ -546,6 +567,18 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Similar to [hideIconsForSecureCamera]: When dream is launched over lockscreen, the icons
|
||||||
|
// are momentarily visible because the dream animation has finished, but SysUI has not been
|
||||||
|
// informed that the dream is full-screen. For extra safety, we double-check that we're
|
||||||
|
// still dreaming.
|
||||||
|
final boolean hideIconsForDream =
|
||||||
|
mTransitionFromLockscreenToDreamStarted
|
||||||
|
&& mKeyguardUpdateMonitor.isDreaming()
|
||||||
|
&& mKeyguardStateController.isOccluded();
|
||||||
|
if (hideIconsForDream) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// While the status bar is transitioning from lockscreen to an occluded, we don't yet know
|
// While the status bar is transitioning from lockscreen to an occluded, we don't yet know
|
||||||
// if the occluding activity is fullscreen or not. If it *is* fullscreen, we don't want to
|
// if the occluding activity is fullscreen or not. If it *is* fullscreen, we don't want to
|
||||||
// briefly show the status bar just to immediately hide it again. So, we wait for the
|
// briefly show the status bar just to immediately hide it again. So, we wait for the
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerPr
|
|||||||
import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxyImpl
|
import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxyImpl
|
||||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
|
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
|
||||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
|
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinderImpl
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
|
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher
|
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher
|
||||||
@@ -107,6 +109,11 @@ abstract class StatusBarPipelineModule {
|
|||||||
impl: CollapsedStatusBarViewModelImpl
|
impl: CollapsedStatusBarViewModelImpl
|
||||||
): CollapsedStatusBarViewModel
|
): CollapsedStatusBarViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
abstract fun collapsedStatusBarViewBinder(
|
||||||
|
impl: CollapsedStatusBarViewBinderImpl
|
||||||
|
): CollapsedStatusBarViewBinder
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Provides
|
@Provides
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
|
|||||||
@@ -19,34 +19,61 @@ package com.android.systemui.statusbar.pipeline.shared.ui.binder
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel
|
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
object CollapsedStatusBarViewBinder {
|
/**
|
||||||
|
* Interface to assist with binding the [CollapsedStatusBarFragment] to
|
||||||
|
* [CollapsedStatusBarViewModel]. Used only to enable easy testing of [CollapsedStatusBarFragment].
|
||||||
|
*/
|
||||||
|
interface CollapsedStatusBarViewBinder {
|
||||||
/**
|
/**
|
||||||
* Binds the view to the view-model. [listener] will be notified whenever an event that may
|
* Binds the view to the view-model. [listener] will be notified whenever an event that may
|
||||||
* change the status bar visibility occurs.
|
* change the status bar visibility occurs.
|
||||||
*/
|
*/
|
||||||
@JvmStatic
|
|
||||||
fun bind(
|
fun bind(
|
||||||
view: View,
|
view: View,
|
||||||
viewModel: CollapsedStatusBarViewModel,
|
viewModel: CollapsedStatusBarViewModel,
|
||||||
listener: StatusBarVisibilityChangeListener,
|
listener: StatusBarVisibilityChangeListener,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SysUISingleton
|
||||||
|
class CollapsedStatusBarViewBinderImpl @Inject constructor() : CollapsedStatusBarViewBinder {
|
||||||
|
override fun bind(
|
||||||
|
view: View,
|
||||||
|
viewModel: CollapsedStatusBarViewModel,
|
||||||
|
listener: StatusBarVisibilityChangeListener,
|
||||||
) {
|
) {
|
||||||
view.repeatWhenAttached {
|
view.repeatWhenAttached {
|
||||||
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
repeatOnLifecycle(Lifecycle.State.CREATED) {
|
||||||
|
launch {
|
||||||
viewModel.isTransitioningFromLockscreenToOccluded.collect {
|
viewModel.isTransitioningFromLockscreenToOccluded.collect {
|
||||||
listener.onStatusBarVisibilityMaybeChanged()
|
listener.onStatusBarVisibilityMaybeChanged()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
launch {
|
||||||
|
viewModel.transitionFromLockscreenToDreamStartedEvent.collect {
|
||||||
|
listener.onTransitionFromLockscreenToDreamStarted()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Listener for various events that may affect the status bar's visibility. */
|
||||||
|
interface StatusBarVisibilityChangeListener {
|
||||||
/**
|
/**
|
||||||
* Listener to be notified when the status bar visibility might have changed due to the device
|
* Called when the status bar visibility might have changed due to the device moving to a
|
||||||
* moving to a different state.
|
* different state.
|
||||||
*/
|
*/
|
||||||
fun interface StatusBarVisibilityChangeListener {
|
|
||||||
fun onStatusBarVisibilityMaybeChanged()
|
fun onStatusBarVisibilityMaybeChanged()
|
||||||
|
|
||||||
|
/** Called when a transition from lockscreen to dream has started. */
|
||||||
|
fun onTransitionFromLockscreenToDreamStarted()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,10 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac
|
|||||||
import com.android.systemui.keyguard.shared.model.TransitionState
|
import com.android.systemui.keyguard.shared.model.TransitionState
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.SharingStarted
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
@@ -43,6 +45,9 @@ interface CollapsedStatusBarViewModel {
|
|||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean>
|
val isTransitioningFromLockscreenToOccluded: StateFlow<Boolean>
|
||||||
|
|
||||||
|
/** Emits whenever a transition from lockscreen to dream has started. */
|
||||||
|
val transitionFromLockscreenToDreamStartedEvent: Flow<Unit>
|
||||||
}
|
}
|
||||||
|
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@@ -59,4 +64,9 @@ constructor(
|
|||||||
it.transitionState == TransitionState.RUNNING
|
it.transitionState == TransitionState.RUNNING
|
||||||
}
|
}
|
||||||
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
|
.stateIn(coroutineScope, SharingStarted.WhileSubscribed(), initialValue = false)
|
||||||
|
|
||||||
|
override val transitionFromLockscreenToDreamStartedEvent: Flow<Unit> =
|
||||||
|
keyguardTransitionInteractor.lockscreenToDreamingTransition
|
||||||
|
.filter { it.transitionState == TransitionState.STARTED }
|
||||||
|
.map {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ import com.android.systemui.statusbar.phone.StatusBarIconController;
|
|||||||
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
|
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
|
||||||
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
|
import com.android.systemui.statusbar.phone.fragment.dagger.StatusBarFragmentComponent;
|
||||||
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeCollapsedStatusBarViewBinder;
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeCollapsedStatusBarViewModel;
|
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.FakeCollapsedStatusBarViewModel;
|
||||||
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
import com.android.systemui.statusbar.policy.KeyguardStateController;
|
||||||
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
|
||||||
@@ -129,6 +130,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
@Mock
|
@Mock
|
||||||
private StatusBarIconController.DarkIconManager mIconManager;
|
private StatusBarIconController.DarkIconManager mIconManager;
|
||||||
private FakeCollapsedStatusBarViewModel mCollapsedStatusBarViewModel;
|
private FakeCollapsedStatusBarViewModel mCollapsedStatusBarViewModel;
|
||||||
|
private FakeCollapsedStatusBarViewBinder mCollapsedStatusBarViewBinder;
|
||||||
@Mock
|
@Mock
|
||||||
private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
|
||||||
@Mock
|
@Mock
|
||||||
@@ -612,6 +614,55 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStatusBarIcons_hiddenThroughoutLockscreenToDreamTransition() {
|
||||||
|
final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
||||||
|
|
||||||
|
// WHEN a transition to dream has started
|
||||||
|
mCollapsedStatusBarViewBinder.getListener().onTransitionFromLockscreenToDreamStarted();
|
||||||
|
when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(true);
|
||||||
|
when(mKeyguardStateController.isOccluded()).thenReturn(true);
|
||||||
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
|
// THEN status icons should be invisible or gone, but certainly not VISIBLE.
|
||||||
|
assertNotEquals(View.VISIBLE, getEndSideContentView().getVisibility());
|
||||||
|
assertNotEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
|
|
||||||
|
// WHEN the transition has finished and dream is displaying
|
||||||
|
mockLockscreenToDreamTransitionFinished();
|
||||||
|
// (This approximates "dream is displaying")
|
||||||
|
when(mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer())
|
||||||
|
.thenReturn(true);
|
||||||
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
|
// THEN the views still aren't visible because dream is hiding them
|
||||||
|
assertNotEquals(View.VISIBLE, getEndSideContentView().getVisibility());
|
||||||
|
assertNotEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
|
|
||||||
|
// WHEN dream has ended
|
||||||
|
when(mStatusBarHideIconsForBouncerManager.getShouldHideStatusBarIconsForBouncer())
|
||||||
|
.thenReturn(false);
|
||||||
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
|
// THEN the views can be visible again
|
||||||
|
assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
|
||||||
|
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testStatusBarIcons_lockscreenToDreamTransitionButNotDreaming_iconsVisible() {
|
||||||
|
final CollapsedStatusBarFragment fragment = resumeAndGetFragment();
|
||||||
|
|
||||||
|
// WHEN a transition to dream has started but we're *not* dreaming
|
||||||
|
mCollapsedStatusBarViewBinder.getListener().onTransitionFromLockscreenToDreamStarted();
|
||||||
|
when(mKeyguardUpdateMonitor.isDreaming()).thenReturn(false);
|
||||||
|
fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
|
||||||
|
|
||||||
|
// THEN the views are still visible
|
||||||
|
assertEquals(View.VISIBLE, getEndSideContentView().getVisibility());
|
||||||
|
assertEquals(View.VISIBLE, getClockView().getVisibility());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Fragment instantiate(Context context, String className, Bundle arguments) {
|
protected Fragment instantiate(Context context, String className, Bundle arguments) {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
@@ -631,6 +682,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
|
|
||||||
mShadeExpansionStateManager = new ShadeExpansionStateManager();
|
mShadeExpansionStateManager = new ShadeExpansionStateManager();
|
||||||
mCollapsedStatusBarViewModel = new FakeCollapsedStatusBarViewModel();
|
mCollapsedStatusBarViewModel = new FakeCollapsedStatusBarViewModel();
|
||||||
|
mCollapsedStatusBarViewBinder = new FakeCollapsedStatusBarViewBinder();
|
||||||
|
|
||||||
setUpNotificationIconAreaController();
|
setUpNotificationIconAreaController();
|
||||||
return new CollapsedStatusBarFragment(
|
return new CollapsedStatusBarFragment(
|
||||||
@@ -644,6 +696,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
mStatusBarIconController,
|
mStatusBarIconController,
|
||||||
mIconManagerFactory,
|
mIconManagerFactory,
|
||||||
mCollapsedStatusBarViewModel,
|
mCollapsedStatusBarViewModel,
|
||||||
|
mCollapsedStatusBarViewBinder,
|
||||||
mStatusBarHideIconsForBouncerManager,
|
mStatusBarHideIconsForBouncerManager,
|
||||||
mKeyguardStateController,
|
mKeyguardStateController,
|
||||||
mShadeViewController,
|
mShadeViewController,
|
||||||
@@ -718,6 +771,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mockLockscreenToDreamTransitionFinished() {
|
||||||
|
for (StatusBarWindowStateListener listener : mStatusBarWindowStateListeners) {
|
||||||
|
listener.onStatusBarWindowStateChanged(StatusBarManager.WINDOW_STATE_HIDDEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private CollapsedStatusBarFragment resumeAndGetFragment() {
|
private CollapsedStatusBarFragment resumeAndGetFragment() {
|
||||||
mFragments.dispatchResume();
|
mFragments.dispatchResume();
|
||||||
processAllMessages();
|
processAllMessages();
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.coroutines.collectValues
|
||||||
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository
|
||||||
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
|
||||||
import com.android.systemui.keyguard.shared.model.KeyguardState
|
import com.android.systemui.keyguard.shared.model.KeyguardState
|
||||||
@@ -176,4 +177,139 @@ class CollapsedStatusBarViewModelImplTest : SysuiTestCase() {
|
|||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun transitionFromLockscreenToDreamStartedEvent_started_emitted() =
|
||||||
|
testScope.runTest {
|
||||||
|
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(emissions.size).isEqualTo(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun transitionFromLockscreenToDreamStartedEvent_startedMultiple_emittedMultiple() =
|
||||||
|
testScope.runTest {
|
||||||
|
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(emissions.size).isEqualTo(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun transitionFromLockscreenToDreamStartedEvent_startedThenRunning_emittedOnlyOne() =
|
||||||
|
testScope.runTest {
|
||||||
|
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
assertThat(emissions.size).isEqualTo(1)
|
||||||
|
|
||||||
|
// WHEN the transition progresses through its animation by going through the RUNNING
|
||||||
|
// step with increasing fractions
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = .1f,
|
||||||
|
TransitionState.RUNNING,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = .2f,
|
||||||
|
TransitionState.RUNNING,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = .3f,
|
||||||
|
TransitionState.RUNNING,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
// THEN the flow does not emit since the flow should only emit when the transition
|
||||||
|
// starts
|
||||||
|
assertThat(emissions.size).isEqualTo(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun transitionFromLockscreenToDreamStartedEvent_irrelevantTransition_notEmitted() =
|
||||||
|
testScope.runTest {
|
||||||
|
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.OCCLUDED,
|
||||||
|
value = 0f,
|
||||||
|
TransitionState.STARTED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(emissions).isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun transitionFromLockscreenToDreamStartedEvent_irrelevantTransitionState_notEmitted() =
|
||||||
|
testScope.runTest {
|
||||||
|
val emissions by collectValues(underTest.transitionFromLockscreenToDreamStartedEvent)
|
||||||
|
|
||||||
|
keyguardTransitionRepository.sendTransitionStep(
|
||||||
|
TransitionStep(
|
||||||
|
KeyguardState.LOCKSCREEN,
|
||||||
|
KeyguardState.DREAMING,
|
||||||
|
value = 1.0f,
|
||||||
|
TransitionState.FINISHED,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(emissions).isEmpty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.statusbar.pipeline.shared.ui.viewmodel
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.CollapsedStatusBarViewBinder
|
||||||
|
import com.android.systemui.statusbar.pipeline.shared.ui.binder.StatusBarVisibilityChangeListener
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fake view binder that can be used from Java tests.
|
||||||
|
*
|
||||||
|
* Since Java tests can't run tests within test scopes, we need to bypass the flows from
|
||||||
|
* [CollapsedStatusBarViewModel] and just trigger the listener directly.
|
||||||
|
*/
|
||||||
|
class FakeCollapsedStatusBarViewBinder : CollapsedStatusBarViewBinder {
|
||||||
|
var listener: StatusBarVisibilityChangeListener? = null
|
||||||
|
|
||||||
|
override fun bind(
|
||||||
|
view: View,
|
||||||
|
viewModel: CollapsedStatusBarViewModel,
|
||||||
|
listener: StatusBarVisibilityChangeListener,
|
||||||
|
) {
|
||||||
|
this.listener = listener
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
|
package com.android.systemui.statusbar.pipeline.shared.ui.viewmodel
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
class FakeCollapsedStatusBarViewModel : CollapsedStatusBarViewModel {
|
class FakeCollapsedStatusBarViewModel : CollapsedStatusBarViewModel {
|
||||||
override val isTransitioningFromLockscreenToOccluded = MutableStateFlow(false)
|
override val isTransitioningFromLockscreenToOccluded = MutableStateFlow(false)
|
||||||
|
|
||||||
|
override val transitionFromLockscreenToDreamStartedEvent = MutableSharedFlow<Unit>()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user