Merge "Add Configuration data for round displays" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 2cf8969..d8bb56e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -9630,6 +9630,7 @@
     method public boolean equals(android.content.res.Configuration);
     method public int getLayoutDirection();
     method public boolean isLayoutSizeAtLeast(int);
+    method public boolean isScreenRound();
     method public static boolean needNewResources(int, int);
     method public void readFromParcel(android.os.Parcel);
     method public void setLayoutDirection(java.util.Locale);
@@ -9672,6 +9673,10 @@
     field public static final int SCREENLAYOUT_LONG_NO = 16; // 0x10
     field public static final int SCREENLAYOUT_LONG_UNDEFINED = 0; // 0x0
     field public static final int SCREENLAYOUT_LONG_YES = 32; // 0x20
+    field public static final int SCREENLAYOUT_ROUND_MASK = 768; // 0x300
+    field public static final int SCREENLAYOUT_ROUND_NO = 256; // 0x100
+    field public static final int SCREENLAYOUT_ROUND_UNDEFINED = 0; // 0x0
+    field public static final int SCREENLAYOUT_ROUND_YES = 512; // 0x200
     field public static final int SCREENLAYOUT_SIZE_LARGE = 3; // 0x3
     field public static final int SCREENLAYOUT_SIZE_MASK = 15; // 0xf
     field public static final int SCREENLAYOUT_SIZE_NORMAL = 2; // 0x2
@@ -34536,6 +34541,7 @@
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
     field public static final int FLAG_PRESENTATION = 8; // 0x8
     field public static final int FLAG_PRIVATE = 4; // 0x4
+    field public static final int FLAG_ROUND = 16; // 0x10
     field public static final int FLAG_SECURE = 2; // 0x2
     field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
     field public static final int STATE_DOZE = 3; // 0x3
diff --git a/api/system-current.txt b/api/system-current.txt
index 263d17a..cd290ec 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -9940,6 +9940,7 @@
     method public boolean equals(android.content.res.Configuration);
     method public int getLayoutDirection();
     method public boolean isLayoutSizeAtLeast(int);
+    method public boolean isScreenRound();
     method public static boolean needNewResources(int, int);
     method public void readFromParcel(android.os.Parcel);
     method public void setLayoutDirection(java.util.Locale);
@@ -9982,6 +9983,10 @@
     field public static final int SCREENLAYOUT_LONG_NO = 16; // 0x10
     field public static final int SCREENLAYOUT_LONG_UNDEFINED = 0; // 0x0
     field public static final int SCREENLAYOUT_LONG_YES = 32; // 0x20
+    field public static final int SCREENLAYOUT_ROUND_MASK = 768; // 0x300
+    field public static final int SCREENLAYOUT_ROUND_NO = 256; // 0x100
+    field public static final int SCREENLAYOUT_ROUND_UNDEFINED = 0; // 0x0
+    field public static final int SCREENLAYOUT_ROUND_YES = 512; // 0x200
     field public static final int SCREENLAYOUT_SIZE_LARGE = 3; // 0x3
     field public static final int SCREENLAYOUT_SIZE_MASK = 15; // 0xf
     field public static final int SCREENLAYOUT_SIZE_NORMAL = 2; // 0x2
@@ -36798,6 +36803,7 @@
     field public static final int DEFAULT_DISPLAY = 0; // 0x0
     field public static final int FLAG_PRESENTATION = 8; // 0x8
     field public static final int FLAG_PRIVATE = 4; // 0x4
+    field public static final int FLAG_ROUND = 16; // 0x10
     field public static final int FLAG_SECURE = 2; // 0x2
     field public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1; // 0x1
     field public static final int STATE_DOZE = 3; // 0x3
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index bc6d4ce..fd60476 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -156,9 +156,34 @@
      * value indicating that a layout dir has been set to RTL. */
     public static final int SCREENLAYOUT_LAYOUTDIR_RTL = 0x02 << SCREENLAYOUT_LAYOUTDIR_SHIFT;
 
