Merge "Add ims registration status" into oc-mr1-dev-plus-aosp
diff --git a/api/test-current.txt b/api/test-current.txt
index f67e5cb..a0453d6 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -12093,6 +12093,18 @@
     ctor public SQLiteFullException(java.lang.String);
   }
 
+  public final class SQLiteGlobal {
+    method public static java.lang.String getDefaultJournalMode();
+    method public static int getDefaultPageSize();
+    method public static java.lang.String getDefaultSyncMode();
+    method public static int getIdleConnectionTimeout();
+    method public static int getJournalSizeLimit();
+    method public static int getWALAutoCheckpoint();
+    method public static int getWALConnectionPoolSize();
+    method public static java.lang.String getWALSyncMode();
+    method public static int releaseMemory();
+  }
+
   public class SQLiteMisuseException extends android.database.sqlite.SQLiteException {
     ctor public SQLiteMisuseException();
     ctor public SQLiteMisuseException(java.lang.String);
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 7fc79d7..a189e27 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -143,6 +143,11 @@
      * the PendingIntent. Use this method of scanning if your process is not always running and it
      * should be started when scan results are available.
      * <p>
+     * An app must hold
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission
+     * in order to get results.
+     * <p>
      * When the PendingIntent is delivered, the Intent passed to the receiver or activity
      * will contain one or more of the extras {@link #EXTRA_CALLBACK_TYPE},
      * {@link #EXTRA_ERROR_CODE} and {@link #EXTRA_LIST_SCAN_RESULT} to indicate the result of
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
index 571656a..94d5555 100644
--- a/core/java/android/database/sqlite/SQLiteGlobal.java
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -16,6 +16,7 @@
 
 package android.database.sqlite;
 
+import android.annotation.TestApi;
 import android.content.res.Resources;
 import android.os.StatFs;
 import android.os.SystemProperties;
@@ -34,6 +35,7 @@
  *
  * @hide
  */
+@TestApi
 public final class SQLiteGlobal {
     private static final String TAG = "SQLiteGlobal";
 
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 3b09c67..6d8a959 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -148,10 +148,12 @@
          * {@link android.view.autofill.AutofillManager#EXTRA_ASSIST_STRUCTURE screen
          * content} and your {@link android.view.autofill.AutofillManager#EXTRA_CLIENT_STATE
          * client state}. Once you complete your authentication flow you should set the
-         * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and provide the fully
-         * populated {@link FillResponse response} by setting it to the
-         * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra.
-         * For example, if you provided an empty {@link FillResponse resppnse} because the
+         * {@link Activity} result to {@link android.app.Activity#RESULT_OK} and set the
+         * {@link android.view.autofill.AutofillManager#EXTRA_AUTHENTICATION_RESULT} extra
+         * with the fully populated {@link FillResponse response} (or {@code null} if the screen
+         * cannot be autofilled).
+         *
+         * <p>For example, if you provided an empty {@link FillResponse response} because the
          * user's data was locked and marked that the response needs an authentication then
          * in the response returned if authentication succeeds you need to provide all
          * available data sets some of which may need to be further authenticated, for
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 829b2b7..a2147b7 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -804,8 +804,11 @@
     public static final int KEYCODE_SYSTEM_NAVIGATION_LEFT = 282;
     /** Key code constant: Consumed by the system for navigation right */
     public static final int KEYCODE_SYSTEM_NAVIGATION_RIGHT = 283;
+    /** Key code constant: Show all apps
+     * @hide */
+    public static final int KEYCODE_ALL_APPS = 284;
 
-    private static final int LAST_KEYCODE = KEYCODE_SYSTEM_NAVIGATION_RIGHT;
+    private static final int LAST_KEYCODE = KEYCODE_ALL_APPS;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index 36ab394..b22ce5e 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -53,8 +53,7 @@
 import android.widget.ImageView;
 
 public class PlatLogoActivity extends Activity {
-    public static final boolean REVEAL_THE_NAME = false;
-    public static final boolean FINISH = false;
+    public static final boolean FINISH = true;
 
     FrameLayout mLayout;
     int mTapCount;
@@ -85,15 +84,18 @@
         im.setAlpha(0f);
 
         im.setBackground(new RippleDrawable(
-                ColorStateList.valueOf(0xFFFFFFFF),
+                ColorStateList.valueOf(0xFF776677),
                 getDrawable(com.android.internal.R.drawable.platlogo),
                 null));
-//        im.setOutlineProvider(new ViewOutlineProvider() {
-//            @Override
-//            public void getOutline(View view, Outline outline) {
-//                outline.setOval(0, 0, view.getWidth(), view.getHeight());
-//            }
-//        });
+        im.setOutlineProvider(new ViewOutlineProvider() {
+            @Override
+            public void getOutline(View view, Outline outline) {
+                final int w = view.getWidth();
+                final int h = view.getHeight();
+                outline.setOval((int)(w*.125), (int)(h*.125), (int)(w*.96), (int)(h*.96));
+            }
+        });
+        im.setElevation(12f*dp);
         im.setClickable(true);
         im.setOnClickListener(new View.OnClickListener() {
             @Override
@@ -103,18 +105,6 @@
                     public boolean onLongClick(View v) {
                         if (mTapCount < 5) return false;
 
-                        if (REVEAL_THE_NAME) {
-                            final Drawable overlay = getDrawable(
-                                com.android.internal.R.drawable.platlogo_m);
-                            overlay.setBounds(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
-                            im.getOverlay().clear();
-                            im.getOverlay().add(overlay);
-                            overlay.setAlpha(0);
-                            ObjectAnimator.ofInt(overlay, "alpha", 0, 255)
-                                .setDuration(500)
-                                .start();
-                        }
-
                         final ContentResolver cr = getContentResolver();
                         if (Settings.System.getLong(cr, Settings.System.EGG_MODE, 0)
                                 == 0) {
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 0d962eb..969608b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1061,7 +1061,7 @@
         WindowManager.LayoutParams attrs = mWindow.getAttributes();
         int sysUiVisibility = attrs.systemUiVisibility | getWindowSystemUiVisibility();
 
-        if (!mWindow.mIsFloating && ActivityManager.isHighEndGfx()) {
+        if (!mWindow.mIsFloating) {
             boolean disallowAnimate = !isLaidOut();
             disallowAnimate |= ((mLastWindowFlags ^ attrs.flags)
                     & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0;
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 544afd9..57b0a73 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -2438,7 +2438,7 @@
 
         // Non-floating windows on high end devices must put up decor beneath the system bars and
         // therefore must know about visibility changes of those.
-        if (!mIsFloating && ActivityManager.isHighEndGfx()) {
+        if (!mIsFloating) {
             if (!targetPreL && a.getBoolean(
                     R.styleable.Window_windowDrawsSystemBarBackgrounds,
                     false)) {
diff --git a/core/java/com/android/internal/widget/NotificationExpandButton.java b/core/java/com/android/internal/widget/NotificationExpandButton.java
index b702898..39f82a5 100644
--- a/core/java/com/android/internal/widget/NotificationExpandButton.java
+++ b/core/java/com/android/internal/widget/NotificationExpandButton.java
@@ -31,7 +31,6 @@
  */
 @RemoteViews.RemoteView
 public class NotificationExpandButton extends ImageView {
-    private View mLabeledBy;
 
     public NotificationExpandButton(Context context) {
         super(context);
@@ -69,12 +68,5 @@
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
         info.setClassName(Button.class.getName());
-        if (mLabeledBy != null) {
-            info.setLabeledBy(mLabeledBy);
-        }
-    }
-
-    public void setLabeledBy(View labeledBy) {
-        mLabeledBy = labeledBy;
     }
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 89bbec2..031c3f5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -309,6 +309,10 @@
     <protected-broadcast android:name="com.android.server.usb.ACTION_OPEN_IN_APPS" />
     <protected-broadcast android:name="com.android.server.am.DELETE_DUMPHEAP" />
     <protected-broadcast android:name="com.android.server.net.action.SNOOZE_WARNING" />
+    <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.USER_DISMISSED_NOTIFICATION" />
+    <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.CONNECT_TO_NETWORK" />
+    <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.PICK_WIFI_NETWORK" />
+    <protected-broadcast android:name="com.android.server.wifi.ConnectToNetworkNotification.PICK_NETWORK_AFTER_FAILURE" />
     <protected-broadcast android:name="android.net.wifi.WIFI_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_AP_STATE_CHANGED" />
     <protected-broadcast android:name="android.net.wifi.WIFI_CREDENTIAL_CHANGED" />
diff --git a/core/res/res/drawable-nodpi/platlogo.xml b/core/res/res/drawable-nodpi/platlogo.xml
index 182ba24..a6dee8a 100644
--- a/core/res/res/drawable-nodpi/platlogo.xml
+++ b/core/res/res/drawable-nodpi/platlogo.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2017 The Android Open Source Project
 
@@ -14,27 +15,35 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="480dp"
-        android:height="480dp"
-        android:viewportWidth="48.0"
-        android:viewportHeight="48.0">
-    <path
-        android:pathData="M25.0,25.0m-20.5,0.0a20.5,20.5,0,1,1,41.0,0.0a20.5,20.5,0,1,1,-41.0,0.0"
-        android:fillAlpha="0.066"
-        android:fillColor="#000000"/>
-    <path
-        android:pathData="M24.0,24.0m-20.0,0.0a20.0,20.0,0,1,1,40.0,0.0a20.0,20.0,0,1,1,-40.0,0.0"
-        android:fillColor="#FFC107"/>
-    <path
-        android:pathData="M44,24.2010101 L33.9004889,14.101499 L14.101499,33.9004889 L24.2010101,44 C29.2525804,43.9497929 34.2887564,41.9975027 38.1431296,38.1431296 C41.9975027,34.2887564 43.9497929,29.2525804 44,24.2010101 Z"
-        android:fillColor="#FE9F00"/>
-    <path
-        android:pathData="M24.0,24.0m-14.0,0.0a14.0,14.0,0,1,1,28.0,0.0a14.0,14.0,0,1,1,-28.0,0.0"
-        android:fillColor="#FED44F"/>
-    <path
-        android:pathData="M37.7829445,26.469236 L29.6578482,18.3441397 L18.3441397,29.6578482 L26.469236,37.7829445 C29.1911841,37.2979273 31.7972024,36.0037754 33.9004889,33.9004889 C36.0037754,31.7972024 37.2979273,29.1911841 37.7829445,26.469236 Z"
-        android:fillColor="#FFC107"/>
-    <path
-        android:pathData="M24.0,24.0m-8.0,0.0a8.0,8.0,0,1,1,16.0,0.0a8.0,8.0,0,1,1,-16.0,0.0"
-        android:fillColor="#FFFFFF"/>
+    android:width="48dp"
+    android:height="48dp"
+    android:viewportWidth="48"
+    android:viewportHeight="48">
+    <group>
+        <path
+            android:fillColor="#2C292A"
+            android:fillType="evenOdd"
+            android:pathData="M6,26a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+        <path
+            android:fillColor="#FAFAFA"
+            android:fillType="evenOdd"
+            android:pathData="M4,24a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+        <path
+            android:fillColor="#2C292A"
+            android:fillType="evenOdd"
+            android:pathData="M2,22a20,20 0 0,1 40,0a20,20 0 0,1 -40,0z"/>
+        <path
+            android:fillColor="#00000000"
+            android:strokeColor="#453F41"
+            android:strokeWidth="1"
+            android:fillType="evenOdd"
+            android:pathData="M26.5 29.5v3c0 1.13-.87 2-2 2s-2-.87-2-2v-3h-1v3c0 1.13-.87 2-2 2s-2-.87-2-2v-3H17a1.5 1.5 0 0 1-1.5-1.5V17.5h13V28a1.5 1.5 0 0 1-1.5 1.5h-.5zM13.5 17.5c1.13 0 2 .87 2 2v7c0 1.13-.87 2-2 2s-2-.87-2-2v-7c0-1.13.87-2 2-2zM30.5 17.5c1.13 0 2 .87 2 2v7c0 1.13-.87 2-2 2s-2-.87-2-2v-7c0-1.13.87-2 2-2zM26.3 12.11A6.46 6.46 0 0 1 28.5 17v.5h-13V17a6.46 6.46 0 0 1 2.2-4.89l-.9-.9a.98.98 0 0 1 0-1.41.98.98 0 0 1 1.4 0l1.26 1.25A6.33 6.33 0 0 1 22 10.5c.87 0 1.73.2 2.54.55L25.8 9.8a.98.98 0 0 1 1.4 0 .98.98 0 0 1 0 1.4l-.9.91z"/>
+        <path
+            android:fillColor="#453F41"
+            android:fillType="evenOdd"
+            android:pathData="M20.16 14.5a.66.66 0 1 1-1.31 0c0-.36.29-.65.65-.65.36 0 .65.29.65.65zM25.16 14.5c0 .36-.3.66-.66.66a.65.65 0 1 1 .66-.66z"/>
+        <path
+            android:fillColor="#453F41"
+            android:pathData="M22 40.5c0.36 0 0.73-0.01 1.09-0.03l-0.18-3A15.77 15.77 0 0 1 22 37.5v3zm2.17-0.13a18.48 18.48 0 0 0 1.08-0.15l-0.53-2.96c-0.3 0.05-0.6 0.1-0.9 0.13l0.35 2.98zM26.32 40a18.37 18.37 0 0 0 1.05-0.28l-0.87-2.87a15.37 15.37 0 0 1-0.88 0.23l0.7 2.92zm2.1-0.64l-1.03-2.81a15.39 15.39 0 0 0 0.84-0.34l1.2 2.74a18.39 18.39 0 0 1-1 0.41zm1.99-0.87l-1.37-2.67a15.46 15.46 0 0 0 0.8-0.44l1.52 2.59a18.46 18.46 0 0 1-0.95 0.52zm1.89-1.11l-1.67-2.5a15.55 15.55 0 0 0 0.74-0.52l1.81 2.39a18.55 18.55 0 0 1-0.88 0.63zm1.75-1.33l-1.95-2.28a15.6 15.6 0 0 0 0.67-0.61l2.09 2.15a18.6 18.6 0 0 1-0.8 0.74zm1.6-1.55l-2.22-2.02a15.6 15.6 0 0 0 0.6-0.7l2.33 1.9a18.6 18.6 0 0 1-0.72 0.82zM37 32.82l-2.43-1.76a15.53 15.53 0 0 0 0.5-0.75l2.54 1.6c-0.2 0.31-0.4 0.61-0.61 0.9zm1.15-1.8l-2.62-1.47a15.45 15.45 0 0 0 0.42-0.8l2.7 1.3a18.45 18.45 0 0 1-0.5 0.97zm0.95-1.98l-2.77-1.14a15.38 15.38 0 0 0 0.32-0.86l2.84 0.98a18.38 18.38 0 0 1-0.39 1.02zm0.72-2.09c0.1-0.34 0.18-0.7 0.26-1.05l-2.93-0.63a15.38 15.38 0 0 1-0.22 0.88l2.89 0.8zm0.46-2.15a18.52 18.52 0 0 0 0.13-1.08l-2.99-0.28a15.52 15.52 0 0 1-0.1 0.9l2.96 0.46zm0.2-2.2a18.81 18.81 0 0 0 0-1.1l-3 0.08a16 16 0 0 1 0 0.92l3 0.1zm-0.06-2.2a18.54 18.54 0 0 0-0.12-1.07l-2.97 0.43c0.04 0.3 0.08 0.6 0.1 0.9l3-0.25zm-0.31-2.15a18.39 18.39 0 0 0-0.25-1.06l-2.9 0.78a15.39 15.39 0 0 1 0.21 0.89l2.94-0.6zm-0.57-2.12l-2.85 0.95a15.37 15.37 0 0 0-0.31-0.85l2.78-1.12a18.37 18.37 0 0 1 0.38 1.02zm-0.83-2.06l-2.71 1.29a15.44 15.44 0 0 0-0.42-0.81l2.63-1.45a18.44 18.44 0 0 1 0.5 0.97zm-1.03-1.88l-2.54 1.6a15.53 15.53 0 0 0-0.5-0.76l2.44-1.74 0.6 0.9zm-1.28-1.79l-2.33 1.88a15.6 15.6 0 0 0-0.6-0.69l2.23-2.02a18.6 18.6 0 0 1 0.7 0.83zm-1.48-1.63l-2.1 2.14a15.6 15.6 0 0 0-0.67-0.62l1.97-2.26a18.6 18.6 0 0 1 0.8 0.74zM33.24 7.3l-1.82 2.38a15.55 15.55 0 0 0-0.74-0.53l1.68-2.49c0.3 0.2 0.6 0.42 0.88 0.64zm-1.71-1.17L29.98 8.7a15.47 15.47 0 0 0-0.8-0.45l1.4-2.66a18.47 18.47 0 0 1 0.95 0.54zm-1.95-1.02l-1.23 2.74A15.4 15.4 0 0 0 27.5 7.5l1.06-2.8a18.4 18.4 0 0 1 1.01 0.4zm-2.06-0.78l-0.9 2.86a15.37 15.37 0 0 0-0.87-0.24l0.72-2.92a18.37 18.37 0 0 1 1.05 0.3zM25.38 3.8a18.47 18.47 0 0 0-1.08-0.17l-0.37 2.98c0.3 0.04 0.6 0.08 0.9 0.14l0.55-2.95zm-2.2-0.27A18.75 18.75 0 0 0 22.1 3.5l-0.02 3L23 6.53l0.19-3zM21 3.53a18.6 18.6 0 0 0-1.08 0.09l0.33 2.98a15.6 15.6 0 0 1 0.91-0.08l-0.16-3zm-2.16 0.24A18.4 18.4 0 0 0 17.76 4l0.68 2.92a15.4 15.4 0 0 1 0.9-0.18l-0.51-2.96zm-2.14 0.5l0.86 2.88a15.37 15.37 0 0 0-0.86 0.28l-1.03-2.81a18.37 18.37 0 0 1 1.03-0.35zm-2.07 0.76l1.2 2.75a15.42 15.42 0 0 0-0.83 0.4L13.63 5.5a18.42 18.42 0 0 1 0.99-0.47zM12.7 6l1.5 2.6a15.5 15.5 0 0 0-0.76 0.48l-1.66-2.5A18.5 18.5 0 0 1 12.7 6zm-1.83 1.22l1.8 2.4a15.58 15.58 0 0 0-0.7 0.57L10.01 7.9a18.58 18.58 0 0 1 0.85-0.68zM9.19 8.66l2.07 2.16a15.6 15.6 0 0 0-0.63 0.65l-2.2-2.04a18.6 18.6 0 0 1 0.76-0.77zm-1.51 1.63l2.32 1.9a15.57 15.57 0 0 0-0.56 0.72l-2.42-1.76a18.57 18.57 0 0 1 0.66-0.86zm-1.23 1.69l2.52 1.62a15.5 15.5 0 0 0-0.47 0.78l-2.61-1.47a18.5 18.5 0 0 1 0.56-0.93zm-1.08 1.9l2.7 1.32a15.41 15.41 0 0 0-0.38 0.83l-2.77-1.15a18.41 18.41 0 0 1 0.45-1zm-0.85 2.04l2.84 0.98a15.37 15.37 0 0 0-0.28 0.87L4.2 16.96c0.1-0.35 0.2-0.7 0.32-1.04zm-0.6 2.12a18.43 18.43 0 0 0-0.2 1.07l2.97 0.47c0.05-0.3 0.1-0.6 0.17-0.9l-2.93-0.64zm-0.34 2.18a18.65 18.65 0 0 0-0.07 1.09l3 0.11 0.06-0.91-2.99-0.29zm-0.08 2.2a18.7 18.7 0 0 0 0.06 1.1l3-0.25a15.7 15.7 0 0 1-0.06-0.91l-3 0.07zm0.18 2.18a18.44 18.44 0 0 0 0.18 1.07l2.95-0.6a15.44 15.44 0 0 1-0.16-0.9L3.68 24.6zm0.43 2.14l2.9-0.77a15.37 15.37 0 0 0 0.26 0.88l-2.85 0.94a18.37 18.37 0 0 1-0.3-1.05zm0.7 2.1l2.78-1.11a15.4 15.4 0 0 0 0.36 0.83l-2.71 1.27a18.4 18.4 0 0 1-0.44-1zm0.9 1.95l2.65-1.43a15.48 15.48 0 0 0 0.45 0.8l-2.55 1.57a18.48 18.48 0 0 1-0.54-0.94zm1.17 1.87l2.45-1.73a15.56 15.56 0 0 0 0.54 0.73l-2.34 1.87a18.56 18.56 0 0 1-0.65-0.87zm1.37 1.72l2.23-2a15.6 15.6 0 0 0 0.63 0.65l-2.1 2.14a18.6 18.6 0 0 1-0.76-0.79zm1.58 1.56l1.98-2.26c0.22 0.2 0.46 0.39 0.7 0.58l-1.84 2.37a18.59 18.59 0 0 1-0.84-0.7zm1.66 1.28l1.7-2.46a15.52 15.52 0 0 0 0.77 0.5l-1.56 2.56a18.52 18.52 0 0 1-0.91-0.6zm1.87 1.14l1.4-2.65a15.43 15.43 0 0 0 0.82 0.4l-1.24 2.73a18.43 18.43 0 0 1-0.98-0.48zm2 0.91l1.08-2.8a15.37 15.37 0 0 0 0.86 0.3l-0.9 2.86a18.37 18.37 0 0 1-1.04-0.36zm2.1 0.67a18.4 18.4 0 0 0 1.07 0.23l0.56-2.94a15.4 15.4 0 0 1-0.9-0.2l-0.72 2.91zm2.18 0.41a18.57 18.57 0 0 0 1.08 0.1l0.2-2.99a15.57 15.57 0 0 1-0.9-0.09l-0.38 2.98zm2.2 0.15H22v-3h-0.13l-0.03 3z"/>
+    </group>
 </vector>
diff --git a/core/res/res/drawable-nodpi/platlogo_m.xml b/core/res/res/drawable-nodpi/platlogo_m.xml
index d9a558d..aacf674 100644
--- a/core/res/res/drawable-nodpi/platlogo_m.xml
+++ b/core/res/res/drawable-nodpi/platlogo_m.xml
@@ -1,5 +1,5 @@
 <!--
-Copyright (C) 2016 The Android Open Source Project
+Copyright (C) 2017 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.
@@ -14,59 +14,27 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
+        android:width="480dp"
+        android:height="480dp"
         android:viewportWidth="48.0"
         android:viewportHeight="48.0">
+    <!--<path
+        android:pathData="M25.0,25.0m-20.5,0.0a20.5,20.5,0,1,1,41.0,0.0a20.5,20.5,0,1,1,-41.0,0.0"
+        android:fillAlpha="0.066"
+        android:fillColor="#000000"/>-->
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M33.8,38l-25.5,-25.5l-1.7000003,0.6999998l25.499998,25.5z"/>
+        android:pathData="M24.0,24.0m-20.0,0.0a20.0,20.0,0,1,1,40.0,0.0a20.0,20.0,0,1,1,-40.0,0.0"
+        android:fillColor="#FFC107"/>
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M40.8,34.8l-25.4,-25.5l-1.6999998,0.6999998l25.5,25.5z"/>
+        android:pathData="M44,24.2010101 L33.9004889,14.101499 L14.101499,33.9004889 L24.2010101,44 C29.2525804,43.9497929 34.2887564,41.9975027 38.1431296,38.1431296 C41.9975027,34.2887564 43.9497929,29.2525804 44,24.2010101 Z"
+        android:fillColor="#FE9F00"/>
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M11.1,13.1l-0.3,-0.4l1.1,-1.3l0,0l-1.6,0.8l-0.4,-0.4l2.6,-1.2l0.4,0.4l-1.1,1.3l0,0l1.6,-0.8l0.3,0.4L11.1,13.1z"/>
+        android:pathData="M24.0,24.0m-14.0,0.0a14.0,14.0,0,1,1,28.0,0.0a14.0,14.0,0,1,1,-28.0,0.0"
+        android:fillColor="#FED44F"/>
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M13,14.2l-0.5,-0.5l-0.6,0.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L13,14.2z M13,13.6l0.3,0.3l0.8,-0.6   l0,0L13,13.6z"/>
+        android:pathData="M37.7829445,26.469236 L29.6578482,18.3441397 L18.3441397,29.6578482 L26.469236,37.7829445 C29.1911841,37.2979273 31.7972024,36.0037754 33.9004889,33.9004889 C36.0037754,31.7972024 37.2979273,29.1911841 37.7829445,26.469236 Z"
+        android:fillColor="#FFC107"/>
     <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M16.3,14.6l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.7,-0.3l1,-0.4l0,0l-2.1,0.5L13.9,16l1.4,-1.1l0,0   l-0.9,0.5l-0.7,0.3l-0.3,-0.4l2.6,-1.2L16.3,14.6z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M17.4,17.8l-0.6,-0.6l-0.7,0.3l0.7,0.7l-0.4,0.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7L17.2,17l0.6,0.6L17.4,17.8   z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M18.8,18.7L18.8,18.7l1.3,-0.2l0.4,0.4l-2.1,0.3l-0.9,0.4l-0.3,-0.4l1,-0.4l1.2,-1.2l0.4,0.4L18.8,18.7z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M22.2,20.5l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.7,-0.3l1,-0.4l0,0L20,22.1l-0.2,-0.2l1.4,-1.1l0,0   l-0.9,0.5l-0.7,0.3l-0.3,-0.4l2.6,-1.2L22.2,20.5z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M22,23.6c0,0,0.1,0.1,0.2,0.1c0.1,0,0.2,0,0.3,-0.1l0.3,0.3c-0.2,0.1,-0.4,0.1,-0.6,0.1c-0.2,0,-0.4,-0.1,-0.5,-0.2   c-0.2,-0.2,-0.2,-0.3,-0.1,-0.5c0.1,-0.2,0.2,-0.3,0.5,-0.4l0.2,-0.1c0.3,-0.1,0.5,-0.2,0.8,-0.2c0.2,0,0.5,0.1,0.6,0.3   c0.1,0.1,0.2,0.3,0.1,0.4c0,0.1,-0.2,0.3,-0.4,0.4L23,23.4c0.1,0,0.2,-0.1,0.2,-0.2c0,-0.1,0,-0.1,0,-0.2C23.1,23,23,22.9,22.9,23   c-0.1,0,-0.2,0.1,-0.4,0.1l-0.2,0.1c-0.2,0.1,-0.3,0.1,-0.3,0.2C21.9,23.5,21.9,23.5,22,23.6z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M23.8,25.9l-0.3,-0.4l1.1,-1.3l0,0L22.9,25l-0.4,-0.4l2.6,-1.2l0.4,0.4l-1.1,1.3l0,0l1.6,-0.8l0.3,0.4L23.8,25.9z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M25.7,27l-0.5,-0.5l-0.6,0.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L25.7,27z M25.7,26.4l0.3,0.3l0.8,-0.6   l0,0L25.7,26.4z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M29,27.4l-1.6,1.2l0,0l2.2,-0.6l0.5,0.5l-2.6,1.2l-0.3,-0.4l0.8,-0.3l1,-0.4l0,0L26.8,29l-0.2,-0.2l1.4,-1.1l0,0   L27,28.1l-0.8,0.3l-0.3,-0.4l2.6,-1.2L29,27.4z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M30,30.6L29.5,30l-0.7,0.3l0.7,0.7L29,31.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7l-0.6,0.3l0.6,0.6L30,30.6z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M31.5,32.1l-0.6,-0.6L29.8,32l-0.4,-0.4l2.6,-1.2l1,1l-0.4,0.2L32,31l-0.7,0.3l0.6,0.6L31.5,32.1z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M32,33.5L31.6,33L31,33.2l-0.4,-0.4l3.1,-0.7l0.4,0.4l-2.1,1.7l-0.4,-0.4L32,33.5z M32.1,32.9l0.3,0.3l0.8,-0.6   l0,0L32.1,32.9z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M34.3,35.3c-0.3,0.1,-0.5,0.2,-0.8,0.1c-0.2,0,-0.5,-0.1,-0.6,-0.3c-0.2,-0.2,-0.2,-0.4,-0.2,-0.5   c0.1,-0.2,0.2,-0.3,0.6,-0.5l0.8,-0.4c0.3,-0.1,0.6,-0.2,0.9,-0.2c0.3,0,0.5,0.1,0.7,0.3c0.2,0.2,0.3,0.4,0.2,0.5c0,0.2,-0.2,0.3,-0.5,0.5   l-0.3,-0.4c0.2,-0.1,0.3,-0.1,0.3,-0.2c0,-0.1,0,-0.1,-0.1,-0.2C35,34,34.9,34,34.8,34c-0.1,0,-0.3,0,-0.5,0.1l-0.8,0.4   c-0.2,0.1,-0.3,0.2,-0.4,0.2c0,0.1,0,0.1,0,0.2c0.1,0.1,0.2,0.1,0.3,0.1c0.1,0,0.2,0,0.4,-0.1L34.3,35.3z"/>
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M36,36.6L35.4,36l-0.7,0.3l0.7,0.7l-0.4,0.2l-1,-1l2.6,-1.2l1,1l-0.4,0.2l-0.7,-0.7l-0.6,0.3l0.6,0.6L36,36.6z"/>
+        android:pathData="M24.0,24.0m-8.0,0.0a8.0,8.0,0,1,1,16.0,0.0a8.0,8.0,0,1,1,-16.0,0.0"
+        android:fillColor="#FFFFFF"/>
 </vector>
diff --git a/core/res/res/drawable-nodpi/stat_sys_adb.xml b/core/res/res/drawable-nodpi/stat_sys_adb.xml
index 89e42e6..2e2b395 100644
--- a/core/res/res/drawable-nodpi/stat_sys_adb.xml
+++ b/core/res/res/drawable-nodpi/stat_sys_adb.xml
@@ -1,3 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
 <!--
 Copyright (C) 2017 The Android Open Source Project
 
@@ -14,19 +15,23 @@
     limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="24dp"
-        android:height="24dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M12.0,12.0m-10.0,0.0a10.0,10.0,0,1,1,20.0,0.0a10.0,10.0,0,1,1,-20.0,0.0"
-        android:fillAlpha="0.25"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M12,22 C6.4771525,22 2,17.5228475 2,12 C2,6.4771525 6.4771525,2 12,2 C17.5228475,2 22,6.4771525 22,12 C22,17.5228475 17.5228475,22 12,22 Z M12,18.5 C15.5898509,18.5 18.5,15.5898509 18.5,12 C18.5,8.41014913 15.5898509,5.5 12,5.5 C8.41014913,5.5 5.5,8.41014913 5.5,12 C5.5,15.5898509 8.41014913,18.5 12,18.5 Z"/>
-    <path
-        android:fillColor="#FF000000"
-        android:pathData="M12,18.5 C8.41014913,18.5 5.5,15.5898509 5.5,12 C5.5,8.41014913 8.41014913,5.5 12,5.5 C15.5898509,5.5 18.5,8.41014913 18.5,12 C18.5,15.5898509 15.5898509,18.5 12,18.5 Z M12,15 C13.6568542,15 15,13.6568542 15,12 C15,10.3431458 13.6568542,9 12,9 C10.3431458,9 9,10.3431458 9,12 C9,13.6568542 10.3431458,15 12,15 Z"
-        android:fillAlpha="0.25"/>
-</vector>
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <group>
+        <path
+            android:fillColor="#FFFFFF"
+            android:fillAlpha=".33"
+            android:fillType="evenOdd"
+            android:pathData="M5.71 18.29A8.99 8.99 0 0 0 22 13c0-3-1.46-5.65-3.71-7.29A8.99 8.99 0 0 0 2 11c0 3 1.46 5.65 3.71 7.29z"/>
+        <path
+            android:fillColor="#FFFFFF"
+            android:fillType="evenOdd"
+            android:pathData="M7.25 19.18A8.5 8.5 0 0 0 19.19 7.24 9 9 0 0 1 7.24 19.19z"/>
+        <path
+            android:fillColor="#FFFFFF"
+            android:fillAlpha=".33"
+            android:pathData="M10.5 3a0.5 0.5 0 1 1 1 0v2.05a0.5 0.5 0 1 1-1 0V3zm3.1 0.42a0.5 0.5 0 0 1 0.93 0.39l-0.8 1.88A0.5 0.5 0 1 1 12.8 5.3l0.8-1.88zm2.7 1.57a0.5 0.5 0 1 1 0.71 0.7l-1.45 1.46a0.5 0.5 0 0 1-0.7-0.71l1.44-1.45zm1.9 2.5a0.5 0.5 0 0 1 0.38 0.92l-1.9 0.77a0.5 0.5 0 0 1-0.37-0.93l1.9-0.77zM19 10.5a0.5 0.5 0 1 1 0 1h-2.05a0.5 0.5 0 0 1 0-1H19zm-0.42 3.1a0.5 0.5 0 0 1-0.39 0.93l-1.88-0.8a0.5 0.5 0 1 1 0.39-0.92l1.88 0.8zm-1.57 2.7a0.5 0.5 0 1 1-0.7 0.71l-1.46-1.45a0.5 0.5 0 0 1 0.71-0.7l1.45 1.44zm-2.5 1.9a0.5 0.5 0 1 1-0.92 0.38l-0.77-1.9a0.5 0.5 0 0 1 0.93-0.37l0.77 1.9zM11.5 19a0.5 0.5 0 1 1-1 0v-2.05a0.5 0.5 0 0 1 1 0V19zm-3.1-0.42a0.5 0.5 0 0 1-0.93-0.39l0.8-1.88A0.5 0.5 0 0 1 9.2 16.7l-0.8 1.88zm-2.7-1.57a0.5 0.5 0 1 1-0.71-0.7l1.45-1.46a0.5 0.5 0 0 1 0.7 0.71L5.7 17.01zm-1.9-2.48a0.5 0.5 0 0 1-0.38-0.92l1.88-0.8a0.5 0.5 0 0 1 0.4 0.92l-1.9 0.8zM3 11.5a0.5 0.5 0 1 1 0-1h2.05a0.5 0.5 0 1 1 0 1H3zm0.42-3.1A0.5 0.5 0 0 1 3.8 7.46l1.88 0.8A0.5 0.5 0 1 1 5.3 9.2L3.42 8.4zm1.57-2.7a0.5 0.5 0 1 1 0.7-0.71l1.46 1.45a0.5 0.5 0 0 1-0.71 0.7L4.99 5.7zm2.5-1.9A0.5 0.5 0 0 1 8.4 3.41l0.77 1.9a0.5 0.5 0 0 1-0.93 0.37L7.48 3.8z"/>
+    </group>
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8151ceb..12d707b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1891,6 +1891,7 @@
         <enum name="KEYCODE_SYSTEM_NAVIGATION_DOWN" value="281" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_LEFT" value="282" />
         <enum name="KEYCODE_SYSTEM_NAVIGATION_RIGHT" value="283" />
+        <enum name="KEYCODE_ALL_APPS" value="284" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
index c9db034..6156692 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTestSuite.java
@@ -23,6 +23,7 @@
         TestSuite suite =
           new TestSuite(NewDatabasePerformanceTestSuite.class.getName());
 
+        suite.addTestSuite(NewDatabasePerformanceTests.CreateTable100.class);
         suite.addTestSuite(NewDatabasePerformanceTests.Insert100.class);
         suite.addTestSuite(NewDatabasePerformanceTests.InsertIndexed100.class);
         suite.addTestSuite(NewDatabasePerformanceTests.Select100.class);
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index f8d8e5e..bcd9060 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -34,8 +34,9 @@
 public class NewDatabasePerformanceTests {
     private static final String TAG = "NewDatabasePerformanceTests";
 
-    // Edit this to change the test run times.  The original is 100.
-    private static final int SIZE_MULTIPLIER = 100;
+    private static final int DATASET_SIZE = 100; // Size of dataset to use for testing
+    private static final int FAST_OP_MULTIPLIER = 25;
+    private static final int FAST_OP_COUNT = FAST_OP_MULTIPLIER * DATASET_SIZE;
 
     public static class PerformanceBase extends TestCase
     implements PerformanceTestCase {
@@ -50,16 +51,21 @@
             if (mDatabaseFile.exists()) {
                 mDatabaseFile.delete();
             }
-            mDatabase =
-                    SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(),
-                            null);
+            mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
             assertTrue(mDatabase != null);
             mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+            mDatabase.beginTransactionNonExclusive();
+            prepareForTest();
+            mDatabase.setTransactionSuccessful();
+            mDatabase.endTransaction();
             mSetupFinishedTime = System.currentTimeMillis();
             Log.i(TAG, "Setup for " + getClass().getSimpleName() + " took "
                     + (mSetupFinishedTime - setupStarted) + " ms");
         }
 
+        protected void prepareForTest() {
+        }
+
         public void tearDown() {
             long duration = System.currentTimeMillis() - mSetupFinishedTime;
             Log.i(TAG, "Test " + getClass().getSimpleName() + " took " + duration + " ms");
@@ -76,7 +82,7 @@
             return 0;
         }
 
-        public String numberName(int number) {
+        String numberName(int number) {
             String result = "";
 
             if (number >= 1000) {
@@ -106,36 +112,50 @@
 
             return result;
         }
+
+        void checkCursor(Cursor c) {
+            c.getColumnCount();
+            c.close();
+        }
+    }
+
+    /**
+     * Test CREATE SIZE tables with 1 row.
+     */
+    public static class CreateTable100 extends PerformanceBase {
+        public void testRun() {
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                String t = "t" + i;
+                mDatabase.execSQL("CREATE TABLE " + t + "(a INTEGER, b INTEGER, c VARCHAR(100))");
+                mDatabase.execSQL("INSERT INTO " + t + " VALUES(" + i + "," + i + ",'"
+                        + numberName(i) + "')");
+            }
+        }
     }
 
     /**
      * Test 100 inserts.
      */
-
     public static class Insert100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-
-        private String[] statements = new String[SIZE];
+        private String[] mStatements = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
-                statements[i] =
+                mStatements[i] =
                         "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                                 + numberName(r) + "')";
             }
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.execSQL(statements[i]);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.execSQL(mStatements[i]);
             }
         }
     }
@@ -145,30 +165,25 @@
      */
 
     public static class InsertIndexed100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-
-        private String[] statements = new String[SIZE];
+        private String[] mStatements = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
-                statements[i] =
-                        "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-                                + numberName(r) + "')";
+                mStatements[i] = "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')";
             }
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.execSQL(statements[i]);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.execSQL(mStatements[i]);
             }
         }
     }
@@ -176,41 +191,35 @@
     /**
      * 100 SELECTs without an index
      */
-
     public static class Select100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
             mDatabase
             .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase
-                            .query("t1", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
@@ -219,37 +228,32 @@
      * 100 SELECTs on a string comparison
      */
     public static class SelectStringComparison100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
             mDatabase
             .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "c LIKE '" + numberName(i) + "'";
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mWhere[i] = "c LIKE '" + numberName(i) + "'";
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase
-                            .query("t1", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
@@ -258,40 +262,35 @@
      * 100 SELECTs with an index
      */
     public static class SelectIndex100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
+        private static final int TABLE_SIZE = 100;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[TABLE_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < TABLE_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < TABLE_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase
-                            .query("t1", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1", COLUMNS, mWhere[i % TABLE_SIZE], null, null, null, null));
             }
         }
     }
@@ -300,27 +299,22 @@
      *  INNER JOIN without an index
      */
     public static class InnerJoin100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -328,9 +322,9 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                        null, null, null, null);
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null));
             }
         }
     }
@@ -340,29 +334,24 @@
      */
 
     public static class InnerJoinOneSide100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
             mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -370,9 +359,9 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-                        null, null, null, null);
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                        null, null, null, null));
             }
         }
     }
