Merge "Update Configuration#isScreenWideColorGamut doc" into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 26e4298..8703bf4 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -162,6 +162,7 @@
   public static final class Manifest.permission_group {
     ctor public Manifest.permission_group();
     field public static final java.lang.String CALENDAR = "android.permission-group.CALENDAR";
+    field public static final java.lang.String CALL_LOG = "android.permission-group.CALL_LOG";
     field public static final java.lang.String CAMERA = "android.permission-group.CAMERA";
     field public static final java.lang.String CONTACTS = "android.permission-group.CONTACTS";
     field public static final java.lang.String LOCATION = "android.permission-group.LOCATION";
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 5219885..986f2ef 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -502,6 +502,7 @@
 }
 
 void StatsLogProcessor::informPullAlarmFired(const int64_t timestampNs) {
+    std::lock_guard<std::mutex> lock(mMetricsMutex);
     mStatsPullerManager.OnAlarmFired(timestampNs);
 }
 
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java
index 9e47ced..ba355f9 100644
--- a/core/java/android/app/NotificationChannel.java
+++ b/core/java/android/app/NotificationChannel.java
@@ -76,6 +76,7 @@
     private static final String ATT_CONTENT_TYPE = "content_type";
     private static final String ATT_SHOW_BADGE = "show_badge";
     private static final String ATT_USER_LOCKED = "locked";
+    private static final String ATT_FG_SERVICE_SHOWN = "fgservice";
     private static final String ATT_GROUP = "group";
     private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system";
     private static final String DELIMITER = ",";
@@ -144,6 +145,7 @@
     // Bitwise representation of fields that have been changed by the user, preventing the app from
     // making changes to these fields.
     private int mUserLockedFields;
+    private boolean mFgServiceShown;
     private boolean mVibrationEnabled;
     private boolean mShowBadge = DEFAULT_SHOW_BADGE;
     private boolean mDeleted = DEFAULT_DELETED;
@@ -200,6 +202,7 @@
         mLights = in.readByte() != 0;
         mVibration = in.createLongArray();
         mUserLockedFields = in.readInt();
+        mFgServiceShown = in.readByte() != 0;
         mVibrationEnabled = in.readByte() != 0;
         mShowBadge = in.readByte() != 0;
         mDeleted = in.readByte() != 0;
@@ -245,6 +248,7 @@
         dest.writeByte(mLights ? (byte) 1 : (byte) 0);
         dest.writeLongArray(mVibration);
         dest.writeInt(mUserLockedFields);
+        dest.writeByte(mFgServiceShown ? (byte) 1 : (byte) 0);
         dest.writeByte(mVibrationEnabled ? (byte) 1 : (byte) 0);
         dest.writeByte(mShowBadge ? (byte) 1 : (byte) 0);
         dest.writeByte(mDeleted ? (byte) 1 : (byte) 0);
@@ -281,6 +285,13 @@
     /**
      * @hide
      */
+    public void setFgServiceShown(boolean shown) {
+        mFgServiceShown = shown;
+    }
+
+    /**
+     * @hide
+     */
     public void setDeleted(boolean deleted) {
         mDeleted = deleted;
     }
@@ -576,6 +587,13 @@
     /**
      * @hide
      */
+    public boolean isFgServiceShown() {
+        return mFgServiceShown;
+    }
+
+    /**
+     * @hide
+     */
     public boolean isBlockableSystem() {
         return mBlockableSystem;
     }
@@ -620,6 +638,7 @@
         setDeleted(safeBool(parser, ATT_DELETED, false));
         setGroup(parser.getAttributeValue(null, ATT_GROUP));
         lockFields(safeInt(parser, ATT_USER_LOCKED, 0));
+        setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false));
         setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false));
     }
 
@@ -724,6 +743,9 @@
         if (getUserLockedFields() != 0) {
             out.attribute(null, ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
         }
+        if (isFgServiceShown()) {
+            out.attribute(null, ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown()));
+        }
         if (canShowBadge()) {
             out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
         }
@@ -772,6 +794,7 @@
         record.put(ATT_LIGHT_COLOR, Integer.toString(getLightColor()));
         record.put(ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate()));
         record.put(ATT_USER_LOCKED, Integer.toString(getUserLockedFields()));
