diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index d3464fde4b75c..d8b1f41c86d5d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -90,6 +90,7 @@ import android.widget.FrameLayout; import android.widget.ImageButton; import android.widget.LinearLayout; import android.widget.TextView; +import android.window.WindowMetricsHelper; import com.android.internal.annotations.GuardedBy; import com.android.internal.inputmethod.IInputContentUriToken; @@ -1438,8 +1439,8 @@ public class InputMethodService extends AbstractInputMethodService { */ public int getMaxWidth() { final WindowManager windowManager = getSystemService(WindowManager.class); - final Rect windowBounds = windowManager.getCurrentWindowMetrics().getBounds(); - return windowBounds.width(); + return WindowMetricsHelper.getBoundsExcludingNavigationBarAndCutout( + windowManager.getCurrentWindowMetrics()).width(); } /** diff --git a/core/java/android/view/WindowMetrics.java b/core/java/android/view/WindowMetrics.java index 86ef87997a07c..d96c5c82fedbd 100644 --- a/core/java/android/view/WindowMetrics.java +++ b/core/java/android/view/WindowMetrics.java @@ -48,22 +48,19 @@ public final class WindowMetrics { * and display cutout areas. The value reported by {@link Display#getSize(Point)} can be * obtained by using: *
- * final WindowMetrics metrics = windowManager.getCurrentMetrics();
+ * final WindowMetrics metrics = windowManager.getCurrentWindowMetrics();
* // Gets all excluding insets
* final WindowInsets windowInsets = metrics.getWindowInsets();
- * Insets insets = windowInsets.getInsets(WindowInsets.Type.navigationBars());
- * final DisplayCutout cutout = windowInsets.getCutout();
- * if (cutout != null) {
- * final Insets cutoutSafeInsets = Insets.of(cutout.getSafeInsetsLeft(), ...);
- * insets = insets.max(insets, cutoutSafeInsets);
- * }
+ * Insets insets = windowInsets.getInsetsIgnoreVisibility(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 Size legacySize = new Size(metrics.getWidth() - insetsWidth,
- * metrics.getHeight() - insetsHeight);
+ * final Rect bounds = metrics.getBounds();
+ * final Size legacySize = new Size(bounds.width() - insetsWidth,
+ * bounds.height() - insetsHeight);
*
*
*
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index 2ead352fd199c..3161c3c498cfd 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -31,6 +31,7 @@ import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.PopupWindow;
+import android.window.WindowMetricsHelper;
/**
* Custom {@link PopupWindow} used to isolate its content from the autofilled app - the
@@ -128,7 +129,8 @@ public class AutofillPopupWindow extends PopupWindow {
// Gravity.BOTTOM because PopupWindow base class does not expose computeGravity().
final WindowManager windowManager = anchor.getContext()
.getSystemService(WindowManager.class);
- final Rect windowBounds = windowManager.getCurrentWindowMetrics().getBounds();
+ final Rect windowBounds = WindowMetricsHelper.getBoundsExcludingNavigationBarAndCutout(
+ windowManager.getCurrentWindowMetrics());
width = windowBounds.width();
if (height != LayoutParams.MATCH_PARENT) {
offsetY = windowBounds.height() - height;
diff --git a/core/java/android/window/VirtualDisplayTaskEmbedder.java b/core/java/android/window/VirtualDisplayTaskEmbedder.java
index 1c0598b1d2164..7389e9f2a6310 100644
--- a/core/java/android/window/VirtualDisplayTaskEmbedder.java
+++ b/core/java/android/window/VirtualDisplayTaskEmbedder.java
@@ -372,11 +372,7 @@ public class VirtualDisplayTaskEmbedder extends TaskEmbedder {
/** Get density of the hosting display. */
private int getBaseDisplayDensity() {
- if (mTmpDisplayMetrics == null) {
- mTmpDisplayMetrics = new DisplayMetrics();
- }
- mContext.getDisplayNoVerify().getRealMetrics(mTmpDisplayMetrics);
- return mTmpDisplayMetrics.densityDpi;
+ return mContext.getResources().getConfiguration().densityDpi;
}
/**
diff --git a/core/java/android/window/WindowMetricsHelper.java b/core/java/android/window/WindowMetricsHelper.java
new file mode 100644
index 0000000000000..fb8b27e52be13
--- /dev/null
+++ b/core/java/android/window/WindowMetricsHelper.java
@@ -0,0 +1,64 @@
+/*
+ * 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.window;
+
+import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
+import static android.view.WindowInsets.Type.displayCutout;
+import static android.view.WindowInsets.Type.navigationBars;
+
+import android.annotation.NonNull;
+import android.graphics.Insets;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.view.Display;
+import android.view.DisplayCutout;
+import android.view.ViewRootImpl;
+import android.view.WindowInsets;
+import android.view.WindowMetrics;
+
+/**
+ * Helper class to calculate size with {@link android.graphics.Insets} based on provided
+ * {@link WindowMetrics}
+ *
+ * @hide
+ */
+public final class WindowMetricsHelper {
+ private WindowMetricsHelper() {}
+
+ /**
+ * Returns bounds excluding navigation bar and display cutout (but including status bar).
+ * This has the same behavior as {@link Display#getSize(Point)}.
+ */
+ public static Rect getBoundsExcludingNavigationBarAndCutout(
+ @NonNull WindowMetrics windowMetrics) {
+ final WindowInsets windowInsets = windowMetrics.getWindowInsets();
+ Insets insets;
+ if (ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_FULL) {
+ insets = windowInsets.getInsetsIgnoringVisibility(navigationBars() | displayCutout());
+ } else {
+ final Insets stableInsets = windowInsets.getStableInsets();
+ insets = Insets.of(stableInsets.left, 0 /* top */, stableInsets.right,
+ stableInsets.bottom);
+ final DisplayCutout cutout = windowInsets.getDisplayCutout();
+ insets = (cutout != null) ? Insets.max(insets, Insets.of(cutout.getSafeInsets()))
+ : insets;
+ }
+ final Rect result = new Rect(windowMetrics.getBounds());
+ result.inset(insets);
+ return result;
+ }
+}
diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml
index 67a57aaaa101a..5c2841aff1d83 100644
--- a/core/tests/coretests/AndroidManifest.xml
+++ b/core/tests/coretests/AndroidManifest.xml
@@ -1461,7 +1461,10 @@
This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
+public class WindowMetricsHelperTest {
+
+ @Rule
+ public ActivityTestRule