@@ -381,29 +370,24 @@
      *  INNER JOIN without an index on one side
      */
     public static class InnerJoinNoIndex100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
             mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -411,9 +395,10 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
-                        null, null, null, null);
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null, null, null, null,
+                                null));
             }
         }
     }
@@ -422,49 +407,44 @@
      *  100 SELECTs with subqueries. Subquery is using an index
      */
     public static class SelectSubQIndex100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t1.a"};
 
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-            mDatabase
-            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
             mDatabase.execSQL("CREATE INDEX i2b ON t2(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] =
+                mWhere[i] =
                         "t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower
                         + " AND t2.b < " + upper + ")";
             }
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase
-                .query("t1", COLUMNS, where[i], null, null, null, null);
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
@@ -473,38 +453,32 @@
      *  100 SELECTs on string comparison with Index
      */
     public static class SelectIndexStringComparison100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "c LIKE '" + numberName(i) + "'";
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mWhere[i] = "c LIKE '" + numberName(i) + "'";
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase
-                            .query("t1", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
@@ -513,19 +487,15 @@
      *  100 SELECTs on integer
      */
     public static class SelectInteger100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -534,10 +504,8 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase.query("t1", COLUMNS, null, null, null, null, null));
             }
         }
     }
@@ -546,19 +514,16 @@
      *  100 SELECTs on String
      */
     public static class SelectString100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
             mDatabase
             .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -566,10 +531,8 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
             }
         }
     }