+        record.put(ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown()));
         record.put(ATT_VIBRATION, longArrayToString(getVibrationPattern()));
         record.put(ATT_SHOW_BADGE, Boolean.toString(canShowBadge()));
         record.put(ATT_DELETED, Boolean.toString(isDeleted()));
@@ -933,6 +956,7 @@
                 + ", mLightColor=" + mLightColor
                 + ", mVibration=" + Arrays.toString(mVibration)
                 + ", mUserLockedFields=" + Integer.toHexString(mUserLockedFields)
+                + ", mFgServiceShown=" + mFgServiceShown
                 + ", mVibrationEnabled=" + mVibrationEnabled
                 + ", mShowBadge=" + mShowBadge
                 + ", mDeleted=" + mDeleted
@@ -963,6 +987,7 @@
             }
         }
         proto.write(NotificationChannelProto.USER_LOCKED_FIELDS, mUserLockedFields);
+        proto.write(NotificationChannelProto.FG_SERVICE_SHOWN, mFgServiceShown);
         proto.write(NotificationChannelProto.IS_VIBRATION_ENABLED, mVibrationEnabled);
         proto.write(NotificationChannelProto.SHOW_BADGE, mShowBadge);
         proto.write(NotificationChannelProto.IS_DELETED, mDeleted);
diff --git a/core/java/android/util/apk/ApkVerityBuilder.java b/core/java/android/util/apk/ApkVerityBuilder.java
index f15e1a1..2dd0117 100644
--- a/core/java/android/util/apk/ApkVerityBuilder.java
+++ b/core/java/android/util/apk/ApkVerityBuilder.java
@@ -134,7 +134,7 @@
         assertSigningBlockAlignedAndHasFullPages(signatureInfo);
         long signingBlockSize =
                 signatureInfo.centralDirOffset - signatureInfo.apkSigningBlockOffset;
-        long dataSize = apk.length() - signingBlockSize - ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
+        long dataSize = apk.length() - signingBlockSize;
         int[] levelOffset = calculateVerityLevelOffset(dataSize);
 
         if (treeOutput != null) {
@@ -346,8 +346,8 @@
 
         buffer.putLong(fileSize);           // original file size
 
-        buffer.put((byte) 0);               // auth block offset, disabled here
-        buffer.put((byte) 2);               // extension count
+        buffer.put((byte) 2);               // authenticated extension count
+        buffer.put((byte) 0);               // unauthenticated extension count
         buffer.put(salt);                   // salt (8 bytes)
         skip(buffer, 22);                   // reserved
 
@@ -359,12 +359,6 @@
             long signingBlockSize, long eocdOffset) {
         // Snapshot of the FSVerity structs (subject to change once upstreamed).
         //
-        // struct fsverity_extension {
-        //   __le16 length;
-        //   u8 type;
-        //   u8 reserved[5];
-        // };
-        //
         // struct fsverity_extension_elide {
         //   __le64 offset;
         //   __le64 length;
@@ -382,10 +376,10 @@
             // struct fsverity_extension #1
             final int kSizeOfFsverityElidedExtension = 16;
 
-            buffer.putShort((short)  // total size of extension, padded to 64-bit alignment
-                    (kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension));
-            buffer.put((byte) 0);    // ID of elide extension
-            skip(buffer, 5);         // reserved
+            // First field is total size of extension, padded to 64-bit alignment
+            buffer.putInt(kSizeOfFsverityExtensionHeader + kSizeOfFsverityElidedExtension);
+            buffer.putShort((short) 1);  // ID of elide extension
+            skip(buffer, 2);             // reserved
 
             // struct fsverity_extension_elide
             buffer.putLong(signingBlockOffset);
@@ -398,9 +392,9 @@
                     + 8 // offset size
                     + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_SIZE;
 
-            buffer.putShort((short) kTotalSize);
-            buffer.put((byte) 1);    // ID of patch extension
-            skip(buffer, 5);         // reserved
+            buffer.putInt(kTotalSize);   // Total size of extension, padded to 64-bit alignment
+            buffer.putShort((short) 2);  // ID of patch extension
+            skip(buffer, 2);             // reserved
 
             // struct fsverity_extension_patch
             buffer.putLong(eocdOffset + ZIP_EOCD_CENTRAL_DIR_OFFSET_FIELD_OFFSET);  // offset
@@ -412,7 +406,7 @@
             if (kPadding == kExtensionSizeAlignment) {
                 kPadding = 0;
             }
-            skip(buffer, kPadding);                              // padding
+            skip(buffer, kPadding);      // padding
         }
 
         buffer.flip();
