Merge "Update clearData flow for notification settings" into qt-dev
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 86b10b9..0d22f3a 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -773,6 +773,8 @@
     private static final int LOG_AM_ON_RESTART_CALLED = 30058;
     private static final int LOG_AM_ON_DESTROY_CALLED = 30060;
     private static final int LOG_AM_ON_ACTIVITY_RESULT_CALLED = 30062;
+    private static final int LOG_AM_ON_TOP_RESUMED_GAINED_CALLED = 30064;
+    private static final int LOG_AM_ON_TOP_RESUMED_LOST_CALLED = 30065;
 
     private static class ManagedDialog {
         Dialog mDialog;
@@ -1840,6 +1842,13 @@
     public void onTopResumedActivityChanged(boolean isTopResumedActivity) {
     }
 
+    final void performTopResumedActivityChanged(boolean isTopResumedActivity, String reason) {
+        onTopResumedActivityChanged(isTopResumedActivity);
+
+        writeEventLog(isTopResumedActivity
+                ? LOG_AM_ON_TOP_RESUMED_GAINED_CALLED : LOG_AM_ON_TOP_RESUMED_LOST_CALLED, reason);
+    }
+
     void setVoiceInteractor(IVoiceInteractor voiceInteractor) {
         if (mVoiceInteractor != null) {
             for (Request activeRequest: mVoiceInteractor.getActiveRequests()) {
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 474f25b..13add09 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4026,7 +4026,7 @@
             r.persistentState = null;
             r.setState(ON_RESUME);
 
-            reportTopResumedActivityChanged(r, r.isTopResumedActivity);
+            reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
         } catch (Exception e) {
             if (!mInstrumentation.onException(r.activity, e)) {
                 throw new RuntimeException("Unable to resume activity "
@@ -4201,7 +4201,7 @@
         r.isTopResumedActivity = onTop;
 
         if (r.getLifecycleState() == ON_RESUME) {
-            reportTopResumedActivityChanged(r, onTop);
+            reportTopResumedActivityChanged(r, onTop, "topStateChangedWhenResumed");
         } else {
             if (DEBUG_ORDER) {
                 Slog.d(TAG, "Won't deliver top position change in state=" + r.getLifecycleState());
@@ -4213,10 +4213,11 @@
      * Call {@link Activity#onTopResumedActivityChanged(boolean)} if its top resumed state changed
      * since the last report.
      */
-    private void reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop) {
+    private void reportTopResumedActivityChanged(ActivityClientRecord r, boolean onTop,
+            String reason) {
         if (r.lastReportedTopResumedState != onTop) {
             r.lastReportedTopResumedState = onTop;
-            r.activity.onTopResumedActivityChanged(onTop);
+            r.activity.performTopResumedActivityChanged(onTop, reason);
         }
     }
 
@@ -4313,7 +4314,7 @@
 
         // Always reporting top resumed position loss when pausing an activity. If necessary, it
         // will be restored in performResumeActivity().
-        reportTopResumedActivityChanged(r, false /* onTop */);
+        reportTopResumedActivityChanged(r, false /* onTop */, "pausing");
 
         try {
             r.activity.mCalled = false;
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a7244a7..76826d3 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -19,7 +19,6 @@
 import android.annotation.CallSuper;
 import android.annotation.Nullable;
 import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.Intent;
 import android.content.res.AssetFileDescriptor;
 import android.database.Cursor;
@@ -266,17 +265,7 @@
         if (visibleFolder != null) {
             assert (visibleFolder.isDirectory());
 
-            final long token = Binder.clearCallingIdentity();
-
-            try {
-                final ContentResolver resolver = getContext().getContentResolver();
-                final Uri uri = MediaStore.Files.getDirectoryUri("external");
-                ContentValues values = new ContentValues();
-                values.put(MediaStore.Files.FileColumns.DATA, visibleFolder.getAbsolutePath());
-                resolver.insert(uri, values);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            MediaStore.scanFile(getContext(), visibleFolder);
         }
     }
 
diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp
index 1c247cb..7052ed6 100644
--- a/core/jni/android_hardware_camera2_DngCreator.cpp
+++ b/core/jni/android_hardware_camera2_DngCreator.cpp
@@ -1008,9 +1008,11 @@
         double x, double y,
         const std::array<float, 6>& distortion,
         const float cx, const float cy, const float f,
-        int preCorrW, int preCorrH) {
+        const int preCorrW, const int preCorrH, const int xMin, const int yMin) {
     undistort(x, y, distortion, cx, cy, f);
-    if (x < 0.0 || y < 0.0 || x > preCorrW - 1 || y > preCorrH - 1) {
+    int xMax = xMin + preCorrW - 1;
+    int yMax = yMin + preCorrH - 1;
+    if (x < xMin || y < yMin || x > xMax || y > yMax) {
         return false;
     }
     return true;
@@ -1019,40 +1021,48 @@
 static inline bool boxWithinPrecorrectionArray(
         int left, int top, int right, int bottom,
         const std::array<float, 6>& distortion,
-        const float& cx, const float& cy, const float& f,
-        const int& preCorrW, const int& preCorrH){
+        const float cx, const float cy, const float f,
+        const int preCorrW, const int preCorrH, const int xMin, const int yMin){
     // Top row
-    if (!unDistortWithinPreCorrArray(left, top, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(left, top,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
-    if (!unDistortWithinPreCorrArray(cx, top, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(cx, top,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
-    if (!unDistortWithinPreCorrArray(right, top, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(right, top,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
     // Middle row
-    if (!unDistortWithinPreCorrArray(left, cy, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(left, cy,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
-    if (!unDistortWithinPreCorrArray(right, cy, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(right, cy,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
     // Bottom row
-    if (!unDistortWithinPreCorrArray(left, bottom, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(left, bottom,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
-    if (!unDistortWithinPreCorrArray(cx, bottom, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(cx, bottom,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
 
-    if (!unDistortWithinPreCorrArray(right, bottom, distortion, cx, cy, f, preCorrW, preCorrH)) {
+    if (!unDistortWithinPreCorrArray(right, bottom,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
         return false;
     }
     return true;
@@ -1062,7 +1072,8 @@
         double scale/*must be <= 1.0*/,
         const std::array<float, 6>& distortion,
         const float cx, const float cy, const float f,
-        const int preCorrW, const int preCorrH){
+        const int preCorrW, const int preCorrH,
+        const int xMin, const int yMin){
 
     double left = cx * (1.0 - scale);
     double right = (preCorrW - 1) * scale + cx * (1.0 - scale);
@@ -1070,14 +1081,14 @@
     double bottom = (preCorrH - 1) * scale + cy * (1.0 - scale);
 
     return boxWithinPrecorrectionArray(left, top, right, bottom,
-            distortion, cx, cy, f, preCorrW, preCorrH);
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin);
 }
 
 static status_t findPostCorrectionScale(
         double stepSize, double minScale,
         const std::array<float, 6>& distortion,
         const float cx, const float cy, const float f,
-        const int preCorrW, const int preCorrH,
+        const int preCorrW, const int preCorrH, const int xMin, const int yMin,
         /*out*/ double* outScale) {
     if (outScale == nullptr) {
         ALOGE("%s: outScale must not be null", __FUNCTION__);
@@ -1086,7 +1097,7 @@
 
     for (double scale = 1.0; scale > minScale; scale -= stepSize) {
         if (scaledBoxWithinPrecorrectionArray(
-                scale, distortion, cx, cy, f, preCorrW, preCorrH)) {
+                scale, distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin)) {
             *outScale = scale;
             return OK;
         }
@@ -1100,16 +1111,18 @@
 // are sampled within the precorrection array
 static void normalizeLensDistortion(
         /*inout*/std::array<float, 6>& distortion,
-        float cx, float cy, float f, int preCorrW, int preCorrH) {
-    ALOGV("%s: distortion [%f, %f, %f, %f, %f, %f], (cx,cy) (%f, %f), f %f, (W,H) (%d, %d)",
+        float cx, float cy, float f, int preCorrW, int preCorrH, int xMin = 0, int yMin = 0) {
+    ALOGV("%s: distortion [%f, %f, %f, %f, %f, %f], (cx,cy) (%f, %f), f %f, (W,H) (%d, %d)"
+            ", (xmin, ymin, xmax, ymax) (%d, %d, %d, %d)",
             __FUNCTION__, distortion[0], distortion[1], distortion[2],
             distortion[3], distortion[4], distortion[5],
-            cx, cy, f, preCorrW, preCorrH);
+            cx, cy, f, preCorrW, preCorrH,
+            xMin, yMin, xMin + preCorrW - 1, yMin + preCorrH - 1);
 
     // Only update distortion coeffients if we can find a good bounding box
     double scale = 1.0;
     if (OK == findPostCorrectionScale(0.002, 0.5,
-            distortion, cx, cy, f, preCorrW, preCorrH,
+            distortion, cx, cy, f, preCorrW, preCorrH, xMin, yMin,
             /*out*/&scale)) {
         ALOGV("%s: scaling distortion coefficients by %f", __FUNCTION__, scale);
         // The formula:
@@ -1216,6 +1229,8 @@
 
     sp<TiffWriter> writer = new TiffWriter();
 
+    uint32_t preXMin = 0;
+    uint32_t preYMin = 0;
     uint32_t preWidth = 0;
     uint32_t preHeight = 0;
     uint8_t colorFilter = 0;
@@ -1225,6 +1240,8 @@
         camera_metadata_entry entry =
                 characteristics.find(ANDROID_SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
         BAIL_IF_EMPTY_RET_NULL_SP(entry, env, TAG_IMAGEWIDTH, writer);
+        preXMin = static_cast<uint32_t>(entry.data.i32[0]);
+        preYMin = static_cast<uint32_t>(entry.data.i32[1]);
         preWidth = static_cast<uint32_t>(entry.data.i32[2]);
         preHeight = static_cast<uint32_t>(entry.data.i32[3]);
 
@@ -1966,9 +1983,16 @@
                     distortion[i+1] = entry3.data.f[i];
                 }
 
-                // TODO b/118690688: deal with the case where RAW size != preCorrSize
                 if (preWidth == imageWidth && preHeight == imageHeight) {
                     normalizeLensDistortion(distortion, cx, cy, f, preWidth, preHeight);
+                } else {
+                    // image size == pixel array size (contains optical black pixels)
+                    // cx/cy is defined in preCorrArray so adding the offset
+                    // Also changes default xmin/ymin so that pixels are only
+                    // sampled within preCorrection array
+                    normalizeLensDistortion(
+                            distortion, cx + preXMin, cy + preYMin, f, preWidth, preHeight,
+                            preXMin, preYMin);
                 }
 
                 float m_x = std::fmaxf(preWidth-1 - cx, cx);
diff --git a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
index 49c16be..dce9ce1 100644
--- a/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
+++ b/packages/SystemUI/res/layout/ongoing_privacy_chip.xml
@@ -21,8 +21,6 @@
     android:id="@+id/privacy_chip"
     android:layout_height="match_parent"
     android:layout_width="wrap_content"
-    android:layout_marginLeft="@dimen/ongoing_appops_chip_margin"
-    android:layout_marginRight="@dimen/ongoing_appops_chip_margin"
     android:layout_gravity="center_vertical|end"
     android:gravity="center_vertical"
     android:orientation="horizontal"
diff --git a/packages/SystemUI/res/layout/qs_carrier.xml b/packages/SystemUI/res/layout/qs_carrier.xml
index b94a316..8f74806 100644
--- a/packages/SystemUI/res/layout/qs_carrier.xml
+++ b/packages/SystemUI/res/layout/qs_carrier.xml
@@ -19,6 +19,7 @@
     android:id="@+id/linear_carrier"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
+    android:minWidth="48dp"
     android:orientation="horizontal"
     android:gravity="center_vertical|start"
     android:background="@android:color/transparent"
diff --git a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
index e44fbcf..8878786 100644
--- a/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
+++ b/packages/SystemUI/res/layout/qs_paged_tile_layout.xml
@@ -18,7 +18,7 @@
 <com.android.systemui.qs.PagedTileLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="0dp"
     android:layout_weight="1"
     android:clipChildren="true"
     android:paddingBottom="@dimen/qs_paged_tile_layout_padding_bottom">
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index 29f53a4..79e2dfb 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -21,8 +21,8 @@
     android:layout_height="wrap_content"
     android:layout_marginTop="@dimen/qs_header_top_margin"
     android:layout_marginBottom="14dp"
-    android:layout_marginStart="@dimen/status_bar_padding_start"
-    android:layout_marginEnd="@dimen/status_bar_padding_end"
+    android:paddingStart="@dimen/status_bar_padding_start"
+    android:paddingEnd="@dimen/status_bar_padding_end"
     android:layout_below="@id/quick_status_bar_system_icons"
     android:clipChildren="false"
     android:clipToPadding="false"
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
index da640fd..37c6d9f 100644
--- a/packages/SystemUI/res/layout/quick_settings_header_info.xml
+++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml
@@ -19,7 +19,6 @@
     android:layout_width="match_parent"
     android:layout_height="@dimen/qs_header_tooltip_height"
     android:layout_below="@id/quick_status_bar_system_icons"
-    android:layout_marginTop="@dimen/qs_header_top_margin"
     android:paddingStart="@dimen/status_bar_padding_start"
     android:paddingEnd="@dimen/status_bar_padding_end">
 
@@ -27,7 +26,7 @@
         android:id="@+id/long_press_tooltip"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_gravity="start|bottom"
+        android:layout_gravity="start|center_vertical"
         android:alpha="0"
         android:text="@string/quick_settings_header_onboarding_text"
         android:textAppearance="@style/TextAppearance.QS.TileLabel"
@@ -36,34 +35,48 @@
 
     <LinearLayout
         android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="start|bottom"
+        android:layout_height="match_parent"
+        android:layout_gravity="start|center_vertical"
         android:gravity="center_vertical">
 
         <LinearLayout
             android:id="@+id/status_container"
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
+            android:layout_height="match_parent"
             android:layout_gravity="start|center_vertical"
             android:layout_weight="1"
             android:gravity="center_vertical"
-            android:alpha="0">
+            android:alpha="0" >
 
-            <ImageView
-                android:id="@+id/next_alarm_icon"
-                android:layout_width="@dimen/qs_header_alarm_icon_size"
-                android:layout_height="@dimen/qs_header_alarm_icon_size"
-                android:src="@drawable/stat_sys_alarm"
-                android:tint="?android:attr/textColorPrimary"
-                android:visibility="gone"/>
-
-            <TextView
-                android:id="@+id/next_alarm_text"
+            <LinearLayout
+                android:id = "@+id/alarm_container"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-                android:textAppearance="@style/TextAppearance.QS.Status"
-                android:visibility="gone"/>
+                android:layout_height="match_parent"
+                android:layout_gravity="center_vertical"
+                android:gravity="center_vertical"
+                android:focusable="true"
+                android:clickable="true">
+
+                <ImageView
+                    android:id="@+id/next_alarm_icon"
+                    android:layout_width="@dimen/qs_header_alarm_icon_size"
+                    android:layout_height="@dimen/qs_header_alarm_icon_size"
+                    android:src="@drawable/ic_alarm"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:contentDescription="@string/accessibility_quick_settings_alarm_set"
+                    android:visibility="gone"/>
+
+                <TextView
+                    android:id="@+id/next_alarm_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:marqueeRepeatLimit="marquee_forever"
+                    android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
+                    android:textAppearance="@style/TextAppearance.QS.Status"
+                    android:visibility="gone"/>
+            </LinearLayout>
 
             <View
                 android:id="@+id/status_separator"
@@ -71,20 +84,33 @@
                 android:layout_height="match_parent"
                 android:visibility="gone"/>
 
-            <ImageView
-                android:id="@+id/ringer_mode_icon"
-                android:layout_width="@dimen/qs_header_alarm_icon_size"
-                android:layout_height="@dimen/qs_header_alarm_icon_size"
-                android:tint="?android:attr/textColorPrimary"
-                android:visibility="gone"/>
-
-            <TextView
-                android:id="@+id/ringer_mode_text"
+            <LinearLayout
+                android:id = "@+id/ringer_container"
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-                android:textAppearance="@style/TextAppearance.QS.Status"
-                android:visibility="gone"/>
+                android:layout_height="match_parent"
+                android:layout_gravity="center_vertical"
+                android:gravity="center_vertical"
+                android:focusable="true"
+                android:clickable="true">
+
+                <ImageView
+                    android:id="@+id/ringer_mode_icon"
+                    android:layout_width="@dimen/qs_header_alarm_icon_size"
+                    android:layout_height="@dimen/qs_header_alarm_icon_size"
+                    android:tint="?android:attr/textColorPrimary"
+                    android:visibility="gone"/>
+
+                <TextView
+                    android:id="@+id/ringer_mode_text"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:ellipsize="marquee"
+                    android:marqueeRepeatLimit="marquee_forever"
+                    android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
+                    android:textAppearance="@style/TextAppearance.QS.Status"
+                    android:visibility="gone"/>
+            </LinearLayout>
         </LinearLayout>
 
         <View
@@ -93,11 +119,13 @@
             android:layout_height="match_parent"
             android:layout_weight="1"/>
 
+
         <include layout="@layout/qs_carrier_group"
                  android:id="@+id/carrier_group"
                  android:layout_width="wrap_content"
-                 android:layout_height="wrap_content"
-                 android_layout_gravity="center vertical|end"/>
+                 android:layout_height="match_parent"
+                 android:layout_gravity="end|center_vertical"
+                 android:focusable="false"/>
     </LinearLayout>
 
 </FrameLayout>
diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml
index e768939..90e78e8 100644
--- a/packages/SystemUI/res/values-land/dimens.xml
+++ b/packages/SystemUI/res/values-land/dimens.xml
@@ -24,8 +24,8 @@
 
     <dimen name="brightness_mirror_height">40dp</dimen>
 
-    <dimen name="qs_tile_margin_top">2dp</dimen>
-    <dimen name="qs_header_tooltip_height">24dp</dimen>
+    <dimen name="qs_tile_margin_top">8dp</dimen>
+    <dimen name="qs_tile_margin_vertical">0dp</dimen>
 
     <dimen name="battery_detail_graph_space_top">9dp</dimen>
     <dimen name="battery_detail_graph_space_bottom">9dp</dimen>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 5d8b9e6..7d76160 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -437,7 +437,7 @@
     <dimen name="qs_tile_padding_bottom">16dp</dimen>
     <dimen name="qs_tile_spacing">4dp</dimen>
     <dimen name="qs_panel_padding_bottom">0dp</dimen>
-    <dimen name="qs_panel_padding_top">30dp</dimen>
+    <dimen name="qs_panel_padding_top">@dimen/qs_header_tooltip_height</dimen>
     <dimen name="qs_detail_header_height">56dp</dimen>
     <dimen name="qs_detail_header_padding">0dp</dimen>
     <dimen name="qs_detail_image_width">56dp</dimen>
@@ -461,8 +461,8 @@
     <dimen name="qs_detail_item_icon_width">32dp</dimen>
     <dimen name="qs_detail_item_icon_marginStart">0dp</dimen>
     <dimen name="qs_detail_item_icon_marginEnd">20dp</dimen>
-    <dimen name="qs_header_tooltip_height">18dp</dimen>
-    <dimen name="qs_header_alarm_icon_size">18dp</dimen>
+    <dimen name="qs_header_tooltip_height">48dp</dimen>
+    <dimen name="qs_header_alarm_icon_size">@dimen/status_bar_icon_drawing_size</dimen>
     <dimen name="qs_header_mobile_icon_size">@dimen/status_bar_icon_drawing_size</dimen>
     <dimen name="qs_header_alarm_text_margin_start">6dp</dimen>
     <dimen name="qs_header_separator_width">8dp</dimen>
@@ -473,7 +473,7 @@
     <dimen name="qs_footer_padding_end">16dp</dimen>
     <dimen name="qs_footer_icon_size">16dp</dimen>
     <dimen name="qs_paged_tile_layout_padding_bottom">0dp</dimen>
-    <dimen name="qs_header_top_margin">12dp</dimen>
+    <dimen name="qs_header_top_margin">15dp</dimen>
 
     <dimen name="qs_notif_collapsed_space">64dp</dimen>
 
@@ -1031,8 +1031,6 @@
     <dimen name="ongoing_appops_dialog_title_size">20sp</dimen>
     <!-- Text size for Ongoing App Ops dialog items -->
     <dimen name="ongoing_appops_dialog_item_size">16sp</dimen>
-    <!-- Side margins around the Ongoing App Ops chip-->
-    <dimen name="ongoing_appops_chip_margin">0dp</dimen>
     <!-- Height of the Ongoing App Ops chip -->
     <dimen name="ongoing_appops_chip_height">32dp</dimen>
     <!-- Padding between background of Ongoing App Ops chip and content -->
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
index e7878c6..669348e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
@@ -117,6 +117,7 @@
             } else {
                 parent.addView(v);
             }
+            parent.setVisibility(View.VISIBLE);
         }
         updateSnapPosition();
         updateSeparatedButtonSize();
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
index 9c71ffc..6bc975a 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
@@ -41,6 +41,21 @@
     private static final String TAG = "ListGridLayout";
     private int mExpectedCount;
 
+    // number of rows and columns to use for different numbers of items
+    private final int[][] mConfigs = {
+            // {rows, columns}
+            {0, 0}, // 0 items
+            {1, 1}, // 1 item
+            {1, 2}, // 2 items
+            {1, 3}, // 3 items
+            {2, 2}, // 4 items
+            {2, 3}, // 5 items
+            {2, 3}, // 6 items
+            {3, 3}, // 7 items
+            {3, 3}, // 8 items
+            {3, 3}  // 9 items
+    };
+
     public ListGridLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
@@ -53,19 +68,28 @@
             ViewGroup subList = (ViewGroup) getChildAt(i);
             if (subList != null) {
                 subList.removeAllViews();
+                subList.setVisibility(View.GONE);
             }
         }
     }
 
     /**
      * Get the parent view associated with the item which should be placed at the given position.
+     * @param index The index of the item.
+     * @param reverseSublists Reverse the order of sublists. Ordinarily, sublists fill from first to
+     *                        last, whereas setting this to true will fill them last to first.
+     * @param swapRowsAndColumns Swap the order in which rows and columns are filled. By default,
+     *                           columns fill first, adding one item to each row. Setting this to
+     *                           true will cause rows to fill first, adding one item to each column.
+     * @return
      */
     public ViewGroup getParentView(int index, boolean reverseSublists, boolean swapRowsAndColumns) {
-        if (getRowCount() == 0) {
+        if (getRowCount() == 0 || index < 0) {
             return null;
         }
-        int column = getParentViewIndex(index, reverseSublists, swapRowsAndColumns);
-        return (ViewGroup) getChildAt(column);
+        int targetIndex = Math.min(index, getMaxElementCount() - 1);
+        int row = getParentViewIndex(targetIndex, reverseSublists, swapRowsAndColumns);
+        return (ViewGroup) getChildAt(row);
     }
 
     private int reverseSublistIndex(int index) {
@@ -74,7 +98,6 @@
 
     private int getParentViewIndex(int index, boolean reverseSublists, boolean swapRowsAndColumns) {
         int sublistIndex;
-        ViewGroup row;
         int rows = getRowCount();
         if (swapRowsAndColumns) {
             sublistIndex = (int) Math.floor(index / rows);
@@ -92,42 +115,31 @@
      */
     public void setExpectedCount(int count) {
         mExpectedCount = count;
-
-        for (int i = 0; i < getChildCount(); i++) {
-            if (i <= getColumnCount()) {
-                setSublistVisibility(i, true);
-            } else {
-                setSublistVisibility(i, false);
-            }
-        }
     }
 
-    private void setSublistVisibility(int index, boolean visible) {
-        View subList = getChildAt(index);
-        if (subList != null) {
-            subList.setVisibility(visible ? View.VISIBLE : View.GONE);
+    private int getMaxElementCount() {
+        return mConfigs.length - 1;
+    }
+
+    private int[] getConfig() {
+        if (mExpectedCount < 0) {
+            return mConfigs[0];
         }
+        int targetElements = Math.min(getMaxElementCount(), mExpectedCount);
+        return mConfigs[targetElements];
     }
 
     /**
      * Get the number of rows which will be used to render children.
      */
     public int getRowCount() {
-        // special case for 3 to use a single row
-        if (mExpectedCount == 3) {
-            return 1;
-        }
-        return (int) Math.round(Math.sqrt(mExpectedCount));
+        return getConfig()[0];
     }
 
     /**
      * Get the number of columns which will be used to render children.
      */
     public int getColumnCount() {
-        // special case for 3 to use a single row
-        if (mExpectedCount == 3) {
-            return 3;
-        }
-        return (int) Math.ceil(Math.sqrt(mExpectedCount));
+        return getConfig()[1];
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 6af7ac4..d363622 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -66,8 +66,6 @@
 import android.view.animation.Animation;
 import android.view.animation.AnimationUtils;
 
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.IKeyguardDrawnCallback;
 import com.android.internal.policy.IKeyguardExitCallback;
@@ -362,7 +360,6 @@
 
     private boolean mWakeAndUnlocking;
     private IKeyguardDrawnCallback mDrawnCallback;
-    private boolean mLockWhenSimRemoved;
     private CharSequence mCustomMessage;
 
     KeyguardUpdateMonitorCallback mUpdateCallback = new KeyguardUpdateMonitorCallback() {
@@ -465,7 +462,6 @@
                         if (simState == ABSENT) {
                             // MVNO SIMs can become transiently NOT_READY when switching networks,
                             // so we should only lock when they are ABSENT.
-                            onSimAbsentLocked();
                             if (simWasLocked) {
                                 if (DEBUG_SIM_STATES) Log.d(TAG, "SIM moved to ABSENT when the "
                                         + "previous state was locked. Reset the state.");
@@ -498,7 +494,6 @@
                                   + "show permanently disabled message in lockscreen.");
                             resetStateLocked();
                         }
-                        onSimAbsentLocked();
                     }
                     break;
                 case READY:
@@ -509,7 +504,6 @@
                                     + "previous state was locked. Reset the state.");
                             resetStateLocked();
                         }
-                        mLockWhenSimRemoved = true;
                     }
                     break;
                 default:
@@ -518,18 +512,6 @@
             }
         }
 
-        private void onSimAbsentLocked() {
-            if (isSecure() && mLockWhenSimRemoved && !mShuttingDown) {
-                mLockWhenSimRemoved = false;
-                MetricsLogger.action(mContext,
-                        MetricsProto.MetricsEvent.ACTION_LOCK_BECAUSE_SIM_REMOVED, mShowing);
-                if (!mShowing) {
-                    Log.i(TAG, "SIM removed, showing keyguard");
-                    doKeyguardLocked(null);
-                }
-            }
-        }
-
         @Override
         public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
             final int currentUser = KeyguardUpdateMonitor.getCurrentUser();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index ebc3a6a..e22a21a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -63,6 +63,7 @@
     private int mLayoutDirection;
     private int mHorizontalClipBound;
     private final Rect mClippingRect;
+    private int mLastMaxHeight = -1;
 
     public PagedTileLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -303,8 +304,11 @@
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 
         final int nTiles = mTiles.size();
-        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
+        // If we have no reason to recalculate the number of rows, skip this step. In particular,
+        // if the height passed by its parent is the same as the last time, we try not to remeasure.
+        if (mDistributeTiles || mLastMaxHeight != MeasureSpec.getSize(heightMeasureSpec)) {
 
+            mLastMaxHeight = MeasureSpec.getSize(heightMeasureSpec);
             // Only change the pages if the number of rows or columns (from updateResources) has
             // changed or the tiles have changed
             if (mPages.get(0).updateMaxRows(heightMeasureSpec, nTiles) || mDistributeTiles) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
index 7de8b74..e352b58 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroup.java
@@ -19,6 +19,8 @@
 import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
 
 import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
 import android.telephony.SubscriptionManager;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -30,6 +32,7 @@
 import com.android.keyguard.CarrierTextController;
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
+import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.statusbar.policy.NetworkController;
 
 import javax.inject.Inject;
@@ -40,7 +43,7 @@
  */
 public class QSCarrierGroup extends LinearLayout implements
         CarrierTextController.CarrierTextCallback,
-        NetworkController.SignalCallback {
+        NetworkController.SignalCallback, View.OnClickListener {
 
     private static final String TAG = "QSCarrierGroup";
     /**
@@ -53,20 +56,29 @@
     private QSCarrier[] mCarrierGroups = new QSCarrier[SIM_SLOTS];
     private final CellSignalState[] mInfos = new CellSignalState[SIM_SLOTS];
     private CarrierTextController mCarrierTextController;
+    private ActivityStarter mActivityStarter;
 
     private boolean mListening;
 
     @Inject
     public QSCarrierGroup(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
-            NetworkController networkController) {
+            NetworkController networkController, ActivityStarter activityStarter) {
         super(context, attrs);
         mNetworkController = networkController;
+        mActivityStarter = activityStarter;
     }
 
     @VisibleForTesting
     public QSCarrierGroup(Context context, AttributeSet attrs) {
         this(context, attrs,
-                Dependency.get(NetworkController.class));
+                Dependency.get(NetworkController.class),
+                Dependency.get(ActivityStarter.class));
+    }
+
+    @Override
+    public void onClick(View v) {
+        mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
+                Settings.ACTION_WIRELESS_SETTINGS), 0);
     }
 
     @Override
@@ -82,6 +94,7 @@
 
         for (int i = 0; i < SIM_SLOTS; i++) {
             mInfos[i] = new CellSignalState();
+            mCarrierGroups[i].setOnClickListener(this);
         }
 
         CharSequence separator = mContext.getString(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index dbd3042..f0413cd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -103,7 +103,9 @@
         if (navBelow) {
             maxQs -= getResources().getDimensionPixelSize(R.dimen.navigation_bar_height);
         }
-        mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.AT_MOST));
+        // Measure with EXACTLY. That way, PagedTileLayout will only use excess height and will be
+        // measured last, after other views and padding is accounted for.
+        mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(maxQs, MeasureSpec.EXACTLY));
         int width = mQSPanel.getMeasuredWidth();
         int height = layoutParams.topMargin + layoutParams.bottomMargin
                 + mQSPanel.getMeasuredHeight() + getPaddingBottom();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index d6e0306..fcaf981 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -128,6 +128,24 @@
         addView(mDivider);
     }
 
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        // We want all the logic of LinearLayout#onMeasure, and for it to assign the excess space
+        // not used by the other children to PagedTileLayout. However, in this case, LinearLayout
+        // assumes that PagedTileLayout would use all the excess space. This is not the case as
+        // PagedTileLayout height is quantized (because it shows a certain number of rows).
+        // Therefore, after everything is measured, we need to make sure that we add up the correct
+        // total height
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        int height = getPaddingBottom() + getPaddingTop();
+        int numChildren = getChildCount();
+        for (int i = 0; i < numChildren; i++) {
+            View child = getChildAt(i);
+            if (child.getVisibility() != View.GONE) height += child.getMeasuredHeight();
+        }
+        setMeasuredDimension(getMeasuredWidth(), height);
+    }
+
     public View getDivider() {
         return mDivider;
     }
@@ -282,6 +300,7 @@
     protected void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         mFooter.onConfigurationChanged();
+        updateResources();
 
         updateBrightnessMirror();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d789821..2e3065a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -35,6 +35,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.AlarmClock;
+import android.provider.Settings;
 import android.service.notification.ZenModeConfig;
 import android.text.format.DateUtils;
 import android.util.AttributeSet;
@@ -133,9 +134,11 @@
     private ImageView mNextAlarmIcon;
     /** {@link TextView} containing the actual text indicating when the next alarm will go off. */
     private TextView mNextAlarmTextView;
+    private View mNextAlarmContainer;
     private View mStatusSeparator;
     private ImageView mRingerModeIcon;
     private TextView mRingerModeTextView;
+    private View mRingerContainer;
     private Clock mClockView;
     private DateView mDateView;
     private OngoingPrivacyChip mPrivacyChip;
@@ -203,10 +206,14 @@
         mStatusSeparator = findViewById(R.id.status_separator);
         mNextAlarmIcon = findViewById(R.id.next_alarm_icon);
         mNextAlarmTextView = findViewById(R.id.next_alarm_text);
+        mNextAlarmContainer = findViewById(R.id.alarm_container);
+        mNextAlarmContainer.setOnClickListener(this::onClick);
         mRingerModeIcon = findViewById(R.id.ringer_mode_icon);
         mRingerModeTextView = findViewById(R.id.ringer_mode_text);
+        mRingerContainer = findViewById(R.id.ringer_container);
+        mRingerContainer.setOnClickListener(this::onClick);
         mPrivacyChip = findViewById(R.id.privacy_chip);
-        mPrivacyChip.setOnClickListener(this);
+        mPrivacyChip.setOnClickListener(this::onClick);
         mCarrierGroup = findViewById(R.id.carrier_group);
 
 
@@ -236,6 +243,8 @@
         // QS will always show the estimate, and BatteryMeterView handles the case where
         // it's unavailable or charging
         mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
+        mRingerModeTextView.setSelected(true);
+        mNextAlarmTextView.setSelected(true);
     }
 
     private List<String> getIgnoredIconSlots() {
@@ -285,11 +294,11 @@
         if (!ZenModeConfig.isZenOverridingRinger(mZenController.getZen(),
                 mZenController.getConsolidatedPolicy())) {
             if (mRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
-                mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_vibrate);
+                mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_vibrate);
                 mRingerModeTextView.setText(R.string.qs_status_phone_vibrate);
                 ringerVisible = true;
             } else if (mRingerMode == AudioManager.RINGER_MODE_SILENT) {
-                mRingerModeIcon.setImageResource(R.drawable.stat_sys_ringer_silent);
+                mRingerModeIcon.setImageResource(R.drawable.ic_volume_ringer_mute);
                 mRingerModeTextView.setText(R.string.qs_status_phone_muted);
                 ringerVisible = true;
             }
@@ -546,7 +555,7 @@
 
     @Override
     public void onClick(View v) {
-        if (v == mClockView) {
+        if (v == mClockView || v == mNextAlarmContainer) {
             mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
                     AlarmClock.ACTION_SHOW_ALARMS),0);
         } else if (v == mPrivacyChip) {
@@ -561,6 +570,9 @@
                         new Intent(Intent.ACTION_REVIEW_ONGOING_PERMISSION_USAGE), 0);
                 mHost.collapsePanels();
             });
+        } else if (v == mRingerContainer) {
+            mActivityStarter.postStartActivityDismissingKeyguard(new Intent(
+                    Settings.ACTION_SOUND_SETTINGS), 0);
         }
     }
 
@@ -573,7 +585,6 @@
     @Override
     public void onZenChanged(int zen) {
         updateStatusText();
-
     }
 
     @Override
@@ -731,8 +742,10 @@
     public void setMargins(int sideMargins) {
         for (int i = 0; i < getChildCount(); i++) {
             View v = getChildAt(i);
+            // Prevents these views from getting set a margin.
+            // The Icon views all have the same padding set in XML to be aligned.
             if (v == mSystemIconsView || v == mQuickQsStatusIcons || v == mHeaderQsPanel
-                    || v == mPrivacyChip) {
+                    || v == mHeaderTextContainerView) {
                 continue;
             }
             RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index 1dd729d..8aacd72 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -137,7 +137,8 @@
      * @param tilesCount Upper limit on the number of tiles to show. to prevent empty rows.
      */
     public boolean updateMaxRows(int heightMeasureSpec, int tilesCount) {
-        final int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mCellMarginTop;
+        final int availableHeight = MeasureSpec.getSize(heightMeasureSpec) - mCellMarginTop
+                + mCellMarginVertical;
         final int previousRows = mRows;
         mRows = availableHeight / (mCellHeight + mCellMarginVertical);
         if (mRows >= mMaxAllowedRows) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
index 8d2f895..f26a94f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/UiModeNightTile.java
@@ -81,6 +81,7 @@
         state.icon = mIcon;
         state.expandedAccessibilityClassName = Switch.class.getName();
         state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
+        state.showRippleEffect = false;
     }
 
     @Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java
new file mode 100644
index 0000000..26f1de8
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/ListGridLayoutTest.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2019 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 com.android.systemui.globalactions;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.testing.AndroidTestingRunner;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.R;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link ListGridLayout}.
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+public class ListGridLayoutTest extends SysuiTestCase {
+
+    private ListGridLayout mListGridLayout;
+
+    @Before
+    public void setUp() throws Exception {
+        GlobalActionsGridLayout globalActions = (GlobalActionsGridLayout)
+                LayoutInflater.from(mContext).inflate(R.layout.global_actions_grid, null);
+        mListGridLayout = globalActions.getListView();
+    }
+
+    @Test
+    public void testInflation() {
+        assertEquals(3, mListGridLayout.getChildCount());
+    }
+
+    @Test
+    public void testGetRowCount() {
+        // above expected range
+        mListGridLayout.setExpectedCount(99);
+        assertEquals(3, mListGridLayout.getRowCount());
+
+        mListGridLayout.setExpectedCount(9);
+        assertEquals(3, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(8);
+        assertEquals(3, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(7);
+        assertEquals(3, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(6);
+        assertEquals(2, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(5);
+        assertEquals(2, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(4);
+        assertEquals(2, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(3);
+        assertEquals(1, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(2);
+        assertEquals(1, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(1);
+        assertEquals(1, mListGridLayout.getRowCount());
+        mListGridLayout.setExpectedCount(0);
+        assertEquals(0, mListGridLayout.getRowCount());
+
+        // below expected range
+        mListGridLayout.setExpectedCount(-1);
+        assertEquals(0, mListGridLayout.getRowCount());
+    }
+
+    @Test
+    public void testGetColumnCount() {
+        // above expected range
+        mListGridLayout.setExpectedCount(99);
+
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(9);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(8);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(7);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(6);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(5);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(4);
+        assertEquals(2, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(3);
+        assertEquals(3, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(2);
+        assertEquals(2, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(1);
+        assertEquals(1, mListGridLayout.getColumnCount());
+        mListGridLayout.setExpectedCount(0);
+        assertEquals(0, mListGridLayout.getColumnCount());
+
+        // below expected range
+        mListGridLayout.setExpectedCount(-1);
+        assertEquals(0, mListGridLayout.getColumnCount());
+    }
+
+    @Test
+    public void testGetParentView_default() {
+        mListGridLayout.setExpectedCount(9);
+
+        // below valid range
+        assertEquals(null,
+                mListGridLayout.getParentView(-1, false, false));
+
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(0, false, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(1, false, false));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(2, false, false));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(3, false, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(4, false, false));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(5, false, false));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(6, false, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(7, false, false));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(8, false, false));
+
+        // above valid range
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(9, false, false));
+    }
+
+    @Test
+    public void testGetParentView_reverseSublists() {
+        mListGridLayout.setExpectedCount(9);
+
+        // below valid range
+        assertEquals(null,
+                mListGridLayout.getParentView(-1, true, false));
+
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(0, true, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(1, true, false));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(2, true, false));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(3, true, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(4, true, false));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(5, true, false));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(6, true, false));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(7, true, false));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(8, true, false));
+
+        // above valid range
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(9, true, false));
+    }
+
+    @Test
+    public void testGetParentView_swapRowsAndColumns() {
+        mListGridLayout.setExpectedCount(9);
+
+        // below valid range
+        assertEquals(null,
+                mListGridLayout.getParentView(-1, false, true));
+
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(0, false, true));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(1, false, true));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(2, false, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(3, false, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(4, false, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(5, false, true));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(6, false, true));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(7, false, true));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(8, false, true));
+
+        // above valid range
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(9, false, true));
+    }
+
+    @Test
+    public void testGetParentView_swapRowsAndColumnsAndReverseSublists() {
+        mListGridLayout.setExpectedCount(9);
+
+        // below valid range
+        assertEquals(null,
+                mListGridLayout.getParentView(-1, true, true));
+
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(0, true, true));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(1, true, true));
+        assertEquals(mListGridLayout.getChildAt(2),
+                mListGridLayout.getParentView(2, true, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(3, true, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(4, true, true));
+        assertEquals(mListGridLayout.getChildAt(1),
+                mListGridLayout.getParentView(5, true, true));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(6, true, true));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(7, true, true));
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(8, true, true));
+
+        // above valid range
+        assertEquals(mListGridLayout.getChildAt(0),
+                mListGridLayout.getParentView(9, true, true));
+    }
+
+    @Test
+    public void testRemoveAllItems() {
+        ViewGroup row1 = (ViewGroup) mListGridLayout.getChildAt(0);
+        ViewGroup row2 = (ViewGroup) mListGridLayout.getChildAt(1);
+        ViewGroup row3 = (ViewGroup) mListGridLayout.getChildAt(2);
+        View item1 = new View(mContext, null);
+        View item2 = new View(mContext, null);
+        View item3 = new View(mContext, null);
+
+        row1.addView(item1);
+        row2.addView(item2);
+        row3.addView(item3);
+
+        assertEquals(1, row1.getChildCount());
+        assertEquals(1, row2.getChildCount());
+        assertEquals(1, row3.getChildCount());
+
+        mListGridLayout.removeAllItems();
+
+        assertEquals(0, row1.getChildCount());
+        assertEquals(0, row2.getChildCount());
+        assertEquals(0, row2.getChildCount());
+    }
+}
diff --git a/services/core/java/com/android/server/am/EventLogTags.logtags b/services/core/java/com/android/server/am/EventLogTags.logtags
index e65a4e5..7c2ea3f 100644
--- a/services/core/java/com/android/server/am/EventLogTags.logtags
+++ b/services/core/java/com/android/server/am/EventLogTags.logtags
@@ -139,3 +139,8 @@
 
 # The task is being compacted
 30063 am_compact (Pid|1|5),(Process Name|3),(Action|3),(BeforeRssTotal|2|2),(BeforeRssFile|2|2),(BeforeRssAnon|2|2),(BeforeRssSwap|2|2),(DeltaRssTotal|2|2),(DeltaRssFile|2|2),(DeltaRssAnon|2|2),(DeltaRssSwap|2|2),(Time|2|3),(LastAction|1|2),(LastActionTimestamp|2|3),(setAdj|1|2),(procState|1|2),(BeforeZRAMFree|2|2),(DeltaZRAMFree|2|2)
+
+# The activity's onTopResumedActivityChanged(true) has been called.
+30064 am_on_top_resumed_gained_called (User|1|5),(Component Name|3),(Reason|3)
+# The activity's onTopResumedActivityChanged(false) has been called.
+30065 am_on_top_resumed_lost_called (User|1|5),(Component Name|3),(Reason|3)
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 1f5b99c..981e0f5 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -940,13 +940,34 @@
         }
     }
 
+    private void applyCustomPolicy(ZenPolicy policy, ZenRule rule) {
+        if (rule.zenMode == NotificationManager.INTERRUPTION_FILTER_NONE) {
+            policy.apply(new ZenPolicy.Builder()
+                    .disallowAllSounds()
+                    .build());
+        } else if (rule.zenMode
+                == NotificationManager.INTERRUPTION_FILTER_ALARMS) {
+            policy.apply(new ZenPolicy.Builder()
+                    .disallowAllSounds()
+                    .allowAlarms(true)
+                    .allowMedia(true)
+                    .build());
+        } else {
+            policy.apply(rule.zenPolicy);
+        }
+    }
+
     private void updateConsolidatedPolicy(String reason) {
         if (mConfig == null) return;
         synchronized (mConfig) {
             ZenPolicy policy = new ZenPolicy();
+            if (mConfig.manualRule != null) {
+                applyCustomPolicy(policy, mConfig.manualRule);
+            }
+
             for (ZenRule automaticRule : mConfig.automaticRules.values()) {
                 if (automaticRule.isAutomaticActive()) {
-                    policy.apply(automaticRule.zenPolicy);
+                    applyCustomPolicy(policy, automaticRule);
                 }
             }
             Policy newPolicy = mConfig.toNotificationPolicy(policy);
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index 2280d3f..05e9b93 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -1,14 +1,6 @@
 {
     "presubmit": [
         {
-            "name": "GtsPermissionTestCases",
-            "options": [
-                {
-                    "include-filter": "com.google.android.permission.gts.DefaultPermissionGrantPolicyTest"
-                }
-            ]
-        },
-        {
             "name": "CtsPermissionTestCases",
             "options": [
                 {
@@ -31,4 +23,4 @@
             ]
         }
     ]
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index 0ebd092..6ce42ec 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1132,7 +1132,7 @@
                 HashSet<Integer> skipRemainingWindowsForTasks = new HashSet<>();
 
                 // Iterate until we figure out what is touchable for the entire screen.
-                for (int i = visibleWindowCount - 1; i >= 0 && !unaccountedSpace.isEmpty(); i--) {
+                for (int i = visibleWindowCount - 1; i >= 0; i--) {
                     final WindowState windowState = visibleWindows.valueAt(i);
 
                     final Rect boundsInScreen = mTempRect;
@@ -1143,6 +1143,11 @@
                         addPopulatedWindowInfo(windowState, boundsInScreen, windows, addedWindows);
                         updateUnaccountedSpace(windowState, boundsInScreen, unaccountedSpace,
                                 skipRemainingWindowsForTasks);
+                        focusedWindowAdded |= windowState.isFocused();
+                    }
+
+                    if (unaccountedSpace.isEmpty() && focusedWindowAdded) {
+                        break;
                     }
                 }