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

Commit 07cc5b73 authored by Tiger's avatar Tiger Committed by Tiger Huang
Browse files

Let light bar state be able to be read by insets API

Before this CL, if the light bar state is controlled by the window style
attribute, apps can only query it via View#getSystemUiVisibility.
However, the API has been deprecated since Android SDK 30.
WindowInsetsController#getSystemBarsAppearance could only return the
values set by WindowInsetsController#setSystemBarsAppearance. Thus, no
API (except the deprecated one), can return the light bar state.

This CL adds a new @hide method, setSystemBarsAppearanceFromResource.
The light bar state read from resource will be passed to that method.
And now getSystemBarsAppearance will also return the appearance flag
specified via setSystemBarsAppearanceFromResource if the same flag is
not controlled by setSystemBarsAppearance.

Fix: 330891999
Flag: NA
Test: atest PendingInsetsControllerTest ViewRootImplTest
Test: ThemeSystemBarsTest
Change-Id: If740d360ad3211b682bd04598099240863048960
parent 69a62d57
Loading
Loading
Loading
Loading
+25 −17
Original line number Diff line number Diff line
@@ -140,10 +140,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
         */
        @Appearance int getSystemBarsAppearance();

        default boolean isSystemBarsAppearanceControlled() {
            return false;
        }

        /**
         * @see WindowInsetsController#setSystemBarsBehavior
         */