diff --git a/core/proto/android/app/notification_channel.proto b/core/proto/android/app/notification_channel.proto
index 337aa1c..d3808e8 100644
--- a/core/proto/android/app/notification_channel.proto
+++ b/core/proto/android/app/notification_channel.proto
@@ -53,4 +53,5 @@
     optional android.media.AudioAttributesProto audio_attributes = 16;
     // If this is a blockable system notification channel.
     optional bool is_blockable_system = 17;
+    optional bool fg_service_shown = 18;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 92560f3..1f8d43c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -840,6 +840,77 @@
         android:protectionLevel="dangerous|instant" />
 
     <!-- ====================================================================== -->
+    <!-- Permissions for accessing the call log                                 -->
+    <!-- ====================================================================== -->
+    <eat-comment />
+
+    <!-- Used for permissions that are associated telephony features. -->
+    <permission-group android:name="android.permission-group.CALL_LOG"
+        android:icon="@drawable/perm_group_phone_calls"
+        android:label="@string/permgrouplab_calllog"
+        android:description="@string/permgroupdesc_calllog"
+        android:request="@string/permgrouprequest_calllog"
+        android:priority="450" />
+
+    <!-- Allows an application to access the IMS call service: making and
+         modifying a call
+        <p>Protection level: signature|privileged
+        @hide
+    -->
+    <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
+        android:label="@string/permlab_accessImsCallService"
+        android:description="@string/permdesc_accessImsCallService"
+        android:protectionLevel="signature|privileged" />
+
+    <!-- Allows an application to read the user's call log.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #READ_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.READ_CALL_LOG"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_readCallLog"
+        android:description="@string/permdesc_readCallLog"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an application to write (but not read) the user's
+         call log data.
+         <p class="note"><strong>Note:</strong> If your app uses the
+         {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+         minSdkVersion}</a> and <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
+         grants your app this permission. If you don't need this permission, be sure your <a
+         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+         targetSdkVersion}</a> is 16 or higher.</p>
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.WRITE_CALL_LOG"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_writeCallLog"
+        android:description="@string/permdesc_writeCallLog"
+        android:protectionLevel="dangerous" />
+
+    <!-- Allows an application to see the number being dialed during an outgoing
+         call with the option to redirect the call to a different number or
+         abort the call altogether.
+         <p>Protection level: dangerous
+    -->
+    <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
+        android:permissionGroup="android.permission-group.CALL_LOG"
+        android:label="@string/permlab_processOutgoingCalls"
+        android:description="@string/permdesc_processOutgoingCalls"
+        android:protectionLevel="dangerous" />
+
+    <!-- ====================================================================== -->
     <!-- Permissions for accessing the device telephony                         -->
     <!-- ====================================================================== -->
     <eat-comment />
@@ -891,54 +962,6 @@
         android:description="@string/permdesc_callPhone"
         android:protectionLevel="dangerous" />
 
-    <!-- Allows an application to access the IMS call service: making and
-         modifying a call
-        <p>Protection level: signature|privileged
-        @hide
-    -->
-    <permission android:name="android.permission.ACCESS_IMS_CALL_SERVICE"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_accessImsCallService"
-        android:description="@string/permdesc_accessImsCallService"
-        android:protectionLevel="signature|privileged" />
-
-    <!-- Allows an application to read the user's call log.
-         <p class="note"><strong>Note:</strong> If your app uses the
-         {@link #READ_CONTACTS} permission and <em>both</em> your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-         minSdkVersion}</a> and <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
-         grants your app this permission. If you don't need this permission, be sure your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p>
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.READ_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_readCallLog"
-        android:description="@string/permdesc_readCallLog"
-        android:protectionLevel="dangerous" />
-
-    <!-- Allows an application to write (but not read) the user's
-         call log data.
-         <p class="note"><strong>Note:</strong> If your app uses the
-         {@link #WRITE_CONTACTS} permission and <em>both</em> your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
-         minSdkVersion}</a> and <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> values are set to 15 or lower, the system implicitly
-         grants your app this permission. If you don't need this permission, be sure your <a
-         href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
-         targetSdkVersion}</a> is 16 or higher.</p>
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.WRITE_CALL_LOG"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_writeCallLog"
-        android:description="@string/permdesc_writeCallLog"
-        android:protectionLevel="dangerous" />
-
     <!-- Allows an application to add voicemails into the system.
          <p>Protection level: dangerous
     -->
