Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b784b2f4 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

Revert^2 [SB][Scene] Hide lockscreen status bar while dozing or not keyguard.

This reverts commit 119a159a.

Reason for revert: Un-reverting original ag/24879447 while fixing build error.

Change-Id: I8b08051a94834766fb634935f1df8c4f0473f788
parent 7831be92
Loading
Loading
Loading
Loading
+32 −2
Original line number Diff line number Diff line
@@ -42,13 +42,13 @@ import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.res.R;
import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.log.core.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.shade.ShadeViewStateProvider;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -67,6 +67,8 @@ import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.ui.binder.KeyguardStatusBarViewBinder;
import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.settings.SecureSettings;
@@ -110,6 +112,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardBypassController mKeyguardBypassController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final KeyguardStatusBarViewModel mKeyguardStatusBarViewModel;
    private final BiometricUnlockController mBiometricUnlockController;
    private final SysuiStatusBarStateController mStatusBarStateController;
    private final StatusBarContentInsetsProvider mInsetsProvider;
@@ -283,6 +286,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
            KeyguardStateController keyguardStateController,
            KeyguardBypassController bypassController,
            KeyguardUpdateMonitor keyguardUpdateMonitor,
            KeyguardStatusBarViewModel keyguardStatusBarViewModel,
            BiometricUnlockController biometricUnlockController,
            SysuiStatusBarStateController statusBarStateController,
            StatusBarContentInsetsProvider statusBarContentInsetsProvider,
@@ -309,6 +313,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
        mKeyguardStateController = keyguardStateController;
        mKeyguardBypassController = bypassController;
        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
        mKeyguardStatusBarViewModel = keyguardStatusBarViewModel;
        mBiometricUnlockController = biometricUnlockController;
        mStatusBarStateController = statusBarStateController;
        mInsetsProvider = statusBarContentInsetsProvider;
@@ -356,6 +361,9 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
        super.onInit();
        mCarrierTextController.init();
        mBatteryMeterViewController.init();
        if (isMigrationEnabled()) {
            KeyguardStatusBarViewBinder.bind(mView, mKeyguardStatusBarViewModel);
        }
    }

    @Override
@@ -380,7 +388,7 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
            // whenever the shade is opened on top of lockscreen, and then re-attached when the
            // shade is closed. So, we need to re-add the IconManager each time we're re-attached to
            // get icon updates.
            if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW)) {
            if (isMigrationEnabled()) {
                mStatusBarIconController.addIconGroup(mTintedIconManager);
            }
        }
@@ -455,6 +463,10 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat

    /** Sets the dozing state. */
    public void setDozing(boolean dozing) {
        if (isMigrationEnabled()) {
            // [KeyguardStatusBarViewModel] will automatically handle dozing.
            return;
        }
        mDozing = dozing;
    }

@@ -502,6 +514,10 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
        if (!isKeyguardShowing()) {
            return;
        }
        if (isMigrationEnabled()) {
            // [KeyguardStatusBarViewBinder] will handle view state updates.
            return;
        }

        float alphaQsExpansion = 1 - Math.min(
                1, mShadeViewStateProvider.getLockscreenShadeDragProgress() * 2);