@@ -154,10 +150,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
         */
        @Behavior int getSystemBarsBehavior();

        default boolean isSystemBarsBehaviorControlled() {
            return false;
        }

        /**
         * Releases a surface and ensure that this is done after {@link #applySurfaceParams} has
         * finished applying params.
@@ -670,6 +662,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
    private int mImeCaptionBarInsetsHeight = 0;
    private boolean mAnimationsDisabled;
    private boolean mCompatSysUiVisibilityStaled;
    private @Appearance int mAppearanceControlled;
    private @Appearance int mAppearanceFromResource;
    private boolean mBehaviorControlled;

    private final Runnable mPendingControlTimeout = this::abortPendingImeControlRequest;
    private final ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners
@@ -1875,20 +1870,28 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

    @Override
    public void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask) {
        mAppearanceControlled |= mask;
        mHost.setSystemBarsAppearance(appearance, mask);
    }

    @Override
    public @Appearance int getSystemBarsAppearance() {
        @Appearance int appearance = mHost.getSystemBarsAppearance();
    public void setSystemBarsAppearanceFromResource(@Appearance int appearance,
            @Appearance int mask) {
        mAppearanceFromResource = (mAppearanceFromResource & ~mask) | (appearance & mask);

        // Don't change the flags which are already controlled by setSystemBarsAppearance.
        mHost.setSystemBarsAppearance(appearance, mask & ~mAppearanceControlled);
    }

    @Override
    public @Appearance int getSystemBarsAppearance() {
        // We only return the requested appearance, not the implied one.
        appearance &= ~APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS;
        if (!mHost.isSystemBarsAppearanceControlled()) {
            appearance &= ~COMPATIBLE_APPEARANCE_FLAGS;
        return (mHost.getSystemBarsAppearance() & mAppearanceControlled)
                | (mAppearanceFromResource & ~mAppearanceControlled);
    }

        return appearance;
    public @Appearance int getAppearanceControlled() {
        return mAppearanceControlled;
    }

    @Override
@@ -1940,18 +1943,23 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation

    @Override
    public void setSystemBarsBehavior(@Behavior int behavior) {
        mBehaviorControlled = true;
        mHost.setSystemBarsBehavior(behavior);
    }

    @Override
    public @Behavior int getSystemBarsBehavior() {
        if (!mHost.isSystemBarsBehaviorControlled()) {
        if (!mBehaviorControlled) {
            // We only return the requested behavior, not the implied one.
            return 0;
            return BEHAVIOR_DEFAULT;
        }
        return mHost.getSystemBarsBehavior();
    }

    public boolean isBehaviorControlled() {
        return mBehaviorControlled;
    }

    @Override
    public void setAnimationsDisabled(boolean disable) {
        mAnimationsDisabled = disable;
+19 −1
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ public class PendingInsetsController implements WindowInsetsController {
    private final ArrayList<PendingRequest> mRequests = new ArrayList<>();
    private @Appearance int mAppearance;
    private @Appearance int mAppearanceMask;
    private @Appearance int mAppearanceFromResource;
    private @Appearance int mAppearanceFromResourceMask;
    private @Behavior int mBehavior = KEEP_BEHAVIOR;
    private boolean mAnimationsDisabled;
    private final InsetsState mDummyState = new InsetsState();
@@ -78,12 +80,22 @@ public class PendingInsetsController implements WindowInsetsController {
        }
    }

    @Override
    public void setSystemBarsAppearanceFromResource(int appearance, int mask) {
        if (mReplayedInsetsController != null) {
            mReplayedInsetsController.setSystemBarsAppearanceFromResource(appearance, mask);
        } else {
            mAppearanceFromResource = (mAppearanceFromResource & ~mask) | (appearance & mask);
            mAppearanceFromResourceMask |= mask;
        }
    }

    @Override
    public int getSystemBarsAppearance() {
        if (mReplayedInsetsController != null) {
            return mReplayedInsetsController.getSystemBarsAppearance();
        }
        return mAppearance;
        return mAppearance | (mAppearanceFromResource & ~mAppearanceMask);
    }

    @Override
@@ -171,6 +183,10 @@ public class PendingInsetsController implements WindowInsetsController {
        if (mAppearanceMask != 0) {
            controller.setSystemBarsAppearance(mAppearance, mAppearanceMask);
        }
        if (mAppearanceFromResourceMask != 0) {
            controller.setSystemBarsAppearanceFromResource(
                    mAppearanceFromResource, mAppearanceFromResourceMask);
        }
        if (mCaptionInsetsHeight != 0) {
            controller.setCaptionInsetsHeight(mCaptionInsetsHeight);
        }
@@ -199,6 +215,8 @@ public class PendingInsetsController implements WindowInsetsController {
        mBehavior = KEEP_BEHAVIOR;
        mAppearance = 0;
        mAppearanceMask = 0;
        mAppearanceFromResource = 0;
        mAppearanceFromResourceMask = 0;
        mAnimationsDisabled = false;
        mLoggingListener = null;
        mRequestedVisibleTypes = WindowInsets.Type.defaultVisible();
+31 −23
Original line number Diff line number Diff line
@@ -34,13 +34,13 @@ import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
import static android.view.Surface.FRAME_RATE_COMPATIBILITY_GTE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_UNKNOWN;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_IDLE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_INVALID;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_LARGE;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_REQUESTED;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_SMALL;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_UNKNOWN;
import static android.view.View.FRAME_RATE_CATEGORY_REASON_VELOCITY;
import static android.view.View.PFLAG_DRAW_ANIMATION;
import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN;
@@ -69,11 +69,10 @@ import static android.view.ViewRootImplProto.WIDTH;
import static android.view.ViewRootImplProto.WINDOW_ATTRIBUTES;
import static android.view.ViewRootImplProto.WIN_FRAME;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
import static android.view.WindowInsetsController.COMPATIBLE_APPEARANCE_FLAGS;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
import static android.view.WindowInsetsController.Appearance;
import static android.view.WindowInsetsController.BEHAVIOR_DEFAULT;
import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
import static android.view.WindowLayout.UNSPECIFIED_LENGTH;
@@ -85,8 +84,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
@@ -107,6 +104,7 @@ import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
import static android.view.accessibility.Flags.fixMergedContentChangeEvent;
import static android.view.accessibility.Flags.forceInvertColor;
import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
@@ -1517,7 +1515,9 @@ public final class ViewRootImpl implements ViewParent,
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                    adjustLayoutParamsForCompatibility(mWindowAttributes);
                    adjustLayoutParamsForCompatibility(mWindowAttributes,
                            mInsetsController.getAppearanceControlled(),
                            mInsetsController.isBehaviorControlled());
                    controlInsetsForCompatibility(mWindowAttributes);
                    Rect attachedFrame = new Rect();
@@ -2033,8 +2033,6 @@ public final class ViewRootImpl implements ViewParent,
            // Preserve appearance and behavior.
            final int appearance = mWindowAttributes.insetsFlags.appearance;
            final int behavior = mWindowAttributes.insetsFlags.behavior;
            final int appearanceAndBehaviorPrivateFlags = mWindowAttributes.privateFlags
                    & (PRIVATE_FLAG_APPEARANCE_CONTROLLED | PRIVATE_FLAG_BEHAVIOR_CONTROLLED);
            final int changes = mWindowAttributes.copyFrom(attrs);
            if ((changes & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
@@ -2057,7 +2055,6 @@ public final class ViewRootImpl implements ViewParent,
            mWindowAttributes.subtreeSystemUiVisibility = subtreeSystemUiVisibility;
            mWindowAttributes.insetsFlags.appearance = appearance;
            mWindowAttributes.insetsFlags.behavior = behavior;
            mWindowAttributes.privateFlags |= appearanceAndBehaviorPrivateFlags;
            if (mWindowAttributes.preservePreviousSurfaceInsets) {
                // Restore old surface insets.
@@ -2911,26 +2908,35 @@ public final class ViewRootImpl implements ViewParent,
    }
    @VisibleForTesting
    public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams) {
    public static void adjustLayoutParamsForCompatibility(WindowManager.LayoutParams inOutParams,
            @Appearance int appearanceControlled, boolean behaviorControlled) {
        final int sysUiVis = inOutParams.systemUiVisibility | inOutParams.subtreeSystemUiVisibility;
        final int flags = inOutParams.flags;
        final int type = inOutParams.type;
        final int adjust = inOutParams.softInputMode & SOFT_INPUT_MASK_ADJUST;
        if ((inOutParams.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) == 0) {
            inOutParams.insetsFlags.appearance &= ~COMPATIBLE_APPEARANCE_FLAGS;
            if ((sysUiVis & SYSTEM_UI_FLAG_LOW_PROFILE) != 0) {
                inOutParams.insetsFlags.appearance |= APPEARANCE_LOW_PROFILE_BARS;
            }
            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0) {
                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_STATUS_BARS;
        @Appearance int appearance = inOutParams.insetsFlags.appearance;
        if ((appearanceControlled & APPEARANCE_LOW_PROFILE_BARS) == 0) {
            appearance &= ~APPEARANCE_LOW_PROFILE_BARS;
            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LOW_PROFILE) != 0
                    ? APPEARANCE_LOW_PROFILE_BARS
                    : 0;
        }
            if ((sysUiVis & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0) {
                inOutParams.insetsFlags.appearance |= APPEARANCE_LIGHT_NAVIGATION_BARS;
        if ((appearanceControlled & APPEARANCE_LIGHT_STATUS_BARS) == 0) {
            appearance &= ~APPEARANCE_LIGHT_STATUS_BARS;
            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0
                    ? APPEARANCE_LIGHT_STATUS_BARS
                    : 0;
        }
        if ((appearanceControlled & APPEARANCE_LIGHT_NAVIGATION_BARS) == 0) {
            appearance &= ~APPEARANCE_LIGHT_NAVIGATION_BARS;
            appearance |= (sysUiVis & SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR) != 0
                    ? APPEARANCE_LIGHT_NAVIGATION_BARS
                    : 0;
        }
        inOutParams.insetsFlags.appearance = appearance;
        if ((inOutParams.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) == 0) {
        if (!behaviorControlled) {
            if ((sysUiVis & SYSTEM_UI_FLAG_IMMERSIVE_STICKY) != 0
                    || (flags & FLAG_FULLSCREEN) != 0) {
                inOutParams.insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
@@ -3480,7 +3486,9 @@ public final class ViewRootImpl implements ViewParent,
                    && !PixelFormat.formatHasAlpha(params.format)) {
                params.format = PixelFormat.TRANSLUCENT;
            }
            adjustLayoutParamsForCompatibility(params);
            adjustLayoutParamsForCompatibility(params,
                    mInsetsController.getAppearanceControlled(),
                    mInsetsController.isBehaviorControlled());
            controlInsetsForCompatibility(params);
            if (mDispatchedSystemBarAppearance != params.insetsFlags.appearance) {
                mDispatchedSystemBarAppearance = params.insetsFlags.appearance;
+0 −17
Original line number Diff line number Diff line
@@ -17,9 +17,6 @@
package android.view;

import static android.view.InsetsController.DEBUG;
import static android.view.WindowInsetsController.COMPATIBLE_APPEARANCE_FLAGS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_APPEARANCE_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_BEHAVIOR_CONTROLLED;

import android.annotation.NonNull;
import android.content.Context;
@@ -174,9 +171,6 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {

    @Override
    public void setSystemBarsAppearance(int appearance, int mask) {
        if ((mask & COMPATIBLE_APPEARANCE_FLAGS) != 0) {
            mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_APPEARANCE_CONTROLLED;
        }
        final InsetsFlags insetsFlags = mViewRoot.mWindowAttributes.insetsFlags;
        final int newAppearance = (insetsFlags.appearance & ~mask) | (appearance & mask);
        if (insetsFlags.appearance != newAppearance) {
@@ -191,14 +185,8 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
        return mViewRoot.mWindowAttributes.insetsFlags.appearance;
    }

    @Override
    public boolean isSystemBarsAppearanceControlled() {
        return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_APPEARANCE_CONTROLLED) != 0;
    }

    @Override
    public void setSystemBarsBehavior(int behavior) {
        mViewRoot.mWindowAttributes.privateFlags |= PRIVATE_FLAG_BEHAVIOR_CONTROLLED;
        if (mViewRoot.mWindowAttributes.insetsFlags.behavior != behavior) {
            mViewRoot.mWindowAttributes.insetsFlags.behavior = behavior;
            mViewRoot.mWindowAttributesChanged = true;
@@ -211,11 +199,6 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host {
        return mViewRoot.mWindowAttributes.insetsFlags.behavior;
    }

    @Override
    public boolean isSystemBarsBehaviorControlled() {
        return (mViewRoot.mWindowAttributes.privateFlags & PRIVATE_FLAG_BEHAVIOR_CONTROLLED) != 0;
    }

    @Override
    public void releaseSurfaceControlFromRt(SurfaceControl surfaceControl) {

+13 −8
Original line number Diff line number Diff line
@@ -100,14 +100,6 @@ public interface WindowInsetsController {
     */
    int APPEARANCE_FORCE_LIGHT_NAVIGATION_BARS = 1 << 9;

    /**
     * Appearance flags that can be implied from system UI flags.
     * @hide
     */
    int COMPATIBLE_APPEARANCE_FLAGS = APPEARANCE_LOW_PROFILE_BARS
            | APPEARANCE_LIGHT_STATUS_BARS
            | APPEARANCE_LIGHT_NAVIGATION_BARS;

    /**
     * Determines the appearance of system bars.
     * @hide
@@ -270,11 +262,24 @@ public interface WindowInsetsController {
     */
    void setSystemBarsAppearance(@Appearance int appearance, @Appearance int mask);

    /**
     * Similar to {@link #setSystemBarsAppearance} but the given flag will only take effect when it
     * is not controlled by {@link #setSystemBarsAppearance}.
     *
     * @see WindowInsetsController#getSystemBarsAppearance()
     * @see android.R.attr#windowLightStatusBar
     * @see android.R.attr#windowLightNavigationBar
     * @hide
     */
    void setSystemBarsAppearanceFromResource(@Appearance int appearance, @Appearance int mask);

    /**
     * Retrieves the requested appearance of system bars.
     *
     * @return The requested bitmask of system bar appearance controlled by this window.
     * @see #setSystemBarsAppearance(int, int)
     * @see android.R.attr#windowLightStatusBar
     * @see android.R.attr#windowLightNavigationBar
     */
    @Appearance int getSystemBarsAppearance();

Loading