+    /** Constant for {@link #screenLayout}: bits that encode roundness of the screen. */
+    public static final int SCREENLAYOUT_ROUND_MASK = 0x300;
+    /** @hide Constant for {@link #screenLayout}: bit shift to get to screen roundness bits */
+    public static final int SCREENLAYOUT_ROUND_SHIFT = 8;
+    /**
+     * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
+     * that it is unknown whether or not the screen has a round shape.
+     */
+    public static final int SCREENLAYOUT_ROUND_UNDEFINED = 0x00;
+    /**
+     * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
+     * that the screen does not have a rounded shape.
+     */
+    public static final int SCREENLAYOUT_ROUND_NO = 0x1 << SCREENLAYOUT_ROUND_SHIFT;
+    /**
+     * Constant for {@link #screenLayout}: a {@link #SCREENLAYOUT_ROUND_MASK} value indicating
+     * that the screen has a rounded shape. Corners may not be visible to the user;
+     * developers should pay special attention to the {@link android.view.WindowInsets} delivered
+     * to views for more information about ensuring content is not obscured.
+     *
+     * <p>Corresponds to the <code>-round</code> resource qualifier.</p>
+     */
+    public static final int SCREENLAYOUT_ROUND_YES = 0x2 << SCREENLAYOUT_ROUND_SHIFT;
+
     /** Constant for {@link #screenLayout}: a value indicating that screenLayout is undefined */
     public static final int SCREENLAYOUT_UNDEFINED = SCREENLAYOUT_SIZE_UNDEFINED |
-            SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED;
+            SCREENLAYOUT_LONG_UNDEFINED | SCREENLAYOUT_LAYOUTDIR_UNDEFINED |
+            SCREENLAYOUT_ROUND_UNDEFINED;
 
     /**
      * Special flag we generate to indicate that the screen layout requires
@@ -174,18 +199,22 @@
      * <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
      * of the screen.  They may be one of
      * {@link #SCREENLAYOUT_SIZE_SMALL}, {@link #SCREENLAYOUT_SIZE_NORMAL},
-     * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.
+     * {@link #SCREENLAYOUT_SIZE_LARGE}, or {@link #SCREENLAYOUT_SIZE_XLARGE}.</p>
      * 
      * <p>The {@link #SCREENLAYOUT_LONG_MASK} defines whether the screen
      * is wider/taller than normal.  They may be one of
-     * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.
+     * {@link #SCREENLAYOUT_LONG_NO} or {@link #SCREENLAYOUT_LONG_YES}.</p>
      * 
      * <p>The {@link #SCREENLAYOUT_LAYOUTDIR_MASK} defines whether the screen layout
      * is either LTR or RTL.  They may be one of
-     * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.
+     * {@link #SCREENLAYOUT_LAYOUTDIR_LTR} or {@link #SCREENLAYOUT_LAYOUTDIR_RTL}.</p>
+     *
+     * <p>The {@link #SCREENLAYOUT_ROUND_MASK} defines whether the screen has a rounded
+     * shape. They may be one of {@link #SCREENLAYOUT_ROUND_NO} or {@link #SCREENLAYOUT_ROUND_YES}.
+     * </p>
      *
      * <p>See <a href="{@docRoot}guide/practices/screens_support.html">Supporting
-     * Multiple Screens</a> for more information.
+     * Multiple Screens</a> for more information.</p>
      */
     public int screenLayout;
 
@@ -1328,6 +1357,16 @@
     }
 
     /**
+     * Return whether the screen has a round shape. Apps may choose to change styling based
+     * on this property, such as the alignment or layout of text or informational icons.
+     *
+     * @return true if the screen is rounded, false otherwise
+     */
+    public boolean isScreenRound() {
+        return (screenLayout & SCREENLAYOUT_ROUND_MASK) == SCREENLAYOUT_ROUND_YES;
+    }
+
+    /**
      *
      * @hide
      */
@@ -1425,6 +1464,17 @@
                 break;
         }
 
+        switch (config.screenLayout & Configuration.SCREENLAYOUT_ROUND_MASK) {
+            case Configuration.SCREENLAYOUT_ROUND_YES:
+                parts.add("round");
+                break;
+            case Configuration.SCREENLAYOUT_ROUND_NO:
+                parts.add("notround");
+                break;
+            default:
+                break;
+        }
+
         switch (config.orientation) {
             case Configuration.ORIENTATION_LANDSCAPE:
                 parts.add("land");
@@ -1640,6 +1690,11 @@
             delta.screenLayout |= change.screenLayout & SCREENLAYOUT_LONG_MASK;
         }
 