@@ -957,18 +980,6 @@
         android:label="@string/permlab_use_sip"
         android:protectionLevel="dangerous"/>
 
-    <!-- Allows an application to see the number being dialed during an outgoing
-         call with the option to redirect the call to a different number or
-         abort the call altogether.
-         <p>Protection level: dangerous
-    -->
-    <permission android:name="android.permission.PROCESS_OUTGOING_CALLS"
-        android:permissionGroup="android.permission-group.PHONE"
-        android:label="@string/permlab_processOutgoingCalls"
-        android:description="@string/permdesc_processOutgoingCalls"
-        android:protectionLevel="dangerous" />
-
-
     <!-- Allows the app to answer an incoming phone call.
          <p>Protection level: dangerous
     -->
diff --git a/core/res/res/values-mcc405/config.xml b/core/res/res/values-mcc405/config.xml
index 6b77e9c..4cadef7 100644
--- a/core/res/res/values-mcc405/config.xml
+++ b/core/res/res/values-mcc405/config.xml
@@ -20,4 +20,6 @@
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <!-- Whether camera shutter sound is forced or not  (country specific). -->
     <bool name="config_camera_sound_forced">true</bool>
+    <!-- Show area update info settings in CellBroadcastReceiver and information in SIM status in Settings app -->
+    <bool name="config_showAreaUpdateInfoSettings">true</bool>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index c7b65ef..791f7c6 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -247,7 +247,7 @@
     <dimen name="notification_header_shrink_min_width">72dp</dimen>
 
     <!-- The minimum height of the content if there are at least two lines or a picture-->
-    <dimen name="notification_min_content_height">41dp</dimen>
+    <dimen name="notification_min_content_height">39dp</dimen>
 
     <!-- The size of the media actions in the media notification. -->
     <dimen name="media_notification_action_button_size">48dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b92052b..bf7ca52 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -724,6 +724,14 @@
         &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to take pictures and record video?</string>
 
     <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgrouplab_calllog">Call logs</string>
+    <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
+    <string name="permgroupdesc_calllog">read and write phone call log</string>
+    <!-- Message shown to the user when the apps requests permission from this group -->
+    <string name="permgrouprequest_calllog">Allow
+        &lt;b><xliff:g id="app_name" example="Gmail">%1$s</xliff:g>&lt;/b> to access your phone call logs?</string>
+
+    <!-- Title of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgrouplab_phone">Phone</string>
     <!-- Description of a category of application permissions, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permgroupdesc_phone">make and manage phone calls</string>
diff --git a/packages/SystemUI/res/layout/app_ops_info.xml b/packages/SystemUI/res/layout/app_ops_info.xml
index 74a4c6e..676301e 100644
--- a/packages/SystemUI/res/layout/app_ops_info.xml
+++ b/packages/SystemUI/res/layout/app_ops_info.xml
@@ -21,6 +21,8 @@
         android:layout_height="wrap_content"
         android:id="@+id/app_ops_info"
         android:clickable="true"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical"
         android:paddingStart="@*android:dimen/notification_content_margin_start"
         android:paddingEnd="@*android:dimen/notification_content_margin_end"
@@ -63,10 +65,10 @@
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="horizontal"
         android:layout_marginTop="@dimen/notification_guts_button_spacing"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:gravity="end" >
+        android:gravity="end"
+        android:orientation="horizontal">
 
         <TextView
             android:id="@+id/settings"
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index b1cb6cf..095f181 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -17,10 +17,12 @@
 
 <com.android.systemui.statusbar.NotificationInfo
         xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/notification_guts"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:id="@+id/notification_guts"
         android:clickable="true"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical"
         android:paddingStart="@*android:dimen/notification_content_margin_start"
         android:paddingEnd="@*android:dimen/notification_content_margin_end"
