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

Commit 16496cb5 authored by Shawn Lin's avatar Shawn Lin Committed by shawnlin
Browse files

Add APIs to get system bar heights

In multi-display devices, there might be differnt cutout on each display
which also causes different status bar height.

Now we no longer overlay the status_bar_height dimen and keep it as
default value and add APIs to calculate the status bar size.

- Add APIs for getting status_bar_height & quick_qs_offset_height in
  system.
- Add APIs for getting split_shade_header_height and
  qs_header_system_icons_area_height in SystemUI.
- Remove all resource overlay for status_bar_height &
  quick_qs_offset_height.

Bug: 186604541
Test: atest SmallClockPositionTest DisplayLayoutTest
      HideDisplayCutoutOrganizerTest SizeCompatTests
      NotificationPanelViewControllerTest
Change-Id: I5a6dfcc6ff06da8ea0fe119fc9d4c089f13b0dff
parent 8172fc3e
Loading
Loading
Loading
Loading
+94 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2021 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.internal.policy;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Insets;
import android.util.RotationUtils;
import android.view.DisplayCutout;
import android.view.Surface;

import com.android.internal.R;

/**
 * Utility functions for system bars used by both window manager and System UI.
 *
 * @hide
 */
public final class SystemBarUtils {

    /**
     * Gets the status bar height.
     */
    public static int getStatusBarHeight(Context context) {
        return getStatusBarHeight(context.getResources(), context.getDisplay().getCutout());
    }

    /**
     * Gets the status bar height with a specific display cutout.
     */
    public static int getStatusBarHeight(Resources res, DisplayCutout cutout) {
        final int defaultSize = res.getDimensionPixelSize(R.dimen.status_bar_height);
        final int safeInsetTop = cutout == null ? 0 : cutout.getSafeInsetTop();
        final int waterfallInsetTop = cutout == null ? 0 : cutout.getWaterfallInsets().top;
        // The status bar height should be:
        // Max(top cutout size, (status bar default height + waterfall top size))
        return Math.max(safeInsetTop, defaultSize + waterfallInsetTop);
    }

    /**
     * Gets the status bar height for a specific rotation.
     */
    public static int getStatusBarHeightForRotation(
            Context context, @Surface.Rotation int targetRot) {
        final int rotation = context.getDisplay().getRotation();
        final DisplayCutout cutout = context.getDisplay().getCutout();

        Insets insets = cutout == null ? Insets.NONE : Insets.of(cutout.getSafeInsets());
        Insets waterfallInsets = cutout == null ? Insets.NONE : cutout.getWaterfallInsets();
        // rotate insets to target rotation if needed.
        if (rotation != targetRot) {
            if (!insets.equals(Insets.NONE)) {
                insets = RotationUtils.rotateInsets(
                        insets, RotationUtils.deltaRotation(rotation, targetRot));
            }
            if (!waterfallInsets.equals(Insets.NONE)) {
                waterfallInsets = RotationUtils.rotateInsets(
                        waterfallInsets, RotationUtils.deltaRotation(rotation, targetRot));
            }
        }
        final int defaultSize =
                context.getResources().getDimensionPixelSize(R.dimen.status_bar_height);
        // The status bar height should be:
        // Max(top cutout size, (status bar default height + waterfall top size))
        return Math.max(insets.top, defaultSize + waterfallInsets.top);
    }

    /**
     * Gets the height of area above QQS where battery/time go in notification panel. The height
     * equals to status bar height if status bar height is bigger than the
     * {@link R.dimen#quick_qs_offset_height}.
     */
    public static int getQuickQsOffsetHeight(Context context) {
        final int defaultSize = context.getResources().getDimensionPixelSize(
                R.dimen.quick_qs_offset_height);
        final int statusBarHeight = getStatusBarHeight(context);
        // Equals to status bar height if status bar height is bigger.
        return Math.max(defaultSize, statusBarHeight);
    }
}
+0 −2
Original line number Original line Diff line number Diff line
@@ -27,8 +27,6 @@
    <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
    <dimen name="password_keyboard_spacebar_vertical_correction">2dip</dimen>
    <dimen name="preference_widget_width">72dp</dimen>
    <dimen name="preference_widget_width">72dp</dimen>


    <!-- Height of the status bar -->
    <dimen name="status_bar_height">@dimen/status_bar_height_landscape</dimen>
    <!-- Height of area above QQS where battery/time go -->
    <!-- Height of area above QQS where battery/time go -->
    <dimen name="quick_qs_offset_height">48dp</dimen>
    <dimen name="quick_qs_offset_height">48dp</dimen>
    <!-- Default height of an action bar. -->
    <!-- Default height of an action bar. -->