+        if ((base.screenLayout & SCREENLAYOUT_ROUND_MASK) !=
+                (change.screenLayout & SCREENLAYOUT_ROUND_MASK)) {
+            delta.screenLayout |= change.screenLayout & SCREENLAYOUT_ROUND_MASK;
+        }
+
         if ((base.uiMode & UI_MODE_TYPE_MASK) != (change.uiMode & UI_MODE_TYPE_MASK)) {
             delta.uiMode |= change.uiMode & UI_MODE_TYPE_MASK;
         }
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index d4b971a..5a587fe 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -172,6 +172,17 @@
     public static final int FLAG_PRESENTATION = 1 << 3;
 
     /**
+     * Display flag: Indicates that the display has a round shape.
+     * <p>
+     * This flag identifies displays that are circular, elliptical or otherwise
+     * do not permit the user to see all the way to the logical corners of the display.
+     * </p>
+     *
+     * @see #getFlags
+     */
+    public static final int FLAG_ROUND = 1 << 4;
+
+    /**
      * Display flag: Indicates that the contents of the display should not be scaled
      * to fit the physical screen dimensions.  Used for development only to emulate
      * devices with smaller physicals screens while preserving density.
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index b9fde8a..cf17990 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -609,6 +609,9 @@
         if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
             result.append(", FLAG_SCALING_DISABLED");
         }
+        if ((flags & Display.FLAG_ROUND) != 0) {
+            result.append(", FLAG_ROUND");
+        }
         return result.toString();
     }
 }
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 84e4ca9..a4c7a3e 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2151,4 +2151,10 @@
          format is UMTS|LTE|... -->
     <string translatable="false" name="config_radio_access_family"></string>
 
+    <!-- Whether the main built-in display is round. This will affect
+         Configuration.screenLayout's SCREENLAYOUT_ROUND_MASK flags for Configurations on the
+         main built-in display. Change this in device-specific overlays.
+         Defaults to the older, deprecated config_windowIsRound already used in
+         some existing device-specific resource overlays. -->
+    <bool name="config_mainBuiltInDisplayIsRound">@bool/config_windowIsRound</bool>
 </resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9c6887f..a24d7f3 100755
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2277,4 +2277,5 @@
   <java-symbol type="drawable" name="ic_perm_device_info" />
   <java-symbol type="string" name="config_radio_access_family" />
   <java-symbol type="string" name="notification_inbox_ellipsis" />
+  <java-symbol type="bool" name="config_mainBuiltInDisplayIsRound" />
 </resources>
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 0db3e3f..97ada15 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -88,6 +88,11 @@
     public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7;
 
     /**
+     * Flag: This display device has a round shape.
+     */
+    public static final int FLAG_ROUND = 1 << 8;
+
+    /**
      * Touch attachment: Display does not receive touch.
      */
     public static final int TOUCH_NONE = 0;
@@ -385,6 +390,9 @@
         if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
             msg.append(", FLAG_OWN_CONTENT_ONLY");
         }
+        if ((flags & FLAG_ROUND) != 0) {
+            msg.append(", FLAG_ROUND");
+        }
         return msg.toString();
     }
 }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index cc7d848..e516573 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -16,6 +16,7 @@
 
 package com.android.server.display;
 
+import android.content.res.Resources;
 import com.android.server.LocalServices;
 import com.android.server.lights.Light;
 import com.android.server.lights.LightsManager;
@@ -267,10 +268,15 @@
                 }
 
                 if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
-                    mInfo.name = getContext().getResources().getString(
+                    final Resources res = getContext().getResources();
+                    mInfo.name = res.getString(
                             com.android.internal.R.string.display_manager_built_in_display_name);
                     mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
                             | DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
+                    if (res.getBoolean(
+                            com.android.internal.R.bool.config_mainBuiltInDisplayIsRound)) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
+                    }
                     mInfo.type = Display.TYPE_BUILT_IN;
                     mInfo.densityDpi = (int)(phys.density * 160 + 0.5f);
                     mInfo.xDpi = phys.xDpi;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index 424b4a0..4823769 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -217,6 +217,9 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
             }
+            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) {
+                mBaseDisplayInfo.flags |= Display.FLAG_ROUND;
+            }
             mBaseDisplayInfo.type = deviceInfo.type;
             mBaseDisplayInfo.address = deviceInfo.address;
             mBaseDisplayInfo.name = deviceInfo.name;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 3644506..e43861c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7341,6 +7341,11 @@
         computeSizeRangesAndScreenLayout(displayInfo, rotated, dw, dh, mDisplayMetrics.density,
                 config);
 
+        config.screenLayout = (config.screenLayout & ~Configuration.SCREENLAYOUT_ROUND_MASK)
+                | ((displayInfo.flags & Display.FLAG_ROUND) != 0
+                        ? Configuration.SCREENLAYOUT_ROUND_YES
+                        : Configuration.SCREENLAYOUT_ROUND_NO);
+
         config.compatScreenWidthDp = (int)(config.screenWidthDp / mCompatibleScreenScale);
         config.compatScreenHeightDp = (int)(config.screenHeightDp / mCompatibleScreenScale);
         config.compatSmallestScreenWidthDp = computeCompatSmallestWidth(rotated,