@@ -578,20 +541,17 @@
      *  100 SELECTs on integer with index
      */
     public static class SelectIntegerIndex100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"b"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
             mDatabase
             .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1b on t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -600,10 +560,8 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
             }
         }
     }
@@ -612,20 +570,16 @@
      *  100 SELECTs on String with index
      */
     public static class SelectIndexString100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -633,10 +587,8 @@
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase.query("t1", COLUMNS, null, null, null, null, null));
             }
         }
 
@@ -646,40 +598,33 @@
      *  100 SELECTs on String with starts with
      */
     public static class SelectStringStartsWith100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"c"};
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
-                where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
+                mWhere[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
 
             }
 
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase
-                            .query("t1", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                mDatabase.query("t1", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null);
             }
         }
     }
@@ -688,18 +633,15 @@
      *  100 Deletes on an indexed table
      */
     public static class DeleteIndexed100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -708,7 +650,7 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 mDatabase.delete("t1", null, null);
             }
         }
@@ -718,17 +660,13 @@
      *  100 Deletes
      */
     public static class Delete100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
@@ -737,7 +675,7 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 mDatabase.delete("t1", null, null);
             }
         }
@@ -747,33 +685,30 @@
      *  100 DELETE's without an index with where clause
      */
     public static class DeleteWhere100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
             }
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", where[i], null);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.delete("t1", mWhere[i], null);
             }
         }
     }