@@ -33,8 +35,7 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:clipChildren="false"
-        android:clipToPadding="false"
-        android:layout_marginTop="2dp" >
+        android:clipToPadding="false">
         <ImageView
             android:id="@+id/pkgicon"
             android:layout_width="@dimen/notification_guts_header_height"
@@ -74,16 +75,16 @@
             android:layout_toEndOf="@id/pkg_group_divider" />
         <ImageButton
             android:id="@+id/info"
-            android:src="@drawable/ic_info"
-            android:tint="?android:attr/colorAccent"
-            android:layout_width="48dp"
-            android:layout_height="48dp"
-            android:padding="12dp"
-            android:layout_marginEnd="-12dp"
+            android:layout_width="56dp"
+            android:layout_height="56dp"
+            android:layout_alignParentEnd="true"
             android:layout_centerVertical="true"
-            android:contentDescription="@string/notification_more_settings"
+            android:layout_marginEnd="-16dp"
             android:background="@drawable/ripple_drawable"
-            android:layout_alignParentEnd="true" />
+            android:contentDescription="@string/notification_more_settings"
+            android:padding="16dp"
+            android:src="@drawable/ic_info"
+            android:tint="?android:attr/colorAccent" />
     </RelativeLayout>
 
     <LinearLayout
@@ -91,7 +92,8 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:layout_marginTop="@*android:dimen/notification_header_padding_top"
+        android:clipChildren="false"
+        android:clipToPadding="false"
         android:orientation="vertical">
 
         <!-- Channel Info Block -->
@@ -105,14 +107,13 @@
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:layout_marginBottom="6dp"
-                style="@style/TextAppearance.NotificationInfo.Primary" />
+                style="@android:style/TextAppearance.Material.Notification.Title" />
             <!-- Question prompt -->
             <TextView
                 android:id="@+id/block_prompt"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                style="@style/TextAppearance.NotificationInfo.Secondary" />
+                style="@android:style/TextAppearance.Material.Notification" />
         </LinearLayout>
 
         <!-- Settings and Done buttons -->
@@ -139,12 +140,14 @@
                 android:text="@string/inline_stop_button"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
             <TextView
                 android:id="@+id/minimize"
                 android:text="@string/inline_minimize_button"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button" />
             <TextView
                 android:id="@+id/keep"
@@ -152,6 +155,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:layout_marginEnd="-8dp"
+                android:layout_marginStart="@dimen/notification_guts_button_horizontal_spacing"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
         </LinearLayout>
     </LinearLayout>
@@ -160,22 +164,24 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_marginBottom="@dimen/notification_guts_button_spacing"
-        android:layout_marginTop="@*android:dimen/notification_header_padding_top"
+        android:layout_marginTop="@dimen/notification_guts_button_spacing"
         android:visibility="gone"
         android:orientation="horizontal" >
         <TextView
             android:id="@+id/confirmation_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_centerVertical="true"
             android:text="@string/notification_channel_disabled"
             style="@style/TextAppearance.NotificationInfo.Confirmation"/>
         <TextView
             android:id="@+id/undo"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:text="@string/inline_undo"
             android:layout_alignParentEnd="true"
+            android:layout_centerVertical="true"
             android:layout_marginEnd="-8dp"
+            android:text="@string/inline_undo"
             style="@style/TextAppearance.NotificationInfo.Button"/>
     </RelativeLayout>
 </com.android.systemui.statusbar.NotificationInfo>
diff --git a/packages/SystemUI/res/layout/status_bar_wifi_group.xml b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
index 482f780..c419b90 100644
--- a/packages/SystemUI/res/layout/status_bar_wifi_group.xml
+++ b/packages/SystemUI/res/layout/status_bar_wifi_group.xml
@@ -28,8 +28,8 @@
         android:id="@+id/wifi_group"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
-        android:paddingStart="2dp"
         android:gravity="center_vertical"
+        android:layout_marginStart="2.5dp"
     >
         <FrameLayout
                 android:id="@+id/inout_container"
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index fd25c40..efcca63 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -95,7 +95,7 @@
     <color name="notification_gear_color">#ff757575</color>
 
     <!-- The "inside" of a notification, reached via longpress -->
