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

Commit 997fb312 authored by Christian Go??llner's avatar Christian Go??llner
Browse files

Start using LetterboxAppearanceCalculator in SysUI

Start using LetterboxAppearanceCalculator in
CentralSurfacesCommandQueueCallbacks, to override the status bar
appearance when apps are letterboxed.

+ Flag guarded for now
+ Also refactors all the logic that was in onSysBarAttrsChanged into its
  own class, to avoid having much logic and state in the
  CentralSurfacesCommandQueueCallbacks class

Test: CentralSurfacesCommandQueueCallbacksTest.java
Test: SystemBarAttributesListenerTest.kt
Test: Manually
Bug: 238741157
Change-Id: I31e0fa200b5da7d46a82712f5b69c4d874de72f8
parent 4c08e927
Loading
Loading
Loading
Loading
+16 −21
Original line number Diff line number Diff line
@@ -57,10 +57,8 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.qs.QSPanelController;
import com.android.systemui.shade.NotificationPanelView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
@@ -91,19 +89,16 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
    private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    private final AssistManager mAssistManager;
    private final DozeServiceHost mDozeServiceHost;
    private final SysuiStatusBarStateController mStatusBarStateController;
    private final NotificationShadeWindowView mNotificationShadeWindowView;
    private final NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
    private final StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
    private final PowerManager mPowerManager;
    private final VibratorHelper mVibratorHelper;
    private final Optional<Vibrator> mVibratorOptional;
    private final LightBarController mLightBarController;
    private final DisableFlagsLogger mDisableFlagsLogger;
    private final int mDisplayId;
    private final boolean mVibrateOnOpening;
    private final VibrationEffect mCameraLaunchGestureVibrationEffect;

    private final SystemBarAttributesListener mSystemBarAttributesListener;

    private static final VibrationAttributes HARDWARE_FEEDBACK_VIBRATION_ATTRIBUTES =
            VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK);
@@ -126,16 +121,14 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
            StatusBarKeyguardViewManager statusBarKeyguardViewManager,
            AssistManager assistManager,
            DozeServiceHost dozeServiceHost,
            SysuiStatusBarStateController statusBarStateController,
            NotificationShadeWindowView notificationShadeWindowView,
            NotificationStackScrollLayoutController notificationStackScrollLayoutController,
            StatusBarHideIconsForBouncerManager statusBarHideIconsForBouncerManager,
            PowerManager powerManager,
            VibratorHelper vibratorHelper,
            Optional<Vibrator> vibratorOptional,
            LightBarController lightBarController,
            DisableFlagsLogger disableFlagsLogger,
            @DisplayId int displayId) {
            @DisplayId int displayId,
            SystemBarAttributesListener systemBarAttributesListener) {

        mCentralSurfaces = centralSurfaces;
        mContext = context;
@@ -152,20 +145,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
        mStatusBarKeyguardViewManager = statusBarKeyguardViewManager;
        mAssistManager = assistManager;
        mDozeServiceHost = dozeServiceHost;
        mStatusBarStateController = statusBarStateController;
        mNotificationShadeWindowView = notificationShadeWindowView;
        mNotificationStackScrollLayoutController = notificationStackScrollLayoutController;
        mStatusBarHideIconsForBouncerManager = statusBarHideIconsForBouncerManager;
        mPowerManager = powerManager;
        mVibratorHelper = vibratorHelper;
        mVibratorOptional = vibratorOptional;
        mLightBarController = lightBarController;
        mDisableFlagsLogger = disableFlagsLogger;
        mDisplayId = displayId;

        mVibrateOnOpening = resources.getBoolean(R.bool.config_vibrateOnIconAnimation);
        mCameraLaunchGestureVibrationEffect = getCameraGestureVibrationEffect(
                mVibratorOptional, resources);
        mSystemBarAttributesListener = systemBarAttributesListener;
    }

    @Override