@@ -782,34 +717,31 @@
      * 100 DELETE's with an index with where clause
      */
     public static class DeleteIndexWhere100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
             }
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.delete("t1", where[i], null);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.delete("t1", mWhere[i], null);
             }
         }
     }
@@ -818,30 +750,26 @@
      * 100 update's with an index with where clause
      */
     public static class UpdateIndexWhere100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private String[] where = new String[SIZE];
-        ContentValues[] mValues = new ContentValues[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
+        ContentValues[] mValues = new ContentValues[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
-
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
                 ContentValues b = new ContentValues(1);
                 b.put("b", upper);
                 mValues[i] = b;
@@ -850,8 +778,8 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.update("t1", mValues[i], where[i], null);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.update("t1", mValues[i], mWhere[i], null);
             }
         }
     }
@@ -860,29 +788,26 @@
      * 100 update's without an index with where clause
      */
     public static class UpdateWhere100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private String[] where = new String[SIZE];
-        ContentValues[] mValues = new ContentValues[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
+        ContentValues[] mValues = new ContentValues[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
 
                 int lower = i * 100;
                 int upper = (i + 10) * 100;
-                where[i] = "b >= " + lower + " AND b < " + upper;
+                mWhere[i] = "b >= " + lower + " AND b < " + upper;
                 ContentValues b = new ContentValues(1);
                 b.put("b", upper);
                 mValues[i] = b;
@@ -890,8 +815,8 @@
         }
 
         public void testRun() {
-            for (int i = 0; i < SIZE; i++) {
-                mDatabase.update("t1", mValues[i], where[i], null);
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mDatabase.update("t1", mValues[i], mWhere[i], null);
             }
         }
     }