-    <color name="notification_guts_bg_color">#eeeeee</color>
+    <color name="notification_guts_bg_color">#f8f9fa</color>
 
     <color name="assist_orb_color">#ffffff</color>
 
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index eb71911..af343fb 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -158,8 +158,17 @@
     <!-- The space around a notification menu item  -->
     <dimen name="notification_menu_icon_padding">20dp</dimen>
 
-    <!-- The veritical space around the buttons in the inline settings -->
-    <dimen name="notification_guts_button_spacing">20dp</dimen>
+    <!-- The vertical space around the buttons in the inline settings -->
+    <dimen name="notification_guts_button_spacing">6dp</dimen>
+
+    <!-- The vertical padding a notification guts button has to fulfill the 48dp touch target -->
+    <dimen name="notification_guts_button_vertical_padding">14dp</dimen>
+
+    <!-- The horizontal padding for notification guts buttons-->
+    <dimen name="notification_guts_button_horizontal_padding">14dp</dimen>
+
+    <!-- The horizontal space around the buttons in the inline settings -->
+    <dimen name="notification_guts_button_horizontal_spacing">8dp</dimen>
 
     <!-- The height of the header in inline settings -->
     <dimen name="notification_guts_header_height">24dp</dimen>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 1e19534..c73da3c 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -483,8 +483,10 @@
         <item name="android:background">@drawable/btn_borderless_rect</item>
         <item name="android:gravity">center</item>
         <item name="android:focusable">true</item>
-        <item name="android:paddingStart">8dp</item>
-        <item name="android:paddingEnd">8dp</item>
+        <item name="android:paddingTop">@dimen/notification_guts_button_vertical_padding</item>
+        <item name="android:paddingBottom">@dimen/notification_guts_button_vertical_padding</item>
+        <item name="android:paddingLeft">@dimen/notification_guts_button_horizontal_padding</item>
+        <item name="android:paddingRight">@dimen/notification_guts_button_horizontal_padding</item>
     </style>
 
     <style name="TextAppearance.HeadsUpStatusBarText"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
index e93e78d..952c8ae 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/MetricsLoggerCompat.java
@@ -17,10 +17,12 @@
 package com.android.systemui.shared.system;
 
 import com.android.internal.logging.MetricsLogger;
