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

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

[CS] 1/4: Add WindowRootViewVisibilityInteractor visibility flows

Bug: 296050180
Test: manual: Verify CentralSurfaces & the new interactor always receive
the same visible values. Namely, true on lockscreen, AOD, or when the
shade is open (locked *or* unlocked), false otherwise (particularly,
false when on bouncer, false when device goes to sleep).
Test: atest ShadeControllerImplTest
WindowRootViewVisibilityInteractorTest
WindowRootViewVisibilityRepositoryTest

Change-Id: I4679118ca61ffdd68469863fe4665910de427051
parent 6cac1114
Loading
Loading
Loading
Loading
+34 −0
Original line number Original line 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.scene.data.repository

import com.android.systemui.dagger.SysUISingleton
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow

/** Source of truth for the visibility of various parts of the window root view. */
@SysUISingleton
class WindowRootViewVisibilityRepository @Inject constructor() {
    private val _isLockscreenOrShadeVisible = MutableStateFlow(false)
    val isLockscreenOrShadeVisible: StateFlow<Boolean> = _isLockscreenOrShadeVisible.asStateFlow()

    fun setIsLockscreenOrShadeVisible(visible: Boolean) {
        _isLockscreenOrShadeVisible.value = visible
    }
}
+66 −0
Original line number Original line 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.scene.domain.interactor

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.KeyguardRepository
import com.android.systemui.scene.data.repository.WindowRootViewVisibilityRepository
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

/** Business logic about the visibility of various parts of the window root view. */
@SysUISingleton
class WindowRootViewVisibilityInteractor
@Inject
constructor(
    @Application scope: CoroutineScope,
    private val windowRootViewVisibilityRepository: WindowRootViewVisibilityRepository,
    keyguardRepository: KeyguardRepository,
) {

    /**
     * True if lockscreen (including AOD) or the shade is visible and false otherwise. Notably,
     * false if the bouncer is visible.
     *
     * TODO(b/297080059): Use [SceneInteractor] as the source of truth if the scene flag is on.
     */
    val isLockscreenOrShadeVisible: StateFlow<Boolean> =
        windowRootViewVisibilityRepository.isLockscreenOrShadeVisible

    /**
     * True if lockscreen (including AOD) or the shade is visible **and** the user is currently
     * interacting with the device, false otherwise. Notably, false if the bouncer is visible and
     * false if the device is asleep.
     */
    val isLockscreenOrShadeVisibleAndInteractive: StateFlow<Boolean> =
        combine(
                isLockscreenOrShadeVisible,
                keyguardRepository.wakefulness,
            ) { isKeyguardAodOrShadeVisible, wakefulness ->
                isKeyguardAodOrShadeVisible && wakefulness.isDeviceInteractive()
            }
            .stateIn(scope, SharingStarted.Eagerly, initialValue = false)

    fun setIsLockscreenOrShadeVisible(visible: Boolean) {
        windowRootViewVisibilityRepository.setIsLockscreenOrShadeVisible(visible)
    }
}
+16 −0
Original line number Original line 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.scene.ui.view
package com.android.systemui.scene.ui.view


import android.annotation.SuppressLint
import android.annotation.SuppressLint
+5 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.LogBuffer;
import com.android.systemui.log.dagger.ShadeTouchLog;
import com.android.systemui.log.dagger.ShadeTouchLog;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.scene.domain.interactor.WindowRootViewVisibilityInteractor;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationShadeWindowController;
import com.android.systemui.statusbar.NotificationShadeWindowController;
@@ -59,6 +60,7 @@ public final class ShadeControllerImpl implements ShadeController {
    private final CommandQueue mCommandQueue;
    private final CommandQueue mCommandQueue;
    private final Executor mMainExecutor;
    private final Executor mMainExecutor;
    private final LogBuffer mTouchLog;
    private final LogBuffer mTouchLog;
    private final WindowRootViewVisibilityInteractor mWindowRootViewVisibilityInteractor;
    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardStateController mKeyguardStateController;
    private final NotificationShadeWindowController mNotificationShadeWindowController;
    private final NotificationShadeWindowController mNotificationShadeWindowController;
    private final StatusBarStateController mStatusBarStateController;
    private final StatusBarStateController mStatusBarStateController;
@@ -83,6 +85,7 @@ public final class ShadeControllerImpl implements ShadeController {
            CommandQueue commandQueue,
            CommandQueue commandQueue,
            @Main Executor mainExecutor,
            @Main Executor mainExecutor,
            @ShadeTouchLog LogBuffer touchLog,
            @ShadeTouchLog LogBuffer touchLog,
            WindowRootViewVisibilityInteractor windowRootViewVisibilityInteractor,
            KeyguardStateController keyguardStateController,
            KeyguardStateController keyguardStateController,
            StatusBarStateController statusBarStateController,
            StatusBarStateController statusBarStateController,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
@@ -97,6 +100,7 @@ public final class ShadeControllerImpl implements ShadeController {
        mCommandQueue = commandQueue;
        mCommandQueue = commandQueue;
        mMainExecutor = mainExecutor;
        mMainExecutor = mainExecutor;
        mTouchLog = touchLog;
        mTouchLog = touchLog;
        mWindowRootViewVisibilityInteractor = windowRootViewVisibilityInteractor;
        mShadeViewControllerLazy = shadeViewControllerLazy;
        mShadeViewControllerLazy = shadeViewControllerLazy;
        mStatusBarStateController = statusBarStateController;
        mStatusBarStateController = statusBarStateController;
        mStatusBarWindowController = statusBarWindowController;
        mStatusBarWindowController = statusBarWindowController;
@@ -391,6 +395,7 @@ public final class ShadeControllerImpl implements ShadeController {


    private void notifyVisibilityChanged(boolean visible) {
    private void notifyVisibilityChanged(boolean visible) {
        mShadeVisibilityListener.visibilityChanged(visible);
        mShadeVisibilityListener.visibilityChanged(visible);
        mWindowRootViewVisibilityInteractor.setIsLockscreenOrShadeVisible(visible);
    }
    }


    private void notifyExpandedVisibleChanged(boolean expandedVisible) {
    private void notifyExpandedVisibleChanged(boolean expandedVisible) {
+8 −1
Original line number Original line Diff line number Diff line
@@ -1171,7 +1171,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
                new FoldStateListener(mContext, this::onFoldedStateChanged));
                new FoldStateListener(mContext, this::onFoldedStateChanged));
    }
    }


    @VisibleForTesting
    /**
     * @deprecated use {@link
     * WindowRootViewVisibilityInteractor.isLockscreenOrShadeVisible} instead.
     */    @VisibleForTesting
    void initShadeVisibilityListener() {
    void initShadeVisibilityListener() {
        mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() {
        mShadeController.setVisibilityListener(new ShadeController.ShadeVisibilityListener() {
            @Override
            @Override
@@ -3337,6 +3340,10 @@ public class CentralSurfacesImpl implements CoreStartable, CentralSurfaces {
        updateVisibleToUser();
        updateVisibleToUser();
    }
    }


    /**
     * @deprecated use {@link
     * WindowRootViewVisibilityInteractor.isLockscreenOrShadeVisibleAndInteractive} instead.
     */
    protected void updateVisibleToUser() {
    protected void updateVisibleToUser() {
        boolean oldVisibleToUser = mVisibleToUser;
        boolean oldVisibleToUser = mVisibleToUser;
        mVisibleToUser = mVisible && mDeviceInteractive;
        mVisibleToUser = mVisible && mDeviceInteractive;
Loading