@@ -900,36 +825,31 @@
      * 100 selects for a String - contains 'e'
      */
     public static class SelectStringContains100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t3(a VARCHAR(100))");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t3 VALUES('"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "a LIKE '*e*'";
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mWhere[i] = "a LIKE '*e*'";
 
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t3", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
@@ -938,37 +858,32 @@
      * 100 selects for a String - contains 'e'-indexed table
      */
     public static class SelectStringIndexedContains100 extends PerformanceBase {
-        private static final int SIZE = SIZE_MULTIPLIER;
-        private static final int REPEAT_COUNT = 10;
         private static final String[] COLUMNS = {"t3.a"};
-        private String[] where = new String[SIZE];
+        private String[] mWhere = new String[DATASET_SIZE];
 
         @Override
-        public void setUp() {
-            super.setUp();
+        protected void prepareForTest() {
             Random random = new Random(42);
 
-            mDatabase
-            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            mDatabase.execSQL("CREATE TABLE t3(a VARCHAR(100))");
             mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
 
-            for (int i = 0; i < SIZE; i++) {
+            for (int i = 0; i < DATASET_SIZE; i++) {
                 int r = random.nextInt(100000);
                 mDatabase.execSQL("INSERT INTO t3 VALUES('"
                         + numberName(r) + "')");
             }
 
-            for (int i = 0; i < SIZE; i++) {
-                where[i] = "a LIKE '*e*'";
+            for (int i = 0; i < DATASET_SIZE; i++) {
+                mWhere[i] = "a LIKE '*e*'";
 
             }
         }
 
         public void testRun() {
-            for (int iter = 0; iter < REPEAT_COUNT; iter++) {
-                for (int i = 0; i < SIZE; i++) {
-                    mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-                }
+            for (int i = 0; i < FAST_OP_COUNT; i++) {
+                checkCursor(mDatabase
+                        .query("t3", COLUMNS, mWhere[i % DATASET_SIZE], null, null, null, null));
             }
         }
     }
diff --git a/core/tests/coretests/src/android/database/run_newdb_perf_test.sh b/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
index 10a62e6..c5b2c97 100755
--- a/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
+++ b/core/tests/coretests/src/android/database/run_newdb_perf_test.sh
@@ -17,8 +17,11 @@
 adb install -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
 adb logcat -c
 
-echo "Running benchmark 5 times"
-for i in {1..5}
+# by default run 5 times
+RUN_N=${1:-5}
+echo "Running benchmark $RUN_N times"
+
+for (( i=0; i<$RUN_N; i++ ))
 do
     adb  shell am instrument -e class 'android.database.NewDatabasePerformanceTestSuite' -w 'com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner'
 done
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index a61881f..95ec83d 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -181,7 +181,8 @@
     }
 
     private void done(boolean success) {
-        if (DBG) logd(String.format("Result success %b for %s", success, mUrl.toString()));
+        if (DBG) logd(String.format("Result success %b for %s", success,
+                mUrl != null ? mUrl.toString() : "null"));
         if (success) {
             // Trigger re-evaluation upon success http response code
             CarrierActionUtils.applyCarrierAction(
diff --git a/packages/EasterEgg/AndroidManifest.xml b/packages/EasterEgg/AndroidManifest.xml
index 14861c26..172490d 100644
--- a/packages/EasterEgg/AndroidManifest.xml
+++ b/packages/EasterEgg/AndroidManifest.xml
@@ -84,5 +84,16 @@
                 <action android:name="android.service.quicksettings.action.QS_TILE" />
             </intent-filter>
         </service>
+
+        <!-- FileProvider for sending pictures -->
+        <provider
+                android:name="android.support.v4.content.FileProvider"
+                android:authorities="com.android.egg.fileprovider"
+                android:grantUriPermissions="true"
+                android:exported="false">
+            <meta-data
+                    android:name="android.support.FILE_PROVIDER_PATHS"
+                    android:resource="@xml/filepaths" />
+        </provider>
     </application>
 </manifest>
diff --git a/packages/EasterEgg/res/drawable/food_cookie.xml b/packages/EasterEgg/res/drawable/food_cookie.xml
new file mode 100644
index 0000000..74dd134
--- /dev/null
+++ b/packages/EasterEgg/res/drawable/food_cookie.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+    <group>
+        <path
+            android:fillColor="#55FFFFFF"
+            android:fillType="evenOdd"
+            android:pathData="M5.71 18.29A8.99 8.99 0 0 0 22 13c0-3-1.46-5.65-3.71-7.29A8.99 8.99 0 0 0 2 11c0 3 1.46 5.65 3.71 7.29z"/>
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:fillType="evenOdd"
+            android:pathData="M7.25 19.18A8.5 8.5 0 0 0 19.19 7.24 9 9 0 0 1 7.24 19.19z"/>
+        <path
+            android:fillColor="#55FFFFFF"
+            android:pathData="M10.5 3a0.5 0.5 0 1 1 1 0v2.05a0.5 0.5 0 1 1-1 0V3zm3.1 0.42a0.5 0.5 0 0 1 0.93 0.39l-0.8 1.88A0.5 0.5 0 1 1 12.8 5.3l0.8-1.88zm2.7 1.57a0.5 0.5 0 1 1 0.71 0.7l-1.45 1.46a0.5 0.5 0 0 1-0.7-0.71l1.44-1.45zm1.9 2.5a0.5 0.5 0 0 1 0.38 0.92l-1.9 0.77a0.5 0.5 0 0 1-0.37-0.93l1.9-0.77zM19 10.5a0.5 0.5 0 1 1 0 1h-2.05a0.5 0.5 0 0 1 0-1H19zm-0.42 3.1a0.5 0.5 0 0 1-0.39 0.93l-1.88-0.8a0.5 0.5 0 1 1 0.39-0.92l1.88 0.8zm-1.57 2.7a0.5 0.5 0 1 1-0.7 0.71l-1.46-1.45a0.5 0.5 0 0 1 0.71-0.7l1.45 1.44zm-2.5 1.9a0.5 0.5 0 1 1-0.92 0.38l-0.77-1.9a0.5 0.5 0 0 1 0.93-0.37l0.77 1.9zM11.5 19a0.5 0.5 0 1 1-1 0v-2.05a0.5 0.5 0 0 1 1 0V19zm-3.1-0.42a0.5 0.5 0 0 1-0.93-0.39l0.8-1.88A0.5 0.5 0 0 1 9.2 16.7l-0.8 1.88zm-2.7-1.57a0.5 0.5 0 1 1-0.71-0.7l1.45-1.46a0.5 0.5 0 0 1 0.7 0.71L5.7 17.01zm-1.9-2.48a0.5 0.5 0 0 1-0.38-0.92l1.88-0.8a0.5 0.5 0 0 1 0.4 0.92l-1.9 0.8zM3 11.5a0.5 0.5 0 1 1 0-1h2.05a0.5 0.5 0 1 1 0 1H3zm0.42-3.1A0.5 0.5 0 0 1 3.8 7.46l1.88 0.8A0.5 0.5 0 1 1 5.3 9.2L3.42 8.4zm1.57-2.7a0.5 0.5 0 1 1 0.7-0.71l1.46 1.45a0.5 0.5 0 0 1-0.71 0.7L4.99 5.7zm2.5-1.9A0.5 0.5 0 0 1 8.4 3.41l0.77 1.9a0.5 0.5 0 0 1-0.93 0.37L7.48 3.8z"/>
+    </group>
+</vector>
\ No newline at end of file
diff --git a/packages/EasterEgg/res/values/strings.xml b/packages/EasterEgg/res/values/strings.xml
index 8478a43..61e3834 100644
--- a/packages/EasterEgg/res/values/strings.xml
+++ b/packages/EasterEgg/res/values/strings.xml
@@ -17,6 +17,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android">
     <string name="app_name" translatable="false">Android Easter Egg</string>
     <string name="notification_name" translatable="false">Android Neko</string>
+    <string name="notification_channel_name" translatable="false">New cats</string>
     <string name="default_tile_name" translatable="false">\????</string>
     <string name="notification_title" translatable="false">A cat is here.</string>
     <string name="default_cat_name" translatable="false">Cat #%s</string>
@@ -34,7 +35,7 @@
         <item>@drawable/food_bits</item>
         <item>@drawable/food_sysuituna</item>
         <item>@drawable/food_chicken</item>
-        <item>@drawable/food_donut</item>
+        <item>@drawable/food_cookie</item>
     </array>
     <integer-array name="food_intervals">
         <item>0</item>
diff --git a/packages/EasterEgg/res/xml/filepaths.xml b/packages/EasterEgg/res/xml/filepaths.xml
new file mode 100644
index 0000000..2130025
--- /dev/null
+++ b/packages/EasterEgg/res/xml/filepaths.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 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.
+-->
+<paths>
+    <external-path name="cats" path="Pictures/Cats" />
+</paths>
\ No newline at end of file
diff --git a/packages/EasterEgg/src/com/android/egg/neko/Cat.java b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
index a4df372..dd1bd07 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/Cat.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/Cat.java
@@ -31,6 +31,8 @@
 import com.android.egg.R;
 import com.android.internal.logging.MetricsLogger;
 
+import static com.android.egg.neko.NekoLand.CHAN_ID;
+
 public class Cat extends Drawable {
     public static final long[] PURR = {0, 40, 20, 40, 20, 40, 20, 40, 20, 40, 20, 40};
 
@@ -218,6 +220,7 @@
                 .setContentText(getName())
                 .setContentIntent(PendingIntent.getActivity(context, 0, intent, 0))
                 .setAutoCancel(true)
+                .setChannel(CHAN_ID)
                 .setVibrate(PURR)
                 .addExtras(extras);
     }
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
index 689e381..d2e37d8 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/NekoLand.java
@@ -31,6 +31,7 @@
 import android.os.Bundle;
 import android.os.Environment;
 import android.provider.MediaStore.Images;
+import android.support.v4.content.FileProvider;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
@@ -56,6 +57,8 @@
 import java.util.List;
 
 public class NekoLand extends Activity implements PrefsListener {
+    public static String CHAN_ID = "EGG";
+
     public static boolean DEBUG = false;
     public static boolean DEBUG_NOTIFICATIONS = false;
 
@@ -289,10 +292,13 @@
                         new String[] {png.toString()},
                         new String[] {"image/png"},
                         null);
-                Uri uri = Uri.fromFile(png);
+                Log.v("Neko", "cat file: " + png);
+                Uri uri = FileProvider.getUriForFile(this, "com.android.egg.fileprovider", png);
+                Log.v("Neko", "cat uri: " + uri);
                 Intent intent = new Intent(Intent.ACTION_SEND);
                 intent.putExtra(Intent.EXTRA_STREAM, uri);
                 intent.putExtra(Intent.EXTRA_SUBJECT, cat.getName());
+                intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                 intent.setType("image/png");
                 startActivity(Intent.createChooser(intent, null));
                 cat.logShare(this);
diff --git a/packages/EasterEgg/src/com/android/egg/neko/NekoService.java b/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
index 808ec36..42506e6 100644
--- a/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
+++ b/packages/EasterEgg/src/com/android/egg/neko/NekoService.java
@@ -15,15 +15,15 @@
 package com.android.egg.neko;
 
 import android.app.Notification;
+import android.app.NotificationChannel;
 import android.app.NotificationManager;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobService;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
+import android.net.Uri;
 import android.os.Bundle;
 
 import java.util.List;
@@ -33,6 +33,9 @@
 
 import java.util.Random;
 
+import static com.android.egg.neko.Cat.PURR;
+import static com.android.egg.neko.NekoLand.CHAN_ID;
+
 public class NekoService extends JobService {
 
     private static final String TAG = "NekoService";
@@ -40,6 +43,7 @@
     public static int JOB_ID = 42;
 
     public static int CAT_NOTIFICATION = 1;
+    public static int DEBUG_NOTIFICATION = 1234;
 
     public static float CAT_CAPTURE_PROB = 1.0f; // generous
 
@@ -50,6 +54,18 @@
 
     public static float INTERVAL_JITTER_FRAC = 0.25f;
 
+    private static void setupNotificationChannels(Context context) {
+        NotificationManager noman = context.getSystemService(NotificationManager.class);
+        NotificationChannel eggChan = new NotificationChannel(CHAN_ID,
+                context.getString(R.string.notification_channel_name),
+                NotificationManager.IMPORTANCE_DEFAULT);
+        eggChan.setSound(Uri.EMPTY, Notification.AUDIO_ATTRIBUTES_DEFAULT); // cats are quiet
+        eggChan.setVibrationPattern(PURR); // not totally quiet though
+        eggChan.setBlockableSystem(true); // unlike a real cat, you can push this one off your lap
+        eggChan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC); // cats sit in the window
+        noman.createNotificationChannel(eggChan);
+    }
+
     @Override
     public boolean onStartJob(JobParameters params) {
         Log.v(TAG, "Starting job: " + String.valueOf(params));
@@ -64,8 +80,9 @@
             final Notification.Builder builder
                     = cat.buildNotification(this)
                         .setContentTitle("DEBUG")
+                        .setChannel(NekoLand.CHAN_ID)
                         .setContentText("Ran job: " + params);
-            noman.notify(1, builder.build());
+            noman.notify(DEBUG_NOTIFICATION, builder.build());
         }
 
         final PrefState prefs = new PrefState(this);
@@ -111,6 +128,8 @@
     }
 
     public static void registerJob(Context context, long intervalMinutes) {
+        setupNotificationChannels(context);
+
         JobScheduler jss = context.getSystemService(JobScheduler.class);
         jss.cancel(JOB_ID);
         long interval = intervalMinutes * MINUTES;
@@ -126,12 +145,13 @@
 
         if (NekoLand.DEBUG_NOTIFICATIONS) {
             NotificationManager noman = context.getSystemService(NotificationManager.class);
-            noman.notify(500, new Notification.Builder(context)
+            noman.notify(DEBUG_NOTIFICATION, new Notification.Builder(context)
                     .setSmallIcon(R.drawable.stat_icon)
                     .setContentTitle(String.format("Job scheduled in %d min", (interval / MINUTES)))
                     .setContentText(String.valueOf(jobInfo))
                     .setPriority(Notification.PRIORITY_MIN)
                     .setCategory(Notification.CATEGORY_SERVICE)
+                    .setChannel(NekoLand.CHAN_ID)
                     .setShowWhen(true)
                     .build());
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
index 9620a91..3c095ae 100644
--- a/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/drawer/TileUtils.java
@@ -442,15 +442,6 @@
                     if (metaData.containsKey(META_DATA_PREFERENCE_CUSTOM_VIEW)) {
                         int layoutId = metaData.getInt(META_DATA_PREFERENCE_CUSTOM_VIEW);
                         remoteViews = new RemoteViews(applicationInfo.packageName, layoutId);
-                        if (metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
-                            String uriString = metaData.getString(
-                                    META_DATA_PREFERENCE_SUMMARY_URI);
-                            String overrideSummary = getTextFromUri(context, uriString, providerMap,
-                                    META_DATA_PREFERENCE_SUMMARY);
-                            if (overrideSummary != null) {
-                                remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
-                            }
-                        }
                     }
                 }
             } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
@@ -555,6 +546,30 @@
         }
     }
 
+    public static void updateTileUsingSummaryUri(Context context, Tile tile) {
+        if (tile == null || tile.metaData == null ||
+            !tile.metaData.containsKey(META_DATA_PREFERENCE_SUMMARY_URI)) {
+            return;
+        }
+
+        final Map<String, IContentProvider> providerMap = new HashMap<>();
+
+        final String uriString = tile.metaData.getString(META_DATA_PREFERENCE_SUMMARY_URI);
+        final Bundle bundle = getBundleFromUri(context, uriString, providerMap);
+        final String overrideSummary = getString(bundle, META_DATA_PREFERENCE_SUMMARY);
+        final String overrideTitle = getString(bundle, META_DATA_PREFERENCE_TITLE);
+        if (overrideSummary != null) {
+            tile.remoteViews.setTextViewText(android.R.id.summary, overrideSummary);
+        }
+        if (overrideTitle != null) {
+            tile.remoteViews.setTextViewText(android.R.id.title, overrideTitle);
+        }
+    }
+
+    private static String getString(Bundle bundle, String key) {
+        return bundle == null ? null : bundle.getString(key);
+    }
+
     private static IContentProvider getProviderFromUri(Context context, Uri uri,
             Map<String, IContentProvider> providerMap) {
         if (uri == null) {
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
index e9ca753..7e7fdb2 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/drawer/TileUtilsTest.java
@@ -22,10 +22,12 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 import static org.robolectric.RuntimeEnvironment.application;
@@ -64,9 +66,6 @@
 import org.mockito.MockitoAnnotations;
 import org.robolectric.RobolectricTestRunner;
 import org.robolectric.annotation.Config;
-import org.robolectric.annotation.Implementation;
-import org.robolectric.annotation.Implements;
-import org.robolectric.internal.ShadowExtractor;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -75,8 +74,7 @@
 
 @RunWith(RobolectricTestRunner.class)
 @Config(manifest = TestConfig.MANIFEST_PATH,
-        sdk = TestConfig.SDK_VERSION,
-        shadows = {TileUtilsTest.TileUtilsShadowRemoteViews.class})
+        sdk = TestConfig.SDK_VERSION)
 public class TileUtilsTest {
 
     @Mock
@@ -421,24 +419,12 @@
     }
 
     @Test
-    public void getTilesForIntent_summaryUriSpecified_shouldOverrideRemoteViewSummary()
+    public void updateTileUsingSummaryUri_summaryUriSpecified_shouldOverrideRemoteViewSummary()
             throws RemoteException {
-        Intent intent = new Intent();
-        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
-        List<Tile> outTiles = new ArrayList<>();
-        List<ResolveInfo> info = new ArrayList<>();
-        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
-                null, URI_GET_SUMMARY);
-        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
-                R.layout.user_preference);
-        info.add(resolveInfo);
-
-        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
-                .thenReturn(info);
-
         // Mock the content provider interaction.
         Bundle bundle = new Bundle();
-        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
+        String expectedSummary = "new summary text";
+        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, expectedSummary);
         when(mIContentProvider.call(anyString(),
                 eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
                 any())).thenReturn(bundle);
@@ -447,57 +433,12 @@
         when(mContentResolver.acquireUnstableProvider(any(Uri.class)))
                 .thenReturn(mIContentProvider);
 
-        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
-                null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */, true /* forceTintExternalIcon */);
-
-        assertThat(outTiles.size()).isEqualTo(1);
-        Tile tile = outTiles.get(0);
-        assertThat(tile.remoteViews).isNotNull();
-        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
-        // Make sure the summary TextView got a new text string.
-        TileUtilsShadowRemoteViews shadowRemoteViews =
-                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
-        assertThat(shadowRemoteViews.overrideViewId).isEqualTo(android.R.id.summary);
-        assertThat(shadowRemoteViews.overrideText).isEqualTo("new summary text");
-    }
-
-    @Test
-    public void getTilesForIntent_providerUnavailable_shouldNotOverrideRemoteViewSummary()
-            throws RemoteException {
-        Intent intent = new Intent();
-        Map<Pair<String, String>, Tile> addedCache = new ArrayMap<>();
-        List<Tile> outTiles = new ArrayList<>();
-        List<ResolveInfo> info = new ArrayList<>();
-        ResolveInfo resolveInfo = newInfo(true, null /* category */, null,
-                null, URI_GET_SUMMARY);
-        resolveInfo.activityInfo.metaData.putInt("com.android.settings.custom_view",
-                R.layout.user_preference);
-        info.add(resolveInfo);
-
-        when(mPackageManager.queryIntentActivitiesAsUser(eq(intent), anyInt(), anyInt()))
-                .thenReturn(info);
-
-        // Mock the content provider interaction.
-        Bundle bundle = new Bundle();
-        bundle.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY, "new summary text");
-        when(mIContentProvider.call(anyString(),
-                eq(TileUtils.getMethodFromUri(Uri.parse(URI_GET_SUMMARY))), eq(URI_GET_SUMMARY),
-                any())).thenReturn(bundle);
-
-        TileUtils.getTilesForIntent(mContext, UserHandle.CURRENT, intent, addedCache,
-                null /* defaultCategory */, outTiles, false /* usePriority */,
-                false /* checkCategory */, true /* forceTintExternalIcon */);
-
-        assertThat(outTiles.size()).isEqualTo(1);
-        Tile tile = outTiles.get(0);
-        assertThat(tile.remoteViews).isNotNull();
-        assertThat(tile.remoteViews.getLayoutId()).isEqualTo(R.layout.user_preference);
-        // Make sure the summary TextView didn't get any text view updates.
-        TileUtilsShadowRemoteViews shadowRemoteViews =
-                (TileUtilsShadowRemoteViews) ShadowExtractor.extract(tile.remoteViews);
-        assertThat(shadowRemoteViews.overrideViewId).isNull();
-        assertThat(shadowRemoteViews.overrideText).isNull();
+        Tile tile = new Tile();
+        tile.metaData = new Bundle();
+        tile.metaData.putString(TileUtils.META_DATA_PREFERENCE_SUMMARY_URI, URI_GET_SUMMARY);
+        tile.remoteViews = mock(RemoteViews.class);
+        TileUtils.updateTileUsingSummaryUri(mContext, tile);
+        verify(tile.remoteViews, times(1)).setTextViewText(anyInt(), eq(expectedSummary));
     }
 
     public static ResolveInfo newInfo(boolean systemApp, String category) {
@@ -562,16 +503,4 @@
         }
     }
 
