|  | /* | 
|  | * Copyright (C) 2020 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 android.view; | 
|  |  | 
|  | import android.annotation.NonNull; | 
|  | import android.graphics.Point; | 
|  | import android.graphics.Rect; | 
|  |  | 
|  | import java.util.function.Supplier; | 
|  |  | 
|  | /** | 
|  | * Metrics about a Window, consisting of the bounds and {@link WindowInsets}. | 
|  | * <p> | 
|  | * This is usually obtained from {@link WindowManager#getCurrentWindowMetrics()} and | 
|  | * {@link WindowManager#getMaximumWindowMetrics()}. | 
|  | * </p> | 
|  | * After {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, it also provides density. | 
|  | * <h3>Obtains Window Dimensions in Density-independent Pixel(DP)</h3> | 
|  | * <p> | 
|  | * While {@link #getDensity()} is provided, the dimension in density-independent pixel could also be | 
|  | * calculated with {@code WindowMetrics} properties, which is similar to | 
|  | * {@link android.content.res.Configuration#screenWidthDp} | 
|  | * <pre class="prettyprint"> | 
|  | * float widthInDp = windowMetrics.getBounds().width() / windowMetrics.getDensity(); | 
|  | * float heightInDp = windowMetrics.getBounds().height() / windowMetrics.getDensity(); | 
|  | * </pre> | 
|  | * Also, the density in DPI can be obtained by: | 
|  | * <pre class="prettyprint"> | 
|  | * float densityDp = DisplayMetrics.DENSITY_DEFAULT * windowMetrics.getDensity(); | 
|  | * </pre> | 
|  | * </p> | 
|  | * | 
|  | * @see WindowInsets#getInsets(int) | 
|  | * @see WindowManager#getCurrentWindowMetrics() | 
|  | * @see WindowManager#getMaximumWindowMetrics() | 
|  | */ | 
|  | public final class WindowMetrics { | 
|  | @NonNull | 
|  | private final Rect mBounds; | 
|  |  | 
|  | private WindowInsets mWindowInsets; | 
|  | private Supplier<WindowInsets> mWindowInsetsSupplier; | 
|  |  | 
|  | /** @see android.util.DisplayMetrics#density */ | 
|  | private final float mDensity; | 
|  |  | 
|  | /** @deprecated use {@link #WindowMetrics(Rect, WindowInsets, float)} instead. */ | 
|  | @Deprecated | 
|  | public WindowMetrics(@NonNull Rect bounds, @NonNull WindowInsets windowInsets) { | 
|  | this(bounds, windowInsets, 1.0f); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * The constructor to create a {@link WindowMetrics} instance. | 
|  | * <p> | 
|  | * Note that in most cases {@link WindowMetrics} is obtained from | 
|  | * {@link WindowManager#getCurrentWindowMetrics()} or | 
|  | * {@link WindowManager#getMaximumWindowMetrics()}. | 
|  | * </p> | 
|  | * | 
|  | * @param bounds The window bounds | 
|  | * @param windowInsets The {@link WindowInsets} of the window | 
|  | * @param density The window density | 
|  | */ | 
|  | public WindowMetrics(@NonNull Rect bounds, @NonNull WindowInsets windowInsets, float density) { | 
|  | mBounds = bounds; | 
|  | mWindowInsets = windowInsets; | 
|  | mDensity = density; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Similar to {@link #WindowMetrics(Rect, WindowInsets, float)} but the window insets are | 
|  | * computed when {@link #getWindowInsets()} is first time called. This reduces unnecessary | 
|  | * calculation and the overhead of obtaining insets state from server side because most | 
|  | * callers are usually only interested in {@link #getBounds()}. | 
|  | * | 
|  | * @hide | 
|  | */ | 
|  | public WindowMetrics(@NonNull Rect bounds, @NonNull Supplier<WindowInsets> windowInsetsSupplier, | 
|  | float density) { | 
|  | mBounds = bounds; | 
|  | mWindowInsetsSupplier = windowInsetsSupplier; | 
|  | mDensity = density; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the bounds of the area associated with this window or {@code UiContext}. | 
|  | * <p> | 
|  | * <b>Note that the size of the reported bounds can have different size than | 
|  | * {@link Display#getSize(Point)}.</b> This method reports the window size including all system | 
|  | * bar areas, while {@link Display#getSize(Point)} reports the area excluding navigation bars | 
|  | * and display cutout areas. The value reported by {@link Display#getSize(Point)} can be | 
|  | * obtained by using: | 
|  | * <pre class="prettyprint"> | 
|  | * final WindowMetrics metrics = windowManager.getCurrentWindowMetrics(); | 
|  | * // Gets all excluding insets | 
|  | * final WindowInsets windowInsets = metrics.getWindowInsets(); | 
|  | * Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars() | 
|  | *         | WindowInsets.Type.displayCutout()); | 
|  | * | 
|  | * int insetsWidth = insets.right + insets.left; | 
|  | * int insetsHeight = insets.top + insets.bottom; | 
|  | * | 
|  | * // Legacy size that Display#getSize reports | 
|  | * final Rect bounds = metrics.getBounds(); | 
|  | * final Size legacySize = new Size(bounds.width() - insetsWidth, | 
|  | *         bounds.height() - insetsHeight); | 
|  | * </pre> | 
|  | * </p> | 
|  | * | 
|  | * @return window bounds in pixels. | 
|  | */ | 
|  | @NonNull | 
|  | public Rect getBounds() { | 
|  | return mBounds; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the {@link WindowInsets} of the area associated with this window or | 
|  | * {@code UiContext}. | 
|  | * | 
|  | * @return the {@link WindowInsets} of the visual area. | 
|  | */ | 
|  | @NonNull | 
|  | public WindowInsets getWindowInsets() { | 
|  | if (mWindowInsets != null) { | 
|  | return mWindowInsets; | 
|  | } | 
|  | return mWindowInsets = mWindowInsetsSupplier.get(); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * Returns the density of the area associated with this window or {@code UiContext}, | 
|  | * which uses the same units as {@link android.util.DisplayMetrics#density}. | 
|  | * | 
|  | * @see android.util.DisplayMetrics#DENSITY_DEFAULT | 
|  | * @see android.util.DisplayMetrics#density | 
|  | */ | 
|  | public float getDensity() { | 
|  | return mDensity; | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public String toString() { | 
|  | return WindowMetrics.class.getSimpleName() + ":{" | 
|  | + "bounds=" + mBounds | 
|  | + ", windowInsets=" + mWindowInsets | 
|  | + ", density=" + mDensity | 
|  | + "}"; | 
|  | } | 
|  | } |