+import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 
 public class MetricsLoggerCompat {
 
     private final MetricsLogger mMetricsLogger;
+    public static final int OVERVIEW_ACTIVITY = MetricsEvent.OVERVIEW_ACTIVITY;
 
     public MetricsLoggerCompat() {
         mMetricsLogger = new MetricsLogger();
@@ -37,4 +39,12 @@
     public void visible(int category) {
         mMetricsLogger.visible(category);
     }
+
+    public void hidden(int category) {
+        mMetricsLogger.hidden(category);
+    }
+
+    public void visibility(int category, boolean visible) {
+        mMetricsLogger.visibility(category, visible);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 824960e..46b4078 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -24,6 +24,7 @@
 import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.widget.LinearLayout;
 
 import com.android.internal.statusbar.StatusBarIcon;
@@ -56,7 +57,14 @@
         mIconSize = iconSize;
         mColor = DarkIconDispatcher.DEFAULT_ICON_TINT;
 
+        if (statusIcons instanceof StatusIconContainer) {
+            setShouldRestrictIcons(((StatusIconContainer) statusIcons).isRestrictingIcons());
+        } else {
+            setShouldRestrictIcons(false);
+        }
         setLayoutParams(mStatusIcons.getLayoutParams());
+        setPadding(mStatusIcons.getPaddingLeft(),mStatusIcons.getPaddingTop(),
+                mStatusIcons.getPaddingRight(), mStatusIcons.getPaddingBottom());
         setOrientation(mStatusIcons.getOrientation());
         setGravity(Gravity.CENTER_VERTICAL); // no LL.getGravity()
         ViewGroup p = (ViewGroup) mStatusIcons.getParent();
@@ -77,6 +85,7 @@
         for (int i = 0; i < getChildCount(); i++) {
             StatusIconDisplayable child = (StatusIconDisplayable) getChildAt(i);
             child.setStaticDrawableColor(mColor);
+            child.setDecorColor(mColor);
         }
     }
 
@@ -189,11 +198,12 @@
         }
         StatusBarIcon icon = new StatusBarIcon(iconPkg, UserHandle.SYSTEM, iconId, 0, 0, "Demo");
         icon.visible = true;
-        StatusBarIconView v = new StatusBarIconView(getContext(), null, null);
+        StatusBarIconView v = new StatusBarIconView(getContext(), slot, null, false);
         v.setTag(slot);
         v.set(icon);
         v.setStaticDrawableColor(mColor);
-        addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+        v.setDecorColor(mColor);
+        addView(v, 0, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, mIconSize));
     }
 
     public void addDemoWifiView(WifiIconState state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
index c97c8eb..8398879 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusIconContainer.java
@@ -73,19 +73,23 @@
 
     public StatusIconContainer(Context context, AttributeSet attrs) {
         super(context, attrs);
+        initDimens();
+        setWillNotDraw(!DEBUG_OVERFLOW);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        setWillNotDraw(!DEBUG_OVERFLOW);
-        initDimens();
     }
 
     public void setShouldRestrictIcons(boolean should) {
         mShouldRestrictIcons = should;
     }
 
+    public boolean isRestrictingIcons() {
+        return mShouldRestrictIcons;
+    }
+
     private void initDimens() {
         // This is the same value that StatusBarIconView uses
         mIconDotFrameWidth = getResources().getDimensionPixelSize(
@@ -209,8 +213,8 @@
         int childCount = getChildCount();
         // Underflow === don't show content until that index
         int firstUnderflowIndex = -1;
-        if (DEBUG) android.util.Log.d(TAG, "calculateIconTransitions: start=" + translationX
-                + " width=" + width);
+        if (DEBUG) android.util.Log.d(TAG, "calculateIconTranslations: start=" + translationX
+                + " width=" + width + " underflow=" + mNeedsUnderflow);
 
         // Collect all of the states which want to be visible
         for (int i = childCount - 1; i >= 0; i--) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index b68ef11..bf17798 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4051,17 +4051,29 @@
         final NotificationRecord r = new NotificationRecord(getContext(), n, channel);
         r.setIsAppImportanceLocked(mRankingHelper.getIsAppImportanceLocked(pkg, callingUid));
 
-        if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0
-                && (channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
-                && (r.getImportance() == IMPORTANCE_MIN || r.getImportance() == IMPORTANCE_NONE)) {
-            // Increase the importance of foreground service notifications unless the user had an
-            // opinion otherwise
-            if (TextUtils.isEmpty(channelId)
-                    || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
-                r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service");
-            } else {
-                channel.setImportance(IMPORTANCE_LOW);
-                mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false);
+        if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
+            final boolean fgServiceShown = channel.isFgServiceShown();
+            if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0
+                        || !fgServiceShown)
+                    && (r.getImportance() == IMPORTANCE_MIN
+                            || r.getImportance() == IMPORTANCE_NONE)) {
+                // Increase the importance of foreground service notifications unless the user had
+                // an opinion otherwise (and the channel hasn't yet shown a fg service).
+                if (TextUtils.isEmpty(channelId)
+                        || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
+                    r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service");
+                } else {
+                    channel.setImportance(IMPORTANCE_LOW);
+                    if (!fgServiceShown) {
+                        channel.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE);
+                        channel.setFgServiceShown(true);
+                    }
+                    mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false);
+                    r.updateNotificationChannel(channel);
+                }
+            } else if (!fgServiceShown && !TextUtils.isEmpty(channelId)
+                    && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) {
+                channel.setFgServiceShown(true);
                 r.updateNotificationChannel(channel);
             }
         }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 58f5898..376cc64 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -557,11 +557,34 @@
         assertEquals(IMPORTANCE_NONE,
                 mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
 
-        final StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
+        StatusBarNotification sbn = generateNotificationRecord(channel).sbn;
         sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
         mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
                 sbn.getId(), sbn.getNotification(), sbn.getUserId());
         waitForIdle();