@@ -472,14 +463,18 @@ public class CentralSurfacesCommandQueueCallbacks implements CommandQueue.Callba
        if (displayId != mDisplayId) {
            return;
        }
        boolean barModeChanged = mCentralSurfaces.setAppearance(appearance);

        mLightBarController.onStatusBarAppearanceChanged(appearanceRegions, barModeChanged,
                mCentralSurfaces.getBarMode(), navbarColorManagedByIme);

        mCentralSurfaces.updateBubblesVisibility();
        mStatusBarStateController.setSystemBarAttributes(
                appearance, behavior, requestedVisibilities, packageName);
        // SystemBarAttributesListener should __always__ be the top-level listener for system bar
        // attributes changed.
        mSystemBarAttributesListener.onSystemBarAttributesChanged(
                displayId,
                appearance,
                appearanceRegions,
                navbarColorManagedByIme,
                behavior,
                requestedVisibilities,
                packageName,
                letterboxDetails
        );
    }

    @Override
+158 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.phone

import android.view.InsetsVisibilities
import android.view.WindowInsetsController.Appearance
import android.view.WindowInsetsController.Behavior
import com.android.internal.statusbar.LetterboxDetails
import com.android.internal.view.AppearanceRegion
import com.android.systemui.dump.DumpManager
import com.android.systemui.flags.FeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent.CentralSurfacesScope
import java.io.PrintWriter
import javax.inject.Inject

/**
 * Top-level listener of system attributes changed. This class is __always the first__ one to be
 * notified about changes.
 *
 * It is responsible for modifying any attributes if necessary, and then notifying the other
 * downstream listeners.
 */
@CentralSurfacesScope
class SystemBarAttributesListener
@Inject
internal constructor(
    private val centralSurfaces: CentralSurfaces,
    private val featureFlags: FeatureFlags,
    private val letterboxAppearanceCalculator: LetterboxAppearanceCalculator,
    private val statusBarStateController: SysuiStatusBarStateController,
    private val lightBarController: LightBarController,
    private val dumpManager: DumpManager,
) : CentralSurfacesComponent.Startable, StatusBarBoundsProvider.BoundsChangeListener {

    private var lastLetterboxAppearance: LetterboxAppearance? = null
    private var lastSystemBarAttributesParams: SystemBarAttributesParams? = null

    override fun start() {
        dumpManager.registerDumpable(javaClass.simpleName, this::dump)
    }

    override fun stop() {
        dumpManager.unregisterDumpable(javaClass.simpleName)
    }

    override fun onStatusBarBoundsChanged() {
        val params = lastSystemBarAttributesParams
        if (params != null && shouldUseLetterboxAppearance(params.letterboxesArray)) {
            onSystemBarAttributesChanged(
                params.displayId,
                params.appearance,
                params.appearanceRegionsArray,
                params.navbarColorManagedByIme,
                params.behavior,
                params.requestedVisibilities,
                params.packageName,
                params.letterboxesArray)
        }
    }

    fun onSystemBarAttributesChanged(
        displayId: Int,
        @Appearance originalAppearance: Int,
        originalAppearanceRegions: Array<AppearanceRegion>,
        navbarColorManagedByIme: Boolean,
        @Behavior behavior: Int,
        requestedVisibilities: InsetsVisibilities,
        packageName: String,
        letterboxDetails: Array<LetterboxDetails>
    ) {
        lastSystemBarAttributesParams =
            SystemBarAttributesParams(
                displayId,
                originalAppearance,
                originalAppearanceRegions.toList(),
                navbarColorManagedByIme,
                behavior,
                requestedVisibilities,
                packageName,
                letterboxDetails.toList())

        val (appearance, appearanceRegions) =
            modifyAppearanceIfNeeded(
                originalAppearance, originalAppearanceRegions, letterboxDetails)

        val barModeChanged = centralSurfaces.setAppearance(appearance)

        lightBarController.onStatusBarAppearanceChanged(
            appearanceRegions, barModeChanged, centralSurfaces.barMode, navbarColorManagedByIme)

        centralSurfaces.updateBubblesVisibility()
        statusBarStateController.setSystemBarAttributes(
            appearance, behavior, requestedVisibilities, packageName)
    }

    private fun modifyAppearanceIfNeeded(
        appearance: Int,
        appearanceRegions: Array<AppearanceRegion>,
        letterboxDetails: Array<LetterboxDetails>
    ): Pair<Int, Array<AppearanceRegion>> =
        if (shouldUseLetterboxAppearance(letterboxDetails)) {
            val letterboxAppearance =
                letterboxAppearanceCalculator.getLetterboxAppearance(
                    appearance, appearanceRegions, letterboxDetails)
            lastLetterboxAppearance = letterboxAppearance
            Pair(letterboxAppearance.appearance, letterboxAppearance.appearanceRegions)
        } else {
            lastLetterboxAppearance = null
            Pair(appearance, appearanceRegions)
        }

    private fun shouldUseLetterboxAppearance(letterboxDetails: Array<LetterboxDetails>) =
        isLetterboxAppearanceFlagEnabled() && letterboxDetails.isNotEmpty()

    private fun isLetterboxAppearanceFlagEnabled() =
        featureFlags.isEnabled(Flags.STATUS_BAR_LETTERBOX_APPEARANCE)

    private fun dump(printWriter: PrintWriter, strings: Array<String>) {
        printWriter.println("lastSystemBarAttributesParams: $lastSystemBarAttributesParams")
        printWriter.println("lastLetterboxAppearance: $lastLetterboxAppearance")
        printWriter.println("letterbox appearance flag: ${isLetterboxAppearanceFlagEnabled()}")
    }
}