-    @Implements(RemoteViews.class)
-    public static class TileUtilsShadowRemoteViews {
-
-        private Integer overrideViewId;
-        private CharSequence overrideText;
-
-        @Implementation
-        public void setTextViewText(int viewId, CharSequence text) {
-            overrideViewId = viewId;
-            overrideText = text;
-        }
-    }
 }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 75e9199..87971cb 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -318,15 +318,20 @@
             android:exported="false">
         </activity>
 
+        <!-- Springboard for launching the share activity -->
+        <receiver android:name=".screenshot.GlobalScreenshot$ShareReceiver"
+            android:process=":screenshot"
+            android:exported="false" />
+
         <!-- Callback for dismissing screenshot notification after a share target is picked -->
         <receiver android:name=".screenshot.GlobalScreenshot$TargetChosenReceiver"
-                  android:process=":screenshot"
-                  android:exported="false" />
+            android:process=":screenshot"
+            android:exported="false" />
 
         <!-- Callback for deleting screenshot notification -->
         <receiver android:name=".screenshot.GlobalScreenshot$DeleteScreenshotReceiver"
-                  android:process=":screenshot"
-                  android:exported="false" />
+            android:process=":screenshot"
+            android:exported="false" />
 
         <!-- started from UsbDeviceSettingsManager -->
         <activity android:name=".usb.UsbConfirmActivity"
diff --git a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
index dde2db2..2f16516 100644
--- a/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
+++ b/packages/SystemUI/res/layout/car_fullscreen_user_pod.xml
@@ -30,7 +30,8 @@
     <TextView android:id="@+id/user_name"
         android:layout_width="@dimen/car_fullscreen_user_pod_width"
         android:layout_height="wrap_content"
-        android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_above_text"
+        android:layout_marginTop="@dimen/car_fullscreen_user_pod_margin_name_top"
+        android:layout_marginBottom="@dimen/car_fullscreen_user_pod_margin_name_bottom"
         android:textSize="@dimen/car_fullscreen_user_pod_text_size"
         android:textColor="@color/qs_user_detail_name"
         android:ellipsize="end"
diff --git a/packages/SystemUI/res/layout/car_qs_footer.xml b/packages/SystemUI/res/layout/car_qs_footer.xml
index 96f34fc..044090b 100644
--- a/packages/SystemUI/res/layout/car_qs_footer.xml
+++ b/packages/SystemUI/res/layout/car_qs_footer.xml
@@ -18,23 +18,24 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/qs_footer"
     android:layout_width="match_parent"
-    android:layout_height="@dimen/qs_footer_height"
+    android:layout_height="@dimen/car_qs_footer_height"
     android:baselineAligned="false"
     android:clickable="false"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:paddingBottom="16dp"
-    android:paddingTop="16dp"
-    android:paddingEnd="32dp"
-    android:paddingStart="32dp"
+    android:paddingBottom="@dimen/car_qs_footer_padding_bottom"
+    android:paddingTop="@dimen/car_qs_footer_padding_top"
+    android:paddingEnd="@dimen/car_qs_footer_padding_end"
+    android:paddingStart="@dimen/car_qs_footer_padding_start"
     android:gravity="center_vertical">
 
     <com.android.systemui.statusbar.phone.MultiUserSwitch
         android:id="@+id/multi_user_switch"
         android:layout_alignParentStart="true"
         android:layout_centerVertical="true"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
+        android:layout_width="@dimen/car_qs_footer_icon_width"
+        android:layout_height="@dimen/car_qs_footer_icon_height"
+        android:layout_marginRight="@dimen/car_qs_footer_user_switch_margin_right"
         android:background="@drawable/ripple_drawable"
         android:focusable="true">
 
@@ -43,15 +44,24 @@
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center"
-            android:scaleType="centerInside"/>
+            android:scaleType="fitCenter"/>
     </com.android.systemui.statusbar.phone.MultiUserSwitch>
 
+    <TextView android:id="@+id/user_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:textSize="@dimen/car_qs_footer_user_name_text_size"
+        android:textColor="@color/car_qs_footer_user_name_color"
+        android:gravity="start|center_vertical"
+        android:layout_centerVertical="true"
+        android:layout_toEndOf="@id/multi_user_switch" />
+
     <com.android.systemui.statusbar.phone.SettingsButton
         android:id="@+id/settings_button"
         android:layout_alignParentEnd="true"
         android:layout_centerVertical="true"
-        android:layout_width="48dp"
-        android:layout_height="48dp"
+        android:layout_width="@dimen/car_qs_footer_icon_width"
+        android:layout_height="@dimen/car_qs_footer_icon_height"
         android:background="@drawable/ripple_drawable"
         android:contentDescription="@string/accessibility_quick_settings_settings"
         android:scaleType="centerCrop"
diff --git a/packages/SystemUI/res/values-h600dp/dimens_car.xml b/packages/SystemUI/res/values-h600dp/dimens_car.xml
new file mode 100644
index 0000000..c3e62c8
--- /dev/null
+++ b/packages/SystemUI/res/values-h600dp/dimens_car.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2017, 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.
+*/
+-->
+<resources>
+    <dimen name="car_body2_size">32sp</dimen> <!-- B2 -->
+</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 745d6015..a923f0b 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -34,6 +34,7 @@
         <attr name="recentItemLayout" format="reference" />
         <!-- Style for the "Clear all" button. -->
         <attr name="clearAllStyle" format="reference" />
+        <attr name="clearAllBackgroundColor" format="reference" />
     </declare-styleable>
     <declare-styleable name="DeadZone">
         <attr name="minSize" format="dimension" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f72f379..f244d88 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -60,6 +60,11 @@
     <!-- The background color for the freeform workspace. -->
     <color name="recents_freeform_workspace_bg_color">#33FFFFFF</color>
 
+    <!-- The background color for clear all button on light backgrounds if not transparent. -->
+    <color name="recents_clear_all_button_bg_light_color">#CCFFFFFF</color>
+    <!-- The background color for clear all button on dark backgrounds if not transparent. -->
+    <color name="recents_clear_all_button_bg_dark_color">#CC000000</color>
+
     <color name="keyguard_affordance">#ffffffff</color>
 
     <!-- The color of the legacy notification background -->
diff --git a/packages/SystemUI/res/values/colors_car.xml b/packages/SystemUI/res/values/colors_car.xml
index 1b8c2fa..710b3e0 100644
--- a/packages/SystemUI/res/values/colors_car.xml
+++ b/packages/SystemUI/res/values/colors_car.xml
@@ -20,8 +20,12 @@
     <color name="car_qs_background_primary">#263238</color> <!-- Blue Gray 900 -->
     <color name="car_user_switcher_progress_bgcolor">#00000000</color> <!-- Transparent -->
     <color name="car_user_switcher_progress_fgcolor">#80CBC4</color> <!-- Teal 200 -->
-    <color name="car_user_switcher_no_user_image_bgcolor">#FAFAFA</color> <!-- Grey 50 -->
-    <color name="car_user_switcher_no_user_image_fgcolor">#212121</color> <!-- Grey 900 -->
-    <color name="car_start_driving_background">#FAFAFA</color> <!-- Grey 50 -->
-    <color name="car_start_driving_text">#212121</color> <!-- Grey 900 -->
+    <color name="car_user_switcher_no_user_image_bgcolor">@color/car_grey_50</color>
+    <color name="car_user_switcher_no_user_image_fgcolor">@color/car_grey_900</color>
+    <color name="car_start_driving_background">@color/car_grey_50</color>
+    <color name="car_start_driving_text">@color/car_grey_900</color>
+    <color name="car_qs_footer_user_name_color">@color/car_grey_50</color>
+
+    <color name="car_grey_50">#FAFAFA</color>
+    <color name="car_grey_900">#212121</color>
 </resources>
diff --git a/packages/SystemUI/res/values/dimens_car.xml b/packages/SystemUI/res/values/dimens_car.xml
index 5f56c4e..8853587 100644
--- a/packages/SystemUI/res/values/dimens_car.xml
+++ b/packages/SystemUI/res/values/dimens_car.xml
@@ -18,7 +18,8 @@
 <resources>
     <dimen name="car_margin">148dp</dimen>
 
-    <dimen name="car_fullscreen_user_pod_margin_above_text">24dp</dimen>
+    <dimen name="car_fullscreen_user_pod_margin_name_top">24dp</dimen>
+    <dimen name="car_fullscreen_user_pod_margin_name_bottom">64dp</dimen>
     <dimen name="car_fullscreen_user_pod_margin_between">24dp</dimen>
     <dimen name="car_fullscreen_user_pod_icon_text_size">96dp</dimen>
     <dimen name="car_fullscreen_user_pod_image_avatar_width">192dp</dimen>