@@ -539,6 +555,11 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
     * Updates the {@link KeyguardStatusBarView} state based on the provided values.
     */
    public void updateViewState(float alpha, int visibility) {
        if (isMigrationEnabled()) {
            // [KeyguardStatusBarViewBinder] will handle view state updates.
            return;
        }

        if (mDisableStateTracker.isDisabled()) {
            visibility = View.INVISIBLE;
        }
@@ -646,10 +667,19 @@ public class KeyguardStatusBarViewController extends ViewController<KeyguardStat
     * @param alpha a value between 0 and 1. -1 if the value is to be reset/ignored.
     */
    public void setAlpha(float alpha) {
        if (isMigrationEnabled()) {
            // [KeyguardStatusBarViewBinder] will handle view state updates.
            return;
        }

        mExplicitAlpha = alpha;
        updateViewState();
    }

    private boolean isMigrationEnabled() {
        return mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW);
    }

    private final ContentObserver mVolumeSettingObserver = new ContentObserver(null) {
        @Override
        public void onChange(boolean selfChange) {
+41 −0
Original line number Diff line number Diff line
/*
 * 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.ui.binder

import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.statusbar.phone.KeyguardStatusBarView
import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel

/** Binds [KeyguardStatusBarViewModel] to [KeyguardStatusBarView]. */
object KeyguardStatusBarViewBinder {
    @JvmStatic
    fun bind(
        view: KeyguardStatusBarView,
        viewModel: KeyguardStatusBarViewModel,
    ) {
        view.repeatWhenAttached {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.isVisible.collect { isVisible ->
                    view.visibility = if (isVisible) View.VISIBLE else View.INVISIBLE
                }
            }
        }
    }
}
+54 −0
Original line number Diff line number Diff line
/*
 * 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.ui.viewmodel

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.StatusBarState
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn

/**
 * A view model for the status bar displayed on keyguard (lockscreen).
 *
 * Note: This view model is for the status bar view as a whole. Certain icons may have their own
 * individual view models, such as
 * [com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel] or
 * [com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel].
 */
@SysUISingleton
class KeyguardStatusBarViewModel
@Inject
constructor(
    @Application scope: CoroutineScope,
    keyguardInteractor: KeyguardInteractor,
) {
    /** True if this view should be visible and false otherwise. */
    val isVisible: StateFlow<Boolean> =
        combine(
                keyguardInteractor.isDozing,
                keyguardInteractor.statusBarState,
            ) { isDozing, statusBarState ->
                !isDozing && statusBarState == StatusBarState.KEYGUARD
            }
            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
}
+122 −1
Original line number Diff line number Diff line
@@ -49,14 +49,22 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.CarrierTextController;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.TestScopeProvider;
import com.android.keyguard.logging.KeyguardLogger;
import com.android.systemui.res.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.battery.BatteryMeterViewController;
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository;
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository;
import com.android.systemui.flags.FakeFeatureFlagsClassic;
import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository;
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.res.R;
import com.android.systemui.scene.SceneTestUtils;
import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags;
import com.android.systemui.shade.ShadeViewStateProvider;
import com.android.systemui.shade.data.repository.FakeShadeRepository;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
@@ -66,6 +74,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.ui.viewmodel.KeyguardStatusBarViewModel;
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel;
import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.settings.SecureSettings;
@@ -79,6 +88,8 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import kotlinx.coroutines.test.TestScope;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -133,16 +144,37 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
    private KeyguardStatusBarView mKeyguardStatusBarView;
    private KeyguardStatusBarViewController mController;
    private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
    private final TestScope mTestScope = TestScopeProvider.getTestScope();
    private final FakeKeyguardRepository mKeyguardRepository = new FakeKeyguardRepository();
    private final SceneTestUtils mSceneTestUtils = new SceneTestUtils(this);
    private KeyguardInteractor mKeyguardInteractor;
    private KeyguardStatusBarViewModel mViewModel;

    @Before
    public void setup() throws Exception {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, false);
        mShadeViewStateProvider = new TestShadeViewStateProvider();
        mShadeViewStateProvider = new TestShadeViewStateProvider();

        MockitoAnnotations.initMocks(this);

        when(mIconManagerFactory.create(any(), any())).thenReturn(mIconManager);

        mKeyguardInteractor = new KeyguardInteractor(
                mKeyguardRepository,
                mCommandQueue,
                mFeatureFlags,
                mSceneTestUtils.getSceneContainerFlags(),
                mSceneTestUtils.getDeviceEntryRepository(),
                new FakeKeyguardBouncerRepository(),
                new FakeConfigurationRepository(),
                new FakeShadeRepository(),
                () -> mSceneTestUtils.sceneInteractor());
        mViewModel =
                new KeyguardStatusBarViewModel(
                        mTestScope.getBackgroundScope(),
                        mKeyguardInteractor);

        allowTestableLooperAsMainThread();
        TestableLooper.get(this).runWithLooper(() -> {
            mKeyguardStatusBarView =
@@ -169,6 +201,7 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
                mKeyguardStateController,
                mKeyguardBypassController,
                mKeyguardUpdateMonitor,
                mViewModel,
                mBiometricUnlockController,
                mStatusBarStateController,
                mStatusBarContentInsetsProvider,
@@ -454,6 +487,94 @@ public class KeyguardStatusBarViewControllerTest extends SysuiTestCase {
        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
    }

    @Test
    public void updateViewState_dozingTrue_flagOff_viewHidden() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, false);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();

        mController.setDozing(true);
        mController.updateViewState();

        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.INVISIBLE);
    }

    @Test
    public void updateViewState_dozingFalse_flagOff_viewShown() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, false);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();

        mController.setDozing(false);
        mController.updateViewState();

        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
    }

    @Test
    public void updateViewState_flagOn_doesNothing() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, true);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();

        mKeyguardStatusBarView.setVisibility(View.GONE);
        mKeyguardStatusBarView.setAlpha(0.456f);

        mController.updateViewState();

        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.GONE);
        assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
    }

    @Test
    public void updateViewStateWithAlphaAndVis_flagOn_doesNothing() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, true);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();

        mKeyguardStatusBarView.setVisibility(View.GONE);
        mKeyguardStatusBarView.setAlpha(0.456f);

        mController.updateViewState(0.789f, View.VISIBLE);

        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.GONE);
        assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
    }

    @Test
    public void setAlpha_flagOn_doesNothing() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, true);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();

        mKeyguardStatusBarView.setAlpha(0.456f);

        mController.setAlpha(0.123f);

        assertThat(mKeyguardStatusBarView.getAlpha()).isEqualTo(0.456f);
    }

    @Test
    public void setDozing_flagOn_doesNothing() {
        mFeatureFlags.set(Flags.MIGRATE_KEYGUARD_STATUS_BAR_VIEW, true);
        mController.init();
        mController.onViewAttached();
        updateStateToKeyguard();
        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);

        mController.setDozing(true);
        mController.updateViewState();

        // setDozing(true) should typically cause the view to hide. But since the flag is on, we
        // should ignore these set dozing calls and stay the same visibility.
        assertThat(mKeyguardStatusBarView.getVisibility()).isEqualTo(View.VISIBLE);
    }

    @Test
    public void setAlpha_explicitAlpha_setsExplicitAlpha() {
        mController.onViewAttached();
+104 −0
Original line number Diff line number Diff line
/*
 * 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.ui.viewmodel

import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.bouncer.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlagsClassic
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.shared.flag.FakeSceneContainerFlags
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
import org.junit.Test

@SmallTest
class KeyguardStatusBarViewModelTest : SysuiTestCase() {
    private val testScope = TestScope()
    private val sceneTestUtils = SceneTestUtils(this)
    private val keyguardRepository = FakeKeyguardRepository()
    private val keyguardInteractor =
        KeyguardInteractor(
            keyguardRepository,
            mock<CommandQueue>(),
            FakeFeatureFlagsClassic(),
            sceneTestUtils.sceneContainerFlags,
            sceneTestUtils.deviceEntryRepository,
            FakeKeyguardBouncerRepository(),
            FakeConfigurationRepository(),
            FakeShadeRepository()
        ) {
            sceneTestUtils.sceneInteractor()
        }

    private val underTest =
        KeyguardStatusBarViewModel(
            testScope.backgroundScope,
            keyguardInteractor,
        )

    @Test
    fun isVisible_dozing_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)
            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)

            keyguardRepository.setIsDozing(true)

            assertThat(latest).isFalse()
        }

    @Test
    fun isVisible_statusBarStateShade_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.SHADE)

            assertThat(latest).isFalse()
        }

    @Test
    fun isVisible_statusBarStateShadeLocked_false() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.SHADE_LOCKED)

            assertThat(latest).isFalse()
        }

    @Test
    fun isVisible_statusBarStateKeyguard_andNotDozing_true() =
        testScope.runTest {
            val latest by collectLastValue(underTest.isVisible)

            keyguardRepository.setStatusBarState(StatusBarState.KEYGUARD)
            keyguardRepository.setIsDozing(false)

            assertThat(latest).isTrue()
        }
}