+14 −8
Original line number Original line Diff line number Diff line
@@ -39,15 +39,21 @@
    <!-- Elevation of toast view -->
    <!-- Elevation of toast view -->
    <dimen name="toast_elevation">2dp</dimen>
    <dimen name="toast_elevation">2dp</dimen>


    <!-- Height of the status bar -->
    <!-- Height of the status bar.
    <dimen name="status_bar_height">@dimen/status_bar_height_portrait</dimen>
         Do not read this dimen directly. Use {@link SystemBarUtils#getStatusBarHeight} instead.
    <!-- Height of the status bar in portrait. The height should be
         -->
         Max((status bar content height + waterfall top size), top cutout size) -->
    <dimen name="status_bar_height">24dp</dimen>
    <dimen name="status_bar_height_portrait">24dp</dimen>
    <!-- Height of the status bar in portrait.
    <!-- Height of the status bar in landscape. The height should be
         Do not read this dimen directly. Use {@link SystemBarUtils#getStatusBarHeight} instead.
         Max((status bar content height + waterfall top size), top cutout size) -->
         -->
    <dimen name="status_bar_height_portrait">@dimen/status_bar_height</dimen>
    <!-- Height of the status bar in landscape.
         Do not read this dimen directly. Use {@link SystemBarUtils#getStatusBarHeight} instead.
         -->
    <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen>
    <dimen name="status_bar_height_landscape">@dimen/status_bar_height_portrait</dimen>
    <!-- Height of area above QQS where battery/time go -->
    <!-- Height of area above QQS where battery/time go.
         Do not read this dimen directly. Use {@link SystemBarUtils#getQuickQsOffsetHeight} instead.
         -->
    <dimen name="quick_qs_offset_height">48dp</dimen>
    <dimen name="quick_qs_offset_height">48dp</dimen>
    <!-- Height of the bottom navigation / system bar. -->
    <!-- Height of the bottom navigation / system bar. -->
    <dimen name="navigation_bar_height">48dp</dimen>
    <dimen name="navigation_bar_height">48dp</dimen>
+9 −35
Original line number Original line Diff line number Diff line
@@ -48,9 +48,11 @@ import android.view.Gravity;
import android.view.InsetsSource;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.InsetsState;
import android.view.Surface;
import android.view.Surface;
import android.view.WindowInsets;

import androidx.annotation.VisibleForTesting;


import com.android.internal.R;
import com.android.internal.R;
import com.android.internal.policy.SystemBarUtils;


import java.lang.annotation.Retention;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.RetentionPolicy;
@@ -198,12 +200,13 @@ public class DisplayLayout {
        recalcInsets(res);
        recalcInsets(res);
    }
    }


    private void recalcInsets(Resources res) {
    @VisibleForTesting
    void recalcInsets(Resources res) {
        computeNonDecorInsets(res, mRotation, mWidth, mHeight, mCutout, mInsetsState, mUiMode,
        computeNonDecorInsets(res, mRotation, mWidth, mHeight, mCutout, mInsetsState, mUiMode,
                mNonDecorInsets, mHasNavigationBar);
                mNonDecorInsets, mHasNavigationBar);
        mStableInsets.set(mNonDecorInsets);
        mStableInsets.set(mNonDecorInsets);
        if (mHasStatusBar) {
        if (mHasStatusBar) {
            convertNonDecorInsetsToStableInsets(res, mStableInsets, mWidth, mHeight, mHasStatusBar);
            convertNonDecorInsetsToStableInsets(res, mStableInsets, mCutout, mHasStatusBar);
        }
        }
        mNavBarFrameHeight = getNavigationBarFrameHeight(res, mWidth > mHeight);
        mNavBarFrameHeight = getNavigationBarFrameHeight(res, mWidth > mHeight);
    }
    }
@@ -323,12 +326,12 @@ public class DisplayLayout {
    /**
    /**
     * Calculates the stable insets if we already have the non-decor insets.
     * Calculates the stable insets if we already have the non-decor insets.
     */
     */
    private static void convertNonDecorInsetsToStableInsets(Resources res, Rect inOutInsets,
    private void convertNonDecorInsetsToStableInsets(Resources res, Rect inOutInsets,
            int displayWidth, int displayHeight, boolean hasStatusBar) {
            DisplayCutout cutout, boolean hasStatusBar) {
        if (!hasStatusBar) {
        if (!hasStatusBar) {
            return;
            return;
        }
        }
        int statusBarHeight = getStatusBarHeight(displayWidth > displayHeight, res);
        int statusBarHeight = SystemBarUtils.getStatusBarHeight(res, cutout);
        inOutInsets.top = Math.max(inOutInsets.top, statusBarHeight);
        inOutInsets.top = Math.max(inOutInsets.top, statusBarHeight);
    }
    }


@@ -377,35 +380,6 @@ public class DisplayLayout {
        }
        }
    }
    }


    /**
     * Calculates the stable insets without running a layout.
     *
     * @param displayRotation the current display rotation
     * @param displayWidth the current display width
     * @param displayHeight the current display height
     * @param displayCutout the current display cutout
     * @param outInsets the insets to return
     */
    static void computeStableInsets(Resources res, int displayRotation, int displayWidth,
            int displayHeight, DisplayCutout displayCutout, InsetsState insetsState, int uiMode,
            Rect outInsets, boolean hasNavigationBar, boolean hasStatusBar) {
        outInsets.setEmpty();

        // Navigation bar and status bar.
        computeNonDecorInsets(res, displayRotation, displayWidth, displayHeight, displayCutout,
                insetsState, uiMode, outInsets, hasNavigationBar);
        convertNonDecorInsetsToStableInsets(res, outInsets, displayWidth, displayHeight,
                hasStatusBar);
    }

    /** Retrieve the statusbar height from resources. */
    static int getStatusBarHeight(boolean landscape, Resources res) {
        return landscape ? res.getDimensionPixelSize(
                com.android.internal.R.dimen.status_bar_height_landscape)
                : res.getDimensionPixelSize(
                        com.android.internal.R.dimen.status_bar_height_portrait);
    }

    /** Calculate the DisplayCutout for a particular display size/rotation. */
    /** Calculate the DisplayCutout for a particular display size/rotation. */
    public static DisplayCutout calculateDisplayCutoutForRotation(
    public static DisplayCutout calculateDisplayCutoutForRotation(
            DisplayCutout cutout, int rotation, int displayWidth, int displayHeight) {
            DisplayCutout cutout, int rotation, int displayWidth, int displayHeight) {
+4 −7
Original line number Original line Diff line number Diff line
@@ -39,7 +39,7 @@ import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.annotation.VisibleForTesting;


import com.android.internal.R;
import com.android.internal.policy.SystemBarUtils;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayController;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.ShellExecutor;
@@ -307,12 +307,9 @@ class HideDisplayCutoutOrganizer extends DisplayAreaOrganizer {
        t.apply();
        t.apply();
    }
    }


    private int getStatusBarHeight() {
    @VisibleForTesting
        final boolean isLandscape =
    int getStatusBarHeight() {
                mIsDefaultPortrait ? isDisplaySizeFlipped() : !isDisplaySizeFlipped();
        return SystemBarUtils.getStatusBarHeight(mContext);
        return mContext.getResources().getDimensionPixelSize(
                isLandscape ? R.dimen.status_bar_height_landscape
                        : R.dimen.status_bar_height_portrait);
    }
    }


    void dump(@NonNull PrintWriter pw) {
    void dump(@NonNull PrintWriter pw) {
Loading