/**
 * Keeps track of the parameters passed in
 * [SystemBarAttributesListener.onSystemBarAttributesChanged].
 */
private data class SystemBarAttributesParams(
    val displayId: Int,
    @Appearance val appearance: Int,
    val appearanceRegions: List<AppearanceRegion>,
    val navbarColorManagedByIme: Boolean,
    @Behavior val behavior: Int,
    val requestedVisibilities: InsetsVisibilities,
    val packageName: String,
    val letterboxes: List<LetterboxDetails>,
) {
    val letterboxesArray = letterboxes.toTypedArray()
    val appearanceRegionsArray = appearanceRegions.toTypedArray()
}
+6 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone.dagger;

import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
import com.android.systemui.statusbar.phone.SystemBarAttributesListener;

import java.util.Set;

@@ -34,4 +35,9 @@ interface CentralSurfacesStartableModule {
    @IntoSet
    CentralSurfacesComponent.Startable letterboxAppearanceCalculator(
            LetterboxAppearanceCalculator letterboxAppearanceCalculator);

    @Binds
    @IntoSet
    CentralSurfacesComponent.Startable sysBarAttrsListener(
            SystemBarAttributesListener systemBarAttributesListener);
}
+7 −0
Original line number Diff line number Diff line
@@ -53,10 +53,12 @@ import com.android.systemui.statusbar.notification.stack.NotificationStackScroll
import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
import com.android.systemui.statusbar.phone.LetterboxAppearanceCalculator;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.StatusBarBoundsProvider;
import com.android.systemui.statusbar.phone.StatusBarHideIconsForBouncerManager;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.StatusIconContainer;
import com.android.systemui.statusbar.phone.SystemBarAttributesListener;
import com.android.systemui.statusbar.phone.TapAgainView;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.fragment.CollapsedStatusBarFragmentLogger;
@@ -258,6 +260,11 @@ public abstract class StatusBarViewModule {
            LetterboxAppearanceCalculator letterboxAppearanceCalculator
    );

    @Binds
    @IntoSet
    abstract StatusBarBoundsProvider.BoundsChangeListener sysBarAttrsListenerAsBoundsListener(
            SystemBarAttributesListener systemBarAttributesListener);

    /**
     * Creates a new {@link CollapsedStatusBarFragment}.
     *
+62 −9
Original line number Diff line number Diff line
@@ -22,26 +22,28 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.app.StatusBarManager;
import android.os.PowerManager;
import android.os.Vibrator;
import android.testing.AndroidTestingRunner;
import android.view.InsetsVisibilities;

import androidx.test.filters.SmallTest;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.internal.statusbar.LetterboxDetails;
import com.android.internal.view.AppearanceRegion;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.NotificationShadeWindowView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DisableFlagsLogger;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -60,6 +62,7 @@ import java.util.Optional;
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {

    @Mock private CentralSurfaces mCentralSurfaces;
    @Mock private ShadeController mShadeController;
    @Mock private CommandQueue mCommandQueue;
@@ -74,14 +77,12 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
    @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
    @Mock private AssistManager mAssistManager;
    @Mock private DozeServiceHost mDozeServiceHost;
    @Mock private StatusBarStateControllerImpl mStatusBarStateController;
    @Mock private NotificationShadeWindowView mNotificationShadeWindowView;
    @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
    @Mock private PowerManager mPowerManager;
    @Mock private VibratorHelper mVibratorHelper;
    @Mock private Vibrator mVibrator;
    @Mock private LightBarController mLightBarController;
    @Mock private StatusBarHideIconsForBouncerManager mStatusBarHideIconsForBouncerManager;
    @Mock private SystemBarAttributesListener mSystemBarAttributesListener;

    CentralSurfacesCommandQueueCallbacks mSbcqCallbacks;

@@ -106,16 +107,14 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
                mStatusBarKeyguardViewManager,
                mAssistManager,
                mDozeServiceHost,
                mStatusBarStateController,
                mNotificationShadeWindowView,
                mNotificationStackScrollLayoutController,
                mStatusBarHideIconsForBouncerManager,
                mPowerManager,
                mVibratorHelper,
                Optional.of(mVibrator),
                mLightBarController,
                new DisableFlagsLogger(),
                DEFAULT_DISPLAY);
                DEFAULT_DISPLAY,
                mSystemBarAttributesListener);

        when(mDeviceProvisionedController.isCurrentUserSetup()).thenReturn(true);
        when(mRemoteInputQuickSettingsDisabler.adjustDisableFlags(anyInt()))
@@ -170,5 +169,59 @@ public class CentralSurfacesCommandQueueCallbacksTest extends SysuiTestCase {
        verify(mDozeServiceHost).setAlwaysOnSuppressed(false);
    }

    @Test
    public void onSystemBarAttributesChanged_forwardsToSysBarAttrsListener() {
        int displayId = DEFAULT_DISPLAY;
        int appearance = 123;
        AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
        boolean navbarColorManagedByIme = true;
        int behavior = 456;
        InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
        String packageName = "test package name";
        LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};

        mSbcqCallbacks.onSystemBarAttributesChanged(
                displayId,
                appearance,
                appearanceRegions,
                navbarColorManagedByIme,
                behavior,
                requestedVisibilities,
                packageName,
                letterboxDetails);

        verify(mSystemBarAttributesListener).onSystemBarAttributesChanged(
                displayId,
                appearance,
                appearanceRegions,
                navbarColorManagedByIme,
                behavior,
                requestedVisibilities,
                packageName,
                letterboxDetails
        );
    }

    @Test
    public void onSystemBarAttributesChanged_differentDisplayId_doesNotForwardToAttrsListener() {
        int appearance = 123;
        AppearanceRegion[] appearanceRegions = new AppearanceRegion[]{};
        boolean navbarColorManagedByIme = true;
        int behavior = 456;
        InsetsVisibilities requestedVisibilities = new InsetsVisibilities();
        String packageName = "test package name";
        LetterboxDetails[] letterboxDetails = new LetterboxDetails[]{};

        mSbcqCallbacks.onSystemBarAttributesChanged(
                DEFAULT_DISPLAY + 1,
                appearance,
                appearanceRegions,
                navbarColorManagedByIme,
                behavior,
                requestedVisibilities,
                packageName,
                letterboxDetails);

        verifyZeroInteractions(mSystemBarAttributesListener);
    }
}
Loading