Don't extend alert windows onto status bar/nav bar.

This requires preserving information about the status bar/nav bar insets
and using it to reduce the available space when measuring wrap_content
windows.

Also remove the hack that was introduced for round devices and should be
handled instead by the round qualifier and theming.

Bug: 26014496

Change-Id: I5688c50153047dcabc197adab8fec141630a2b51
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 36009dc..1a20e5c 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -205,6 +205,9 @@
     private float mAvailableWidth;
 
     String mLogTag = TAG;
+    private final Rect mFloatingInsets = new Rect();
+    private boolean mApplyFloatingVerticalInsets = false;
+    private boolean mApplyFloatingHorizontalInsets = false;
 
     DecorView(Context context, int featureId, PhoneWindow window,
             WindowManager.LayoutParams params) {
@@ -567,6 +570,7 @@
         final int heightMode = getMode(heightMeasureSpec);
 
         boolean fixedWidth = false;
+        mApplyFloatingHorizontalInsets = false;
         if (widthMode == AT_MOST) {
             final TypedValue tvw = isPortrait ? mWindow.mFixedWidthMinor : mWindow.mFixedWidthMajor;
             if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
@@ -584,10 +588,16 @@
                     widthMeasureSpec = MeasureSpec.makeMeasureSpec(
                             Math.min(w, widthSize), EXACTLY);
                     fixedWidth = true;
+                } else {
+                    widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            widthMeasureSpec - mFloatingInsets.left - mFloatingInsets.right,
+                            AT_MOST);
+                    mApplyFloatingHorizontalInsets = true;
                 }
             }
         }
 
+        mApplyFloatingVerticalInsets = false;
         if (heightMode == AT_MOST) {
             final TypedValue tvh = isPortrait ? mWindow.mFixedHeightMajor
                     : mWindow.mFixedHeightMinor;
@@ -601,10 +611,14 @@
                     h = 0;
                 }
                 if (DEBUG_MEASURE) Log.d(mLogTag, "Fixed height: " + h);
+                final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
                 if (h > 0) {
-                    final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
                     heightMeasureSpec = MeasureSpec.makeMeasureSpec(
                             Math.min(h, heightSize), EXACTLY);
+                } else if ((mWindow.getAttributes().flags & FLAG_FULLSCREEN) == 0) {
+                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            heightSize - mFloatingInsets.top - mFloatingInsets.bottom, AT_MOST);
+                    mApplyFloatingVerticalInsets = true;
                 }
             }
         }
@@ -672,6 +686,12 @@
         if (mOutsets.top > 0) {
             offsetTopAndBottom(-mOutsets.top);
         }
+        if (mApplyFloatingVerticalInsets) {
+            offsetTopAndBottom(mFloatingInsets.top);
+        }
+        if (mApplyFloatingHorizontalInsets) {
+            offsetLeftAndRight(mFloatingInsets.left);
+        }
 
         // If the application changed its SystemUI metrics, we might also have to adapt
         // our shadow elevation.
@@ -868,6 +888,25 @@
 
     @Override
     public WindowInsets onApplyWindowInsets(WindowInsets insets) {
+        final WindowManager.LayoutParams attrs = mWindow.getAttributes();
+        mFloatingInsets.setEmpty();
+        if ((attrs.flags & FLAG_FULLSCREEN) == 0) {
+            // For dialog windows we want to make sure they don't go over the status bar or nav bar.
+            // We consume the system insets and we will reuse them later during the measure phase.
+            // We allow the app to ignore this and handle insets itself by using FLAG_FULLSCREEN.
+            if (attrs.height == WindowManager.LayoutParams.WRAP_CONTENT) {
+                mFloatingInsets.top = insets.getSystemWindowInsetTop();
+                mFloatingInsets.bottom = insets.getSystemWindowInsetBottom();
+                insets = insets.replaceSystemWindowInsets(insets.getSystemWindowInsetLeft(), 0,
+                        insets.getSystemWindowInsetRight(), 0);
+            }
+            if (mWindow.getAttributes().width == WindowManager.LayoutParams.WRAP_CONTENT) {
+                mFloatingInsets.left = insets.getSystemWindowInsetTop();
+                mFloatingInsets.right = insets.getSystemWindowInsetBottom();
+                insets = insets.replaceSystemWindowInsets(0, insets.getSystemWindowInsetTop(),
+                        0, insets.getSystemWindowInsetBottom());
+            }
+        }
         mFrameOffsets.set(insets.getSystemWindowInsets());
         insets = updateColorViews(insets, true /* animate */);
         insets = updateStatusGuard(insets);