+        // The first time a foreground service notification is shown, we allow the channel
+        // to be updated to allow it to be seen.
+        assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
+        assertEquals(IMPORTANCE_LOW,
+                mService.getNotificationRecord(sbn.getKey()).getImportance());
+        assertEquals(IMPORTANCE_LOW,
+                mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
+        mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId());
+        waitForIdle();
+
+        update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE);
+        update.setFgServiceShown(true);
+        mBinderService.updateNotificationChannelForPackage(PKG, mUid, update);
+        waitForIdle();
+        assertEquals(IMPORTANCE_NONE,
+                mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance());
+
+        sbn = generateNotificationRecord(channel).sbn;
+        sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE;
+        mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag",
+                sbn.getId(), sbn.getNotification(), sbn.getUserId());
+        waitForIdle();
+        // The second time it is shown, we keep the user's preference.
         assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length);
         assertNull(mService.getNotificationRecord(sbn.getKey()));
         assertEquals(IMPORTANCE_NONE,
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 4ca175f..6ce66f0 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -98,7 +98,7 @@
     private static final String LAUNCH_FILE = "applaunch.txt";
     private static final String TRACE_SUB_DIRECTORY = "atrace_logs";
     private static final String DEFAULT_TRACE_CATEGORIES =
-            "sched,freq,gfx,view,dalvik,webview,input,wm,disk,am,wm,binder_driver,hal";
+            "sched,freq,gfx,view,dalvik,webview,input,wm,disk,am,wm,binder_driver,hal,ss";
     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
     private static final String TRIAL_LAUNCH = "TRIAL_LAUNCH";
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 19c6c31..7f48544 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -598,10 +598,13 @@
       // If no inner element exists, represent a unique identifier
       out_resource->value = util::make_unique<Id>();
     } else {
-      // If an inner element exists, the inner element must be a reference to
-      // another resource id
       Reference* ref = ValueCast<Reference>(out_resource->value.get());
-      if (!ref || ref->name.value().type != ResourceType::kId) {
+      if (ref && !ref->name && !ref->id) {
+        // A null reference also means there is no inner element when ids are in the form:
+        //    <id name="name"/>
+        out_resource->value = util::make_unique<Id>();
+      } else if (!ref || ref->name.value().type != ResourceType::kId) {
+        // If an inner element exists, the inner element must be a reference to another resource id
         diag_->Error(DiagMessage(out_resource->source)
                          << "<" << parser->element_name()
                          << "> inner element must either be a resource reference or empty");
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index c12b9fa..41b4041 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -944,20 +944,30 @@
   ASSERT_THAT(test::GetValue<Id>(&table_, "id/bar"), NotNull());
   ASSERT_THAT(test::GetValue<Id>(&table_, "id/baz"), NotNull());
 
+  input = R"(
+    <id name="foo2">@id/bar</id>
+    <id name="bar2"/>
+    <id name="baz2"></id>)";
+  ASSERT_TRUE(TestParse(input));
+
+  ASSERT_THAT(test::GetValue<Reference>(&table_, "id/foo2"), NotNull());
+  ASSERT_THAT(test::GetValue<Id>(&table_, "id/bar2"), NotNull());
+  ASSERT_THAT(test::GetValue<Id>(&table_, "id/baz2"), NotNull());
+
   // Reject attribute references
-  input = R"(<item name="foo2" type="id">?attr/bar"</item>)";
+  input = R"(<item name="foo3" type="id">?attr/bar"</item>)";
   ASSERT_FALSE(TestParse(input));
 
   // Reject non-references
-  input = R"(<item name="foo3" type="id">0x7f010001</item>)";
+  input = R"(<item name="foo4" type="id">0x7f010001</item>)";
   ASSERT_FALSE(TestParse(input));
-  input = R"(<item name="foo4" type="id">@drawable/my_image</item>)";
+  input = R"(<item name="foo5" type="id">@drawable/my_image</item>)";
   ASSERT_FALSE(TestParse(input));
-  input = R"(<item name="foo5" type="id"><string name="biz"></string></item>)";
+  input = R"(<item name="foo6" type="id"><string name="biz"></string></item>)";
   ASSERT_FALSE(TestParse(input));
 
   // Ids that reference other resource ids cannot be public
-  input = R"(<public name="foo6" type="id">@id/bar6</item>)";
+  input = R"(<public name="foo7" type="id">@id/bar7</item>)";
   ASSERT_FALSE(TestParse(input));
 }