@@ -37,5 +38,17 @@
     <dimen name="car_start_driving_corner_radius">16dp</dimen>
     <dimen name="car_start_driving_padding_side">30dp</dimen>
     <dimen name="car_start_driving_height">80dp</dimen>
-    <dimen name="car_start_driving_text_size">32sp</dimen> <!-- B2 -->
+    <dimen name="car_start_driving_text_size">@dimen/car_body2_size</dimen>
+
+    <dimen name="car_qs_footer_height">112dp</dimen>
+    <dimen name="car_qs_footer_padding_bottom">16dp</dimen>
+    <dimen name="car_qs_footer_padding_top">16dp</dimen>
+    <dimen name="car_qs_footer_padding_end">46dp</dimen>
+    <dimen name="car_qs_footer_padding_start">46dp</dimen>
+    <dimen name="car_qs_footer_icon_width">56dp</dimen>
+    <dimen name="car_qs_footer_icon_height">56dp</dimen>
+    <dimen name="car_qs_footer_user_switch_margin_right">46dp</dimen>
+    <dimen name="car_qs_footer_user_name_text_size">@dimen/car_body2_size</dimen>
+
+    <dimen name="car_body2_size">26sp</dimen>
 </resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 2199fff..90c5977 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -34,11 +34,13 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowDisablePreview">true</item>
         <item name="clearAllStyle">@style/ClearAllButtonDefaultMargins</item>
+        <item name="clearAllBackgroundColor">@color/recents_clear_all_button_bg_dark_color</item>
         <item name="wallpaperTextColor">@*android:color/primary_text_material_dark</item>
         <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_dark</item>
     </style>
 
     <style name="RecentsTheme.Wallpaper.Light">
+        <item name="clearAllBackgroundColor">@color/recents_clear_all_button_bg_light_color</item>
         <item name="wallpaperTextColor">@*android:color/primary_text_material_light</item>
         <item name="wallpaperTextColorSecondary">@*android:color/secondary_text_material_light</item>
     </style>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
index d42b87b..142aab2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/car/CarQSFooter.java
@@ -22,6 +22,7 @@
 import android.view.View;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
+import android.widget.TextView;
 
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
@@ -44,6 +45,7 @@
     private UserInfoController mUserInfoController;
 
     private MultiUserSwitch mMultiUserSwitch;
+    private TextView mUserName;
     private ImageView mMultiUserAvatar;
     private UserGridView mUserGridView;
 
@@ -56,6 +58,7 @@
         super.onFinishInflate();
         mMultiUserSwitch = findViewById(R.id.multi_user_switch);
         mMultiUserAvatar = mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
+        mUserName = findViewById(R.id.user_name);
 
         mUserInfoController = Dependency.get(UserInfoController.class);
 
@@ -89,6 +92,7 @@
     @Override
     public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
         mMultiUserAvatar.setImageDrawable(picture);
+        mUserName.setText(name);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
index 8c04daf..1a7d14a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java
@@ -451,15 +451,22 @@
 
     public static class DrawableIcon extends Icon {
         protected final Drawable mDrawable;
+        protected final Drawable mInvisibleDrawable;
 
         public DrawableIcon(Drawable drawable) {
             mDrawable = drawable;
+            mInvisibleDrawable = drawable.getConstantState().newDrawable();
         }
 
         @Override
         public Drawable getDrawable(Context context) {
             return mDrawable;
         }
+
+        @Override
+        public Drawable getInvisibleDrawable(Context context) {
+            return mInvisibleDrawable;
+        }
     }
 
     public static class DrawableIconWithRes extends DrawableIcon {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 71f06cb..c44cd72 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -205,6 +205,10 @@
                         mStackButtonShadowDistance.x, mStackButtonShadowDistance.y,
                         mStackButtonShadowColor);
             }
+            if (Recents.getConfiguration().isLowRamDevice) {
+                int bgColor = Utils.getColorAttr(mContext, R.attr.clearAllBackgroundColor);
+                mStackActionButton.setBackgroundColor(bgColor);
+            }
         }
 
         // Let's also require dark status and nav bars if the text is dark
@@ -955,8 +959,8 @@
         int left, top;
         if (Recents.getConfiguration().isLowRamDevice) {
             Rect windowRect = Recents.getSystemServices().getWindowRect();
-            left = (windowRect.width() - mSystemInsets.left - mSystemInsets.right
-                    - mStackActionButton.getMeasuredWidth()) / 2;
+            int spaceLeft = windowRect.width() - mSystemInsets.left - mSystemInsets.right;
+            left = (spaceLeft - mStackActionButton.getMeasuredWidth()) / 2 + mSystemInsets.left;
             top = windowRect.height() - (mStackActionButton.getMeasuredHeight()
                     + mSystemInsets.bottom + mStackActionButton.getPaddingBottom() / 2);
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index a633a3e..8899e30 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -2396,10 +2396,14 @@
     }
 
     private void updateStackActionButtonVisibility() {
+        if (Recents.getConfiguration().isLowRamDevice) {
+            return;
+        }
+
         // Always show the button in grid layout.
         if (useGridLayout() ||
                 (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
-                        mStack.getTaskCount() > 0 && !Recents.getConfiguration().isLowRamDevice)) {
+                        mStack.getTaskCount() > 0)) {
             EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
         } else {
             EventBus.getDefault().send(new HideStackActionButtonEvent());
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
index 52fa7b5..17e6b9e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/lowram/TaskStackLowRamLayoutAlgorithm.java
@@ -126,7 +126,6 @@
             return transformOut;
         }
         boolean visible = true;
-        int x = mPaddingLeftRight;
         int y;
         if (taskCount > 1) {
             y = getTaskTopFromIndex(taskIndex) - percentageToScroll(stackScroll);
@@ -255,7 +254,7 @@
         transformOut.dimAlpha = 0f;
         transformOut.viewOutlineAlpha = 1f;
         transformOut.rect.set(getTaskRect());
-        transformOut.rect.offset(mPaddingLeftRight, y);
+        transformOut.rect.offset(mPaddingLeftRight + mSystemInsets.left, y);
         Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
         transformOut.visible = visible;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index a35310f..991c3c8 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -16,11 +16,16 @@
 
 package com.android.systemui.screenshot;
 
+import static com.android.systemui.screenshot.GlobalScreenshot.SHARING_INTENT;
+import static com.android.systemui.statusbar.phone.StatusBar.SYSTEM_DIALOG_REASON_SCREENSHOT;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
+import android.app.ActivityManager;
+import android.app.ActivityOptions;
 import android.app.admin.DevicePolicyManager;
 import android.app.Notification;
 import android.app.Notification.BigPictureStyle;
@@ -48,6 +53,7 @@
 import android.os.Environment;
 import android.os.PowerManager;
 import android.os.Process;
+import android.os.RemoteException;
 import android.os.UserHandle;
 import android.provider.MediaStore;
 import android.util.DisplayMetrics;
@@ -277,14 +283,13 @@
             sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
             sharingIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
 
-            // Create a share action for the notification
-            PendingIntent chooseAction = PendingIntent.getBroadcast(context, 0,
-                    new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
-                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-            Intent chooserIntent = Intent.createChooser(sharingIntent, null,
-                    chooseAction.getIntentSender())
-                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
-            PendingIntent shareAction = PendingIntent.getActivity(context, 0, chooserIntent,
+            // Create a share action for the notification. Note, we proxy the call to ShareReceiver
+            // because RemoteViews currently forces an activity options on the PendingIntent being
+            // launched, and since we don't want to trigger the share sheet in this case, we will
+            // start the chooser activitiy directly in ShareReceiver.
+            PendingIntent shareAction = PendingIntent.getBroadcast(context, 0,
+                    new Intent(context, GlobalScreenshot.ShareReceiver.class)
+                            .putExtra(SHARING_INTENT, sharingIntent),
                     PendingIntent.FLAG_CANCEL_CURRENT);
             Notification.Action.Builder shareActionBuilder = new Notification.Action.Builder(
                     R.drawable.ic_screenshot_share,
@@ -292,7 +297,7 @@
             mNotificationBuilder.addAction(shareActionBuilder.build());
 
             // Create a delete action for the notification
-            PendingIntent deleteAction = PendingIntent.getBroadcast(context,  0,
+            PendingIntent deleteAction = PendingIntent.getBroadcast(context, 0,
                     new Intent(context, GlobalScreenshot.DeleteScreenshotReceiver.class)
                             .putExtra(GlobalScreenshot.SCREENSHOT_URI_ID, uri.toString()),
                     PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
@@ -403,6 +408,7 @@
 
 class GlobalScreenshot {
     static final String SCREENSHOT_URI_ID = "android:screenshot_uri_id";
+    static final String SHARING_INTENT = "android:screenshot_sharing_intent";
 
     private static final int SCREENSHOT_FLASH_TO_PEAK_DURATION = 130;
     private static final int SCREENSHOT_DROP_IN_DURATION = 430;
@@ -897,6 +903,30 @@
     }
 
     /**
+     * Receiver to proxy the share intent.
+     */
+    public static class ShareReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            try {
+                ActivityManager.getService().closeSystemDialogs(SYSTEM_DIALOG_REASON_SCREENSHOT);
+            } catch (RemoteException e) {
+            }
+
+            Intent sharingIntent = intent.getParcelableExtra(SHARING_INTENT);
+            PendingIntent chooseAction = PendingIntent.getBroadcast(context, 0,
+                    new Intent(context, GlobalScreenshot.TargetChosenReceiver.class),
+                    PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
+            Intent chooserIntent = Intent.createChooser(sharingIntent, null,
+                    chooseAction.getIntentSender())
+                    .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
+            ActivityOptions opts = ActivityOptions.makeBasic();
+            opts.setDisallowEnterPictureInPictureWhileLaunching(true);
+            context.startActivityAsUser(chooserIntent, opts.toBundle(), UserHandle.CURRENT);
+        }
+    }
+
+    /**
      * Removes the notification for a screenshot after a share target is chosen.
      */
     public static class TargetChosenReceiver extends BroadcastReceiver {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
index fcc982ea..b95b8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationHeaderViewWrapper.java
@@ -114,7 +114,6 @@
         mIcon = mView.findViewById(com.android.internal.R.id.icon);
         mHeaderText = mView.findViewById(com.android.internal.R.id.header_text);
         mExpandButton = mView.findViewById(com.android.internal.R.id.expand_button);
-        mExpandButton.setLabeledBy(mRow);
         mWorkProfileImage = mView.findViewById(com.android.internal.R.id.profile_badge);
         mColor = resolveColor(mExpandButton);
         mNotificationHeader = mView.findViewById(com.android.internal.R.id.notification_header);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
index f379a46..1f44abe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BarTransitions.java
@@ -41,8 +41,6 @@
     private static final boolean DEBUG = false;
     private static final boolean DEBUG_COLORS = false;
 
-    public static final boolean HIGH_END = ActivityManager.isHighEndGfx();
-
     public static final int MODE_OPAQUE = 0;
     public static final int MODE_SEMI_TRANSPARENT = 1;
     public static final int MODE_TRANSLUCENT = 2;
@@ -66,9 +64,7 @@
         mTag = "BarTransitions." + view.getClass().getSimpleName();
         mView = view;
         mBarBackground = new BarBackgroundDrawable(mView.getContext(), gradientResourceId);
-        if (HIGH_END) {
-            mView.setBackground(mBarBackground);
-        }
+        mView.setBackground(mBarBackground);
     }
 
     public int getMode() {
@@ -89,7 +85,7 @@
 
     public boolean isAlwaysOpaque() {
         // Low-end devices do not support translucent modes, fallback to opaque
-        return !HIGH_END || mAlwaysOpaque;
+        return mAlwaysOpaque;
     }
 
     public void transitionTo(int mode, boolean animate) {
@@ -109,9 +105,7 @@
     }
 
     protected void onTransition(int oldMode, int newMode, boolean animate) {
-        if (HIGH_END) {
-            applyModeBackground(oldMode, newMode, animate);
-        }
+        applyModeBackground(oldMode, newMode, animate);
     }
 
     protected void applyModeBackground(int oldMode, int newMode, boolean animate) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 8c923cb..2c3f452 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -161,10 +161,6 @@
                 showNotificationIconArea(animate);
             }
         }
-        if (!BarTransitions.HIGH_END) {
-            int mask = DISABLE_NOTIFICATION_ICONS | DISABLE_SYSTEM_INFO;
-            getView().setVisibility((mDisabled1 & mask) == mask ? View.GONE : View.VISIBLE);
-        }
     }
 
     protected int adjustDisableFlags(int state) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
index d3a6280..b0ac6ec 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LightBarTransitionsController.java
@@ -127,11 +127,6 @@
     }
 
     public void setIconsDark(boolean dark, boolean animate) {
-        if (!BarTransitions.HIGH_END) {
-            setIconTintInternal(0.0f);
-            mNextDarkIntensity = 0.0f;
-            return;
-        }
         if (!animate) {
             setIconTintInternal(dark ? 1.0f : 0.0f);
             mNextDarkIntensity = dark ? 1.0f : 0.0f;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 0575e21..7a10985 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -300,6 +300,7 @@
     // Should match the values in PhoneWindowManager
     public static final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
     public static final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
+    static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
 
     private static final String BANNER_ACTION_CANCEL =
             "com.android.systemui.statusbar.banner_action_cancel";
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 9fbec70..eb895de 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4300,6 +4300,11 @@
     // OS: O MR
     FIELD_NUM_STATUS_ICONS = 1095;
 
+    // ACTION: Logged when user tries to pair a Bluetooth device without name from Settings app
+    // CATEGORY: SETTINGS
+    // OS: O MR
+    ACTION_SETTINGS_BLUETOOTH_PAIR_DEVICES_WITHOUT_NAMES = 1096;
+
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
   }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 95db603..d81cd64 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -456,14 +456,7 @@
             }
         }
         if (response == null) {
-            if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
-            if ((requestFlags & FLAG_MANUAL_REQUEST) != 0) {
-                getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
-            }
-            mService.resetLastResponse();
-            // Nothing to be done, but need to notify client.
-            notifyUnavailableToClient();
-            removeSelf();
+            processNullResponseLocked(requestFlags);
             return;
         }
 
@@ -748,16 +741,24 @@
         }
 
         final Parcelable result = data.getParcelable(AutofillManager.EXTRA_AUTHENTICATION_RESULT);
+        if (sDebug) Slog.d(TAG, "setAuthenticationResultLocked(): result=" + result);
         if (result instanceof FillResponse) {
             final FillResponse response = (FillResponse) result;
             mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
             replaceResponseLocked(authenticatedResponse, response);
         } else if (result instanceof Dataset) {
+            // TODO: add proper metric
             if (datasetIdx != AutofillManager.AUTHENTICATION_ID_DATASET_ID_UNDEFINED) {
                 final Dataset dataset = (Dataset) result;
                 authenticatedResponse.getDatasets().set(datasetIdx, dataset);
                 autoFill(requestId, datasetIdx, dataset);
             }
+        } else {
+            if (result != null) {
+                Slog.w(TAG, "service returned invalid auth type: " + result);
+            }
+            // TODO: add proper metric (on else)
+            processNullResponseLocked(0);
         }
     }
 
@@ -1409,6 +1410,17 @@
         processResponseLocked(newResponse, 0);
     }
 
+    private void processNullResponseLocked(int flags) {
+        if (sVerbose) Slog.v(TAG, "canceling session " + id + " when server returned null");
+        if ((flags & FLAG_MANUAL_REQUEST) != 0) {
+            getUiForShowing().showError(R.string.autofill_error_cannot_autofill, this);
+        }
+        mService.resetLastResponse();
+        // Nothing to be done, but need to notify client.
+        notifyUnavailableToClient();
+        removeSelf();
+    }
+
     private void processResponseLocked(@NonNull FillResponse newResponse, int flags) {
         // Make sure we are hiding the UI which will be shown
         // only if handling the current response requires it.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index dad3125..85fa7a1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -13231,7 +13231,6 @@
                 return;
             }
         }
-
         // We are now ready to launch the assist activity.
         IResultReceiver sendReceiver = null;
         Bundle sendBundle = null;
@@ -13261,17 +13260,24 @@
             return;
         }
 
-        long ident = Binder.clearCallingIdentity();
+        final long ident = Binder.clearCallingIdentity();
         try {
-            pae.intent.replaceExtras(pae.extras);
-            pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_SINGLE_TOP
-                    | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-            closeSystemDialogs("assist");
-            try {
-                mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
-            } catch (ActivityNotFoundException e) {
-                Slog.w(TAG, "No activity to handle assist action.", e);
+            if (TextUtils.equals(pae.intent.getAction(),
+                    android.service.voice.VoiceInteractionService.SERVICE_INTERFACE)) {
+                pae.intent.putExtras(pae.extras);
+                mContext.startServiceAsUser(pae.intent, new UserHandle(pae.userHandle));
+            } else {
+                pae.intent.replaceExtras(pae.extras);
+                pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_SINGLE_TOP
+                        | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                closeSystemDialogs("assist");
+
+                try {
+                    mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
+                } catch (ActivityNotFoundException e) {
+                    Slog.w(TAG, "No activity to handle assist action.", e);
+                }
             }
         } finally {
             Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index d62d935..791b2c0 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3007,13 +3007,6 @@
             // Ensure the task/activity being brought forward is not the assistant
             return false;
         }
-        final boolean isFullscreen = toFrontTask != null
-                ? toFrontTask.containsOnlyFullscreenActivities()
-                : toFrontActivity.fullscreen;
-        if (!isFullscreen) {
-            // Ensure the task/activity being brought forward is fullscreen
-            return false;
-        }
         return true;
     }
 
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 1bbb068..eadc8a6 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -1112,19 +1112,6 @@
         return intent != null ? intent : affinityIntent;
     }
 
-    /**
-     * @return Whether there are only fullscreen activities in this task.
-     */
-    boolean containsOnlyFullscreenActivities() {
-        for (int i = 0; i < mActivities.size(); i++) {
-            final ActivityRecord r = mActivities.get(i);
-            if (!r.finishing && !r.fullscreen) {
-                return false;
-            }
-        }
-        return true;
-    }
-
     /** Returns the first non-finishing activity from the root. */
     ActivityRecord getRootActivity() {
         for (int i = 0; i < mActivities.size(); i++) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 20fb350..4145e60 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8512,7 +8512,7 @@
                         continue;
                     }
                     if (filterAppAccessLPr(ps, callingUid, userId)) {
-                        return null;
+                        continue;
                     }
                     final PackageInfo pi = generatePackageInfo(ps, flags, userId);
                     if (pi != null) {
@@ -8527,7 +8527,7 @@
                         continue;
                     }
                     if (filterAppAccessLPr(ps, callingUid, userId)) {
-                        return null;
+                        continue;
                     }
                     final PackageInfo pi = generatePackageInfo((PackageSetting)
                             p.mExtras, flags, userId);
@@ -8639,7 +8639,7 @@
                             continue;
                         }
                         if (filterAppAccessLPr(ps, callingUid, userId)) {
-                            return null;
+                            continue;
                         }
                         ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
                                 ps.readUserState(userId), userId);
@@ -8665,7 +8665,7 @@
                             continue;
                         }
                         if (filterAppAccessLPr(ps, callingUid, userId)) {
-                            return null;
+                            continue;
                         }
                         ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
                                 ps.readUserState(userId), userId);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 27159fa..bc531c3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -335,6 +335,7 @@
     static public final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
     static public final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
     static public final String SYSTEM_DIALOG_REASON_ASSIST = "assist";
+    static public final String SYSTEM_DIALOG_REASON_SCREENSHOT = "screenshot";
 
     /**
      * These are the system UI flags that, when changing, can cause the layout
@@ -829,6 +830,7 @@
     private static final int MSG_ACCESSIBILITY_TV = 23;
     private static final int MSG_DISPATCH_BACK_KEY_TO_AUTOFILL = 24;
     private static final int MSG_SYSTEM_KEY_PRESS = 25;
+    private static final int MSG_HANDLE_ALL_APPS = 26;
 
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
     private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
@@ -921,6 +923,9 @@
                 case MSG_SYSTEM_KEY_PRESS:
                     sendSystemKeyToStatusBar(msg.arg1);
                     break;
+                case MSG_HANDLE_ALL_APPS:
+                    launchAllAppsAction();
+                    break;
             }
         }
     }
@@ -1801,6 +1806,17 @@
 
     private void launchAllAppsAction() {
         Intent intent = new Intent(Intent.ACTION_ALL_APPS);
+        if (mHasFeatureLeanback) {
+            final PackageManager pm = mContext.getPackageManager();
+            Intent intentLauncher = new Intent(Intent.ACTION_MAIN);
+            intentLauncher.addCategory(Intent.CATEGORY_HOME);
+            ResolveInfo resolveInfo = pm.resolveActivityAsUser(intentLauncher,
+                    PackageManager.MATCH_SYSTEM_ONLY,
+                    mCurrentUserId);
+            if (resolveInfo != null) {
+                intent.setPackage(resolveInfo.activityInfo.packageName);
+            }
+        }
         startActivityAsUser(intent, UserHandle.CURRENT);
     }
 
@@ -3620,6 +3636,14 @@
             return -1;
         } else if (mHasFeatureLeanback && interceptAccessibilityGestureTv(keyCode, down)) {
             return -1;
+        } else if (keyCode == KeyEvent.KEYCODE_ALL_APPS) {
+            if (!down) {
+                mHandler.removeMessages(MSG_HANDLE_ALL_APPS);
+                Message msg = mHandler.obtainMessage(MSG_HANDLE_ALL_APPS);
+                msg.setAsynchronous(true);
+                msg.sendToTarget();
+            }
+            return -1;
         }
 
         // Toggle Caps Lock on META-ALT.
diff --git a/services/core/java/com/android/server/search/SearchManagerService.java b/services/core/java/com/android/server/search/SearchManagerService.java
index 8969771..c3fa823 100644
--- a/services/core/java/com/android/server/search/SearchManagerService.java
+++ b/services/core/java/com/android/server/search/SearchManagerService.java
@@ -17,7 +17,6 @@
 package com.android.server.search;
 
 import android.app.ActivityManager;
-import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.ISearchManager;
 import android.app.SearchManager;
@@ -26,7 +25,6 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.database.ContentObserver;
@@ -37,6 +35,7 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
+import android.service.voice.VoiceInteractionService;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -272,24 +271,25 @@
         }
     }
 
+    // Check and return VIS component
     private ComponentName getLegacyAssistComponent(int userHandle) {
         try {
             userHandle = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
-                    Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent", null);
-            IPackageManager pm = AppGlobals.getPackageManager();
-            Intent assistIntent = new Intent(Intent.ACTION_ASSIST);
-            ResolveInfo info =
-                    pm.resolveIntent(assistIntent,
-                            assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
-                            PackageManager.MATCH_DEFAULT_ONLY, userHandle);
-            if (info != null) {
+                    Binder.getCallingUid(), userHandle, true, false, "getLegacyAssistComponent",
+                    null);
+            PackageManager pm = mContext.getPackageManager();
+            Intent intentAssistProbe = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
+            List<ResolveInfo> infoListVis = pm.queryIntentServicesAsUser(intentAssistProbe,
+                    PackageManager.MATCH_SYSTEM_ONLY, userHandle);
+            if (infoListVis == null || infoListVis.isEmpty()) {
+                return null;
+            } else {
+                ResolveInfo rInfo = infoListVis.get(0);
                 return new ComponentName(
-                        info.activityInfo.applicationInfo.packageName,
-                        info.activityInfo.name);
+                        rInfo.serviceInfo.applicationInfo.packageName,
+                        rInfo.serviceInfo.name);
+
             }
-        } catch (RemoteException re) {
-            // Local call
-            Log.e(TAG, "RemoteException in getLegacyAssistComponent: " + re);
         } catch (Exception e) {
             Log.e(TAG, "Exception in getLegacyAssistComponent: " + e);
         }
@@ -304,9 +304,15 @@
         }
         long ident = Binder.clearCallingIdentity();
         try {
-            Intent intent = new Intent(Intent.ACTION_ASSIST);
+            Intent intent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
             intent.setComponent(comp);
+
             IActivityManager am = ActivityManager.getService();
+            if (args != null) {
+                args.putInt(Intent.EXTRA_KEY_EVENT, android.view.KeyEvent.KEYCODE_ASSIST);
+            }
+            intent.putExtras(args);
+
             return am.launchAssistIntent(intent, ActivityManager.ASSIST_CONTEXT_BASIC, hint,
                     userHandle, args);
         } catch (RemoteException e) {