Merge "Remove dead code"
diff --git a/api/current.txt b/api/current.txt
index 5b5bd24..5931b31 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -42407,7 +42407,7 @@
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+    method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
     method public int describeContents();
     method public int getDataLimitBehavior();
     method public long getDataLimitBytes();
@@ -42429,9 +42429,7 @@
   public static class SubscriptionPlan.Builder {
     method public android.telephony.SubscriptionPlan build();
     method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+    method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
     method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/api/system-current.txt b/api/system-current.txt
index 76a71cd..0bcb1c2 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5191,7 +5191,7 @@
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+    method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
     method public int describeContents();
     method public int getDataLimitBehavior();
     method public long getDataLimitBytes();
@@ -5213,9 +5213,10 @@
   public static class SubscriptionPlan.Builder {
     method public android.telephony.SubscriptionPlan build();
     method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+    method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
     method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/api/test-current.txt b/api/test-current.txt
index f9402e4..d5b1399 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -492,6 +492,11 @@
     method public int getProgramId();
   }
 
+  public final class PlaybackParams implements android.os.Parcelable {
+    method public int getAudioStretchMode();
+    method public android.media.PlaybackParams setAudioStretchMode(int);
+  }
+
   public static final class VolumeShaper.Configuration.Builder {
     method public android.media.VolumeShaper.Configuration.Builder setOptionFlags(int);
   }
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 46d1264..5113fd0 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1145,6 +1145,21 @@
                 SUPPRESSED_EFFECT_NOTIFICATION_LIST
         };
 
+        private static final int[] SCREEN_OFF_SUPPRESSED_EFFECTS = {
+                SUPPRESSED_EFFECT_SCREEN_OFF,
+                SUPPRESSED_EFFECT_FULL_SCREEN_INTENT,
+                SUPPRESSED_EFFECT_LIGHTS,
+                SUPPRESSED_EFFECT_AMBIENT,
+        };
+
+        private static final int[] SCREEN_ON_SUPPRESSED_EFFECTS = {
+                SUPPRESSED_EFFECT_SCREEN_ON,
+                SUPPRESSED_EFFECT_PEEK,
+                SUPPRESSED_EFFECT_STATUS_BAR,
+                SUPPRESSED_EFFECT_BADGE,
+                SUPPRESSED_EFFECT_NOTIFICATION_LIST
+        };
+
         /**
          * Visual effects to suppress for a notification that is filtered by Do Not Disturb mode.
          * Bitmask of SUPPRESSED_EFFECT_* constants.
@@ -1297,6 +1312,32 @@
             return true;
         }
 
+        /**
+         * @hide
+         */
+        public static boolean areAnyScreenOffEffectsSuppressed(int effects) {
+            for (int i = 0; i < SCREEN_OFF_SUPPRESSED_EFFECTS.length; i++) {
+                final int effect = SCREEN_OFF_SUPPRESSED_EFFECTS[i];
+                if ((effects & effect) != 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * @hide
+         */
+        public static boolean areAnyScreenOnEffectsSuppressed(int effects) {
+            for (int i = 0; i < SCREEN_ON_SUPPRESSED_EFFECTS.length; i++) {
+                final int effect = SCREEN_ON_SUPPRESSED_EFFECTS[i];
+                if ((effects & effect) != 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         public static String suppressedEffectsToString(int effects) {
             if (effects <= 0) return "";
             final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 9f3df37..f7908b6 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -51,7 +51,6 @@
 import android.util.EventLog;
 import android.util.Log;
 
-import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.MimeIconUtils;
 import com.android.internal.util.Preconditions;
 
@@ -602,6 +601,8 @@
             try {
                 return provider.getType(url);
             } catch (RemoteException e) {
+                // Arbitrary and not worth documenting, as Activity
+                // Manager will kill this process shortly anyway.
                 return null;
             } catch (java.lang.Exception e) {
                 Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
@@ -620,9 +621,7 @@
                     ContentProvider.getUriWithoutUserId(url), resolveUserId(url));
             return type;
         } catch (RemoteException e) {
-            // Arbitrary and not worth documenting, as Activity
-            // Manager will kill this process shortly anyway.
-            return null;
+            throw e.rethrowFromSystemServer();
         } catch (java.lang.Exception e) {
             Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
             return null;
@@ -1964,6 +1963,7 @@
             getContentService().registerContentObserver(uri, notifyForDescendents,
                     observer.getContentObserver(), userHandle, mTargetSdkVersion);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -1982,6 +1982,7 @@
                         contentObserver);
             }
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2089,6 +2090,7 @@
                     syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0,
                     userHandle, mTargetSdkVersion);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2105,6 +2107,7 @@
                     observer != null && observer.deliverSelfNotifications(), flags,
                     userHandle, mTargetSdkVersion);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2126,6 +2129,7 @@
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, /* toPackage= */ null,
                     resolveUserId(uri));
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2141,6 +2145,7 @@
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, toPackage,
                     resolveUserId(uri));
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2160,6 +2165,7 @@
                     ContentProvider.getUriWithoutUserId(uri), modeFlags, /* toPackage= */ null,
                     resolveUserId(uri));
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2178,7 +2184,7 @@
             return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, true).getList();
         } catch (RemoteException e) {
-            throw new RuntimeException("Activity manager has died", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2194,7 +2200,7 @@
             return ActivityManager.getService()
                     .getPersistedUriPermissions(mPackageName, false).getList();
         } catch (RemoteException e) {
-            throw new RuntimeException("Activity manager has died", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2273,7 +2279,7 @@
         try {
             getContentService().syncAsUser(request, userId);
         } catch(RemoteException e) {
-            // Shouldn't happen.
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2285,7 +2291,7 @@
         try {
             getContentService().sync(request);
         } catch(RemoteException e) {
-            // Shouldn't happen.
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2349,6 +2355,7 @@
         try {
             getContentService().cancelSync(account, authority, null);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2360,6 +2367,7 @@
         try {
             getContentService().cancelSyncAsUser(account, authority, null, userId);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2371,7 +2379,7 @@
         try {
             return getContentService().getSyncAdapterTypes();
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2383,7 +2391,7 @@
         try {
             return getContentService().getSyncAdapterTypesAsUser(userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2397,8 +2405,8 @@
         try {
             return getContentService().getSyncAdapterPackagesForAuthorityAsUser(authority, userId);
         } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
         }
-        return ArrayUtils.emptyArray(String.class);
     }
 
     /**
@@ -2414,7 +2422,7 @@
         try {
             return getContentService().getSyncAutomatically(account, authority);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2427,7 +2435,7 @@
         try {
             return getContentService().getSyncAutomaticallyAsUser(account, authority, userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2453,8 +2461,7 @@
         try {
             getContentService().setSyncAutomaticallyAsUser(account, authority, sync, userId);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2500,8 +2507,7 @@
         try {
              getContentService().addPeriodicSync(account, authority, extras, pollFrequency);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2540,7 +2546,7 @@
         try {
             getContentService().removePeriodicSync(account, authority, extras);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2564,8 +2570,7 @@
         try {
             getContentService().cancelRequest(request);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2582,7 +2587,7 @@
         try {
             return getContentService().getPeriodicSyncs(account, authority, null);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2596,7 +2601,7 @@
         try {
             return getContentService().getIsSyncable(account, authority);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2609,7 +2614,7 @@
         try {
             return getContentService().getIsSyncableAsUser(account, authority, userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2623,8 +2628,7 @@
         try {
             getContentService().setIsSyncable(account, authority, syncable);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2640,7 +2644,7 @@
         try {
             return getContentService().getMasterSyncAutomatically();
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2652,7 +2656,7 @@
         try {
             return getContentService().getMasterSyncAutomaticallyAsUser(userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2676,8 +2680,7 @@
         try {
             getContentService().setMasterSyncAutomaticallyAsUser(sync, userId);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2701,7 +2704,7 @@
         try {
             return getContentService().isSyncActive(account, authority, null);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2727,7 +2730,7 @@
             }
             return syncs.get(0);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2744,7 +2747,7 @@
         try {
             return getContentService().getCurrentSyncs();
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2756,7 +2759,7 @@
         try {
             return getContentService().getCurrentSyncsAsUser(userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2771,7 +2774,7 @@
         try {
             return getContentService().getSyncStatus(account, authority, null);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2784,7 +2787,7 @@
         try {
             return getContentService().getSyncStatusAsUser(account, authority, null, userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2809,7 +2812,7 @@
         try {
             return getContentService().isSyncPendingAsUser(account, authority, null, userId);
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2841,7 +2844,7 @@
             getContentService().addStatusChangeListener(mask, observer);
             return observer;
         } catch (RemoteException e) {
-            throw new RuntimeException("the ContentService should always be reachable", e);
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -2856,8 +2859,7 @@
         try {
             getContentService().removeStatusChangeListener((ISyncStatusObserver.Stub) handle);
         } catch (RemoteException e) {
-            // exception ignored; if this is thrown then it means the runtime is in the midst of
-            // being restarted
+            throw e.rethrowFromSystemServer();
         }
     }
 
@@ -3027,9 +3029,7 @@
             return sContentService;
         }
         IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
-        if (false) Log.v("ContentService", "default service binder = " + b);
         sContentService = IContentService.Stub.asInterface(b);
-        if (false) Log.v("ContentService", "default service = " + sContentService);
         return sContentService;
     }
 
@@ -3038,7 +3038,7 @@
         return mPackageName;
     }
 
-    private static IContentService sContentService;
+    private static volatile IContentService sContentService;
     private final Context mContext;
 
     final String mPackageName;
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d734aa3..6e952c0 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6137,7 +6137,9 @@
      * signed.  This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
      * since it takes into account the possibility of signing certificate rotation, except in the
      * case of packages that are signed by multiple certificates, for which signing certificate
-     * rotation is not supported.
+     * rotation is not supported.  This method is analogous to using {@code getPackageInfo} with
+     * {@code GET_SIGNING_CERTIFICATES} and then searching through the resulting {@code
+     * signingCertificateHistory} field to see if the desired certificate is present.
      *
      * @param packageName package whose signing certificates to check
      * @param certificate signing certificate for which to search
@@ -6151,13 +6153,19 @@
     }
 
     /**
-     * Searches the set of signing certificates by which the given uid has proven to have been
-     * signed.  This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
+     * Searches the set of signing certificates by which the package(s) for the given uid has proven
+     * to have been signed.  For multiple packages sharing the same uid, this will return the
+     * signing certificates found in the signing history of the "newest" package, where "newest"
+     * indicates the package with the newest signing certificate in the shared uid group.  This
+     * method should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
      * since it takes into account the possibility of signing certificate rotation, except in the
      * case of packages that are signed by multiple certificates, for which signing certificate
-     * rotation is not supported.
+     * rotation is not supported. This method is analogous to using {@code getPackagesForUid}
+     * followed by {@code getPackageInfo} with {@code GET_SIGNING_CERTIFICATES}, selecting the
+     * {@code PackageInfo} of the newest-signed bpackage , and finally searching through the
+     * resulting {@code signingCertificateHistory} field to see if the desired certificate is there.
      *
-     * @param uid package whose signing certificates to check
+     * @param uid uid whose signing certificates to check
      * @param certificate signing certificate for which to search
      * @param type representation of the {@code certificate}
      * @return true if this package was or is signed by exactly the certificate {@code certificate}
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 1a28732..e84c85e 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -19,7 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.BackupUtils;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.util.Preconditions;
@@ -136,7 +136,7 @@
         return 0;
     }
 
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         return cycleRule.cycleIterator();
     }
 
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index bf6b7e0..6546c39 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -31,6 +31,7 @@
 import android.os.UserHandle;
 import android.util.DebugUtils;
 import android.util.Pair;
+import android.util.Range;
 
 import com.google.android.collect.Sets;
 
@@ -258,8 +259,21 @@
     }
 
     /** {@hide} */
+    @Deprecated
     public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
-        return policy.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
+        return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
+            @Override
+            public boolean hasNext() {
+                return it.hasNext();
+            }
+
+            @Override
+            public Pair<ZonedDateTime, ZonedDateTime> next() {
+                final Range<ZonedDateTime> r = it.next();
+                return Pair.create(r.getLower(), r.getUpper());
+            }
+        };
     }
 
     /**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 770ffc9..b644c1d 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7384,6 +7384,17 @@
                 BOOLEAN_VALIDATOR;
 
         /**
+         * Whether the swipe up gesture to switch apps should be enabled.
+         *
+         * @hide
+         */
+        public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED =
+                "swipe_up_to_switch_apps_enabled";
+
+        private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR =
+                BOOLEAN_VALIDATOR;
+
+        /**
          * Whether or not the smart camera lift trigger that launches the camera when the user moves
          * the phone into a position for taking photos should be enabled.
          *
@@ -7894,6 +7905,7 @@
             NIGHT_DISPLAY_AUTO_MODE,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
+            SWIPE_UP_TO_SWITCH_APPS_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
             SYSTEM_NAVIGATION_KEYS_ENABLED,
             QS_TILES,
@@ -8027,6 +8039,8 @@
             VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
                     CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR);
+            VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED,
+                    SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
                     CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR);
             VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED,
@@ -8938,6 +8952,20 @@
        /** {@hide} */
        public static final String NETSTATS_UID_TAG_DELETE_AGE = "netstats_uid_tag_delete_age";
 
+       /** {@hide} */
+       public static final String NETPOLICY_QUOTA_ENABLED = "netpolicy_quota_enabled";
+       /** {@hide} */
+       public static final String NETPOLICY_QUOTA_UNLIMITED = "netpolicy_quota_unlimited";
+       /** {@hide} */
+       public static final String NETPOLICY_QUOTA_LIMITED = "netpolicy_quota_limited";
+       /** {@hide} */
+       public static final String NETPOLICY_QUOTA_FRAC_JOBS = "netpolicy_quota_frac_jobs";
+       /** {@hide} */
+       public static final String NETPOLICY_QUOTA_FRAC_MULTIPATH = "netpolicy_quota_frac_multipath";
+
+       /** {@hide} */
+       public static final String NETPOLICY_OVERRIDE_ENABLED = "netpolicy_override_enabled";
+
        /**
         * User preference for which network(s) should be used. Only the
         * connectivity service should touch this.
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 3830b7a..daecea7 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -1487,14 +1487,18 @@
     /**
      * Returns a description of the current do not disturb settings from config.
      * - If turned on manually and end time is known, returns end time.
+     * - If turned on manually and end time is on forever until turned off, return null if
+     * describeForeverCondition is false, else return String describing indefinite behavior
      * - If turned on by an automatic rule, returns the automatic rule name.
      * - If on due to an app, returns the app name.
      * - If there's a combination of rules/apps that trigger, then shows the one that will
      *  last the longest if applicable.
-     * @return null if do not disturb is off.
+     * @return null if DND is off or describeForeverCondition is false and
+     * DND is on forever (until turned off)
      */
-    public static String getDescription(Context context, boolean zenOn, ZenModeConfig config) {
-        if (!zenOn) {
+    public static String getDescription(Context context, boolean zenOn, ZenModeConfig config,
+            boolean describeForeverCondition) {
+        if (!zenOn || config == null) {
             return null;
         }
 
@@ -1513,8 +1517,11 @@
             } else {
                 if (id == null) {
                     // Do not disturb manually triggered to remain on forever until turned off
-                    // No subtext
-                    return null;
+                    if (describeForeverCondition) {
+                        return context.getString(R.string.zen_mode_forever);
+                    } else {
+                        return null;
+                    }
                 } else {
                     latestEndTime = tryParseCountdownConditionId(id);
                     if (latestEndTime > 0) {
diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java
index 9f115eb..975ad48 100644
--- a/core/java/android/util/RecurrenceRule.java
+++ b/core/java/android/util/RecurrenceRule.java
@@ -158,7 +158,7 @@
                 && period.getDays() == 0;
     }
 
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         if (period != null) {
             return new RecurringIterator();
         } else {
@@ -166,7 +166,7 @@
         }
     }
 
-    private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+    private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> {
         boolean hasNext;
 
         public NonrecurringIterator() {
@@ -179,13 +179,13 @@
         }
 
         @Override
-        public Pair<ZonedDateTime, ZonedDateTime> next() {
+        public Range<ZonedDateTime> next() {
             hasNext = false;
-            return new Pair<>(start, end);
+            return new Range<>(start, end);
         }
     }
 
-    private class RecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+    private class RecurringIterator implements Iterator<Range<ZonedDateTime>> {
         int i;
         ZonedDateTime cycleStart;
         ZonedDateTime cycleEnd;
@@ -231,12 +231,12 @@
         }
 
         @Override
-        public Pair<ZonedDateTime, ZonedDateTime> next() {
+        public Range<ZonedDateTime> next() {
             if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
-            Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd);
+            Range<ZonedDateTime> r = new Range<>(cycleStart, cycleEnd);
             i--;
             updateCycle();
-            return p;
+            return r;
         }
     }
 
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index f0f30a0..372362f 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -503,6 +503,14 @@
 
     /**
      * @hide
+     * @return {@code true} if the IME is a trusted system component (e.g. pre-installed)
+     */
+    public boolean isSystem() {
+        return (mService.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
+    /**
+     * @hide
      */
     public boolean isAuxiliaryIme() {
         return mIsAuxIme;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 9a082ec..ddba477 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -129,16 +129,16 @@
     }
     // ----------------------------------------------------------------------
 
-    public static boolean isSystemIme(InputMethodInfo inputMethod) {
-        return (inputMethod.getServiceInfo().applicationInfo.flags
-                & ApplicationInfo.FLAG_SYSTEM) != 0;
+    @Deprecated
+    public static boolean isSystemIme(@NonNull InputMethodInfo inputMethod) {
+        return inputMethod.isSystem();
     }
 
     public static boolean isSystemImeThatHasSubtypeOf(final InputMethodInfo imi,
             final Context context, final boolean checkDefaultAttribute,
             @Nullable final Locale requiredLocale, final boolean checkCountry,
             final String requiredSubtypeMode) {
-        if (!isSystemIme(imi)) {
+        if (!imi.isSystem()) {
             return false;
         }
         if (checkDefaultAttribute && !imi.isDefault(context)) {
@@ -182,7 +182,7 @@
 
     private static boolean isSystemAuxilialyImeThatHasAutomaticSubtype(final InputMethodInfo imi,
             final Context context, final boolean checkDefaultAttribute) {
-        if (!isSystemIme(imi)) {
+        if (!imi.isSystem()) {
             return false;
         }
         if (checkDefaultAttribute && !imi.isDefault(context)) {
@@ -435,12 +435,11 @@
             if (imi.isAuxiliaryIme()) {
                 continue;
             }
-            if (InputMethodUtils.isSystemIme(imi)
-                    && containsSubtypeOf(imi, ENGLISH_LOCALE, false /* checkCountry */,
-                            SUBTYPE_MODE_KEYBOARD)) {
+            if (imi.isSystem() && containsSubtypeOf(
+                    imi, ENGLISH_LOCALE, false /* checkCountry */, SUBTYPE_MODE_KEYBOARD)) {
                 return imi;
             }
-            if (firstFoundSystemIme < 0 && InputMethodUtils.isSystemIme(imi)) {
+            if (firstFoundSystemIme < 0 && imi.isSystem()) {
                 firstFoundSystemIme = i;
             }
         }
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index 3de8c39..237efd8 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -213,6 +213,13 @@
     optional SettingProto keyguard_slice_uri = 29;
     optional SettingProto last_setup_shown = 30 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
+    message Launcher {
+        option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+        optional SettingProto swipe_up_to_switch_apps_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional Launcher launcher = 70;
+
     message Location {
         option (android.msg_privacy).dest = DEST_EXPLICIT;
 
@@ -479,5 +486,5 @@
 
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 70;
+    // Next tag = 71;
 }
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index da15506..c5ab2e6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -487,6 +487,7 @@
     <protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
     <protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
     <protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
+    <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" />
 
     <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
     <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 8443a67..4ce89c9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -974,6 +974,9 @@
     -->
     <integer name="config_longPressOnBackBehavior">0</integer>
 
+    <!-- Allows activities to be launched on a long press on power during device setup. -->
+    <bool name="config_allowStartActivityForLongPressOnPowerInSetup">false</bool>
+
     <!-- Control the behavior when the user short presses the power button.
             0 - Nothing
             1 - Go to sleep (doze)
diff --git a/core/res/res/values/styles_device_defaults.xml b/core/res/res/values/styles_device_defaults.xml
index f8659e2..d722961 100644
--- a/core/res/res/values/styles_device_defaults.xml
+++ b/core/res/res/values/styles_device_defaults.xml
@@ -128,6 +128,9 @@
     <style name="Widget.DeviceDefault.TextSelectHandle" parent="Widget.Material.TextSelectHandle"/>
     <style name="Widget.DeviceDefault.TextView.ListSeparator" parent="Widget.Material.TextView.ListSeparator"/>
     <style name="Widget.DeviceDefault.TimePicker" parent="Widget.Material.TimePicker"/>
+    <style name="Widget.DeviceDefault.Toolbar" parent="Widget.Material.Toolbar">
+        <item name="titleTextAppearance">@style/TextAppearance.DeviceDefault.Widget.Toolbar.Title</item>
+    </style>
 
     <style name="Widget.DeviceDefault.Light" parent="Widget.Material.Light"/>
     <style name="Widget.DeviceDefault.Light.Button" parent="Widget.Material.Light.Button"/>
@@ -186,7 +189,9 @@
     <style name="Widget.DeviceDefault.Light.ActionBar.TabView" parent="Widget.Material.Light.ActionBar.TabView"/>
     <style name="Widget.DeviceDefault.Light.ActionBar.TabText" parent="Widget.Material.Light.ActionBar.TabText"/>
     <style name="Widget.DeviceDefault.Light.ActionBar.TabBar" parent="Widget.Material.Light.ActionBar.TabBar"/>
-    <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Material.Light.ActionBar.Solid"/>
+    <style name="Widget.DeviceDefault.Light.ActionBar.Solid" parent="Widget.Material.Light.ActionBar.Solid">
+        <item name="titleTextStyle">@style/TextAppearance.DeviceDefault.Widget.ActionBar.Title</item>
+    </style>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
     <style name="Widget.DeviceDefault.Light.ActionBar.Solid.Inverse" parent="Widget.Holo.Light.ActionBar.Solid.Inverse"/>
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
@@ -242,7 +247,9 @@
     <style name="TextAppearance.DeviceDefault.Widget.PopupMenu" parent="TextAppearance.Material.Widget.PopupMenu"/>
     <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Large" parent="TextAppearance.Material.Widget.PopupMenu.Large"/>
     <style name="TextAppearance.DeviceDefault.Widget.PopupMenu.Small" parent="TextAppearance.Material.Widget.PopupMenu.Small"/>
-    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title"/>
+    <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title">
+        <item name="fontFamily">@string/config_headlineFontFamilyMedium</item>
+    </style>
     <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Widget.ActionBar.Subtitle"/>
     <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Title" parent="TextAppearance.Material.Widget.ActionMode.Title"/>
     <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle" parent="TextAppearance.Material.Widget.ActionMode.Subtitle"/>
@@ -261,6 +268,7 @@
     <!-- @deprecated Action bars are now themed using the inheritable android:theme attribute. -->
     <style name="TextAppearance.DeviceDefault.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse"/>
     <style name="TextAppearance.DeviceDefault.Widget.ActionBar.Menu" parent="TextAppearance.Material.Widget.ActionBar.Menu"/>
+    <style name="TextAppearance.DeviceDefault.Widget.Toolbar.Title" parent="TextAppearance.DeviceDefault.Widget.ActionBar.Title" />
 
     <!-- Preference Styles -->
     <style name="Preference.DeviceDefault" parent="Preference.Material"/>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5856648..ce7f1ff 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -434,6 +434,7 @@
   <java-symbol type="integer" name="config_veryLongPressOnPowerBehavior" />
   <java-symbol type="integer" name="config_veryLongPressTimeout" />
   <java-symbol type="integer" name="config_longPressOnBackBehavior" />
+  <java-symbol type="bool" name="config_allowStartActivityForLongPressOnPowerInSetup" />
   <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" />
   <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" />
   <java-symbol type="integer" name="config_max_pan_devices" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index cf7b3b6..fd6cc95 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -181,6 +181,9 @@
         <item name="actionBarStyle">@style/Widget.DeviceDefault.ActionBar.Solid</item>
         <item name="actionModePopupWindowStyle">@style/Widget.DeviceDefault.PopupWindow.ActionMode</item>
 
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
         <item name="buttonBarStyle">@style/DeviceDefault.ButtonBar</item>
         <item name="segmentedButtonStyle">@style/DeviceDefault.SegmentedButton</item>
 
@@ -233,6 +236,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
@@ -257,6 +263,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -283,6 +292,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -308,6 +320,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -341,6 +356,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -365,6 +383,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -388,6 +409,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -412,6 +436,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -452,6 +479,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -477,6 +507,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -500,6 +533,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -525,6 +561,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -549,6 +588,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -573,6 +615,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -597,6 +642,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -621,6 +669,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -645,6 +696,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.SearchBar" parent="Theme.Material.SearchBar">
@@ -667,6 +721,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -689,6 +746,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -822,6 +882,9 @@
         <item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item>
         <item name="actionModePopupWindowStyle">@style/Widget.DeviceDefault.Light.PopupWindow.ActionMode</item>
 
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
         <item name="buttonBarStyle">@style/DeviceDefault.Light.ButtonBar</item>
         <item name="segmentedButtonStyle">@style/DeviceDefault.Light.SegmentedButton</item>
 
@@ -869,6 +932,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -892,6 +958,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -916,6 +985,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -942,6 +1014,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -967,6 +1042,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -998,6 +1076,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -1025,6 +1106,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
      <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -1051,6 +1135,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -1078,6 +1165,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1131,6 +1221,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -1159,6 +1252,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -1185,6 +1281,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -1210,6 +1309,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -1234,6 +1336,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
@@ -1256,6 +1361,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -1278,11 +1386,15 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
     <style name="Theme.DeviceDefault.Settings" parent="Theme.Material.Settings">
         <!-- action bar -->
+        <item name="actionBarStyle">@style/Widget.DeviceDefault.Light.ActionBar.Solid</item>
         <item name="actionBarTheme">@style/ThemeOverlay.DeviceDefault.ActionBar.Accent</item>
         <item name="popupTheme">@style/ThemeOverlay.DeviceDefault.Popup.Light</item>
 
@@ -1313,6 +1425,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- @hide DeviceDefault theme for a window that should use Settings theme colors
@@ -1337,6 +1452,9 @@
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
 
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
         <!-- volume background -->
         <item name="panelColorBackground">@color/primary_material_light</item>
     </style>
@@ -1352,6 +1470,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -1376,6 +1497,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.Material.Settings.Dialog">
@@ -1402,6 +1526,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.DialogWhenLarge" parent="Theme.Material.Settings.DialogWhenLarge">
@@ -1428,6 +1555,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -1454,6 +1584,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -1488,6 +1621,9 @@
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
         <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
     <!-- DeviceDefault theme for the default system theme.  -->
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index d75a476..613ab6d 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -303,6 +303,12 @@
                     Settings.Global.NETSTATS_UID_TAG_DELETE_AGE,
                     Settings.Global.NETSTATS_UID_TAG_PERSIST_BYTES,
                     Settings.Global.NETSTATS_UID_TAG_ROTATE_AGE,
+                    Settings.Global.NETPOLICY_QUOTA_ENABLED,
+                    Settings.Global.NETPOLICY_QUOTA_UNLIMITED,
+                    Settings.Global.NETPOLICY_QUOTA_LIMITED,
+                    Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS,
+                    Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH,
+                    Settings.Global.NETPOLICY_OVERRIDE_ENABLED,
                     Settings.Global.NETWORK_AVOID_BAD_WIFI,
                     Settings.Global.NETWORK_DEFAULT_DAILY_MULTIPATH_QUOTA_BYTES,
                     Settings.Global.NETWORK_METERED_MULTIPATH_PREFERENCE,
diff --git a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
index 42b6048..39d492d 100644
--- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
+++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
@@ -57,13 +57,13 @@
 
         assertTrue(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2015-11-14T00:00:00.00Z"),
                 ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next());
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2015-10-14T00:00:00.00Z"),
                 ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next());
     }
@@ -77,13 +77,13 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-17T00:11:00.00Z"),
                 ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next());
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-14T00:11:00.00Z"),
                 ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next());
         assertFalse(it.hasNext());
@@ -98,9 +98,9 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-14T00:11:00.000Z"),
                 ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next());
         assertFalse(it.hasNext());
@@ -112,7 +112,7 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertFalse(it.hasNext());
     }
 
@@ -122,22 +122,22 @@
                 ZonedDateTime.parse("2030-01-31T00:00:00.000Z"),
                 Period.ofMonths(1));
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         ZonedDateTime lastStart = null;
         int months = 0;
         while (it.hasNext()) {
-            final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
+            final Range<ZonedDateTime> cycle = it.next();
 
             // Make sure cycle has reasonable length
-            final long length = cycle.second.toEpochSecond() - cycle.first.toEpochSecond();
+            final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond();
             assertTrue(cycle + " must be more than 4 weeks", length >= 2419200);
             assertTrue(cycle + " must be less than 5 weeks", length <= 3024000);
 
             // Make sure we have no gaps
             if (lastStart != null) {
-                assertEquals(lastStart, cycle.second);
+                assertEquals(lastStart, cycle.getUpper());
             }
-            lastStart = cycle.first;
+            lastStart = cycle.getLower();
             months++;
         }
 
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 20c22b7..18dd97f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -738,6 +738,23 @@
     /**
      * Creates a typeface object that best matches the specified existing typeface and the specified
      * weight and italic style
+     * <p>Below are numerical values and corresponding common weight names.</p>
+     * <table>
+     * <thead>
+     * <tr><th>Value</th><th>Common weight name</th></tr>
+     * </thead>
+     * <tbody>
+     * <tr><td>100</td><td>Thin</td></tr>
+     * <tr><td>200</td><td>Extra Light</td></tr>
+     * <tr><td>300</td><td>Light</td></tr>
+     * <tr><td>400</td><td>Normal</td></tr>
+     * <tr><td>500</td><td>Medium</td></tr>
+     * <tr><td>600</td><td>Semi Bold</td></tr>
+     * <tr><td>700</td><td>Bold</td></tr>
+     * <tr><td>800</td><td>Extra Bold</td></tr>
+     * <tr><td>900</td><td>Black</td></tr>
+     * </tbody>
+     * </table>
      *
      * <p>
      * This method is thread safe.
@@ -749,6 +766,9 @@
      * @param italic {@code true} if italic style is desired to be drawn. Otherwise, {@code false}
      * @return A {@link Typeface} object for drawing specified weight and italic style. Never
      *         returns {@code null}
+     *
+     * @see #getWeight()
+     * @see #isItalic()
      */
     public static @NonNull Typeface create(@Nullable Typeface family,
             @IntRange(from = 1, to = 1000) int weight, boolean italic) {
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 0a6c45b..7b14322 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -36,6 +36,7 @@
 bool Properties::skipEmptyFrames = true;
 bool Properties::useBufferAge = true;
 bool Properties::enablePartialUpdates = true;
+bool Properties::usePresentTime = true;
 
 DebugLevel Properties::debugLevel = kDebugDisabled;
 OverdrawColorSet Properties::overdrawColorSet = OverdrawColorSet::Default;
@@ -135,6 +136,7 @@
     skipEmptyFrames = property_get_bool(PROPERTY_SKIP_EMPTY_DAMAGE, true);
     useBufferAge = property_get_bool(PROPERTY_USE_BUFFER_AGE, true);
     enablePartialUpdates = property_get_bool(PROPERTY_ENABLE_PARTIAL_UPDATES, true);
+    usePresentTime = property_get_bool(PROPERTY_USE_PRESENT_TIME, true);
 
     filterOutTestOverhead = property_get_bool(PROPERTY_FILTER_TEST_OVERHEAD, false);
 
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 764c502..1a0bdfd 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -151,6 +151,12 @@
  */
 #define PROPERTY_ENABLE_PARTIAL_UPDATES "debug.hwui.use_partial_updates"
 
+/**
+ * Setting this to "false" will disable the use of the EGL_ANDROID_presentation_time extension
+ * and prevents more precise control over swap behavior & timings.
+ */
+#define PROPERTY_USE_PRESENT_TIME "debug.hwui.use_present_time"
+
 #define PROPERTY_FILTER_TEST_OVERHEAD "debug.hwui.filter_test_overhead"
 
 /**
@@ -220,6 +226,7 @@
     static bool skipEmptyFrames;
     static bool useBufferAge;
     static bool enablePartialUpdates;
+    static bool usePresentTime;
 
     // TODO: Move somewhere else?
     static constexpr float textGamma = 1.45f;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 0e4b6f9..d983200 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -17,6 +17,7 @@
 #include "CanvasContext.h"
 #include <GpuMemoryTracker.h>
 
+#include "../Properties.h"
 #include "AnimationContext.h"
 #include "Caches.h"
 #include "EglManager.h"
@@ -33,7 +34,6 @@
 #include "renderstate/Stencil.h"
 #include "utils/GLUtils.h"
 #include "utils/TimeUtils.h"
-#include "../Properties.h"
 
 #include <cutils/properties.h>
 #include <private/hwui/DrawGlInfo.h>
@@ -190,6 +190,7 @@
     if (hasSurface) {
         mHaveNewSurface = true;
         mSwapHistory.clear();
+        updateBufferCount();
     } else {
         mRenderThread.removeFrameCallback(this);
     }
@@ -423,6 +424,9 @@
 
     waitOnFences();
 
+    frame.setPresentTime(mCurrentFrameInfo->get(FrameInfoIndex::Vsync) +
+                         (mRenderThread.timeLord().frameIntervalNanos() * (mRenderAheadDepth + 1)));
+
     bool requireSwap = false;
     bool didSwap =
             mRenderPipeline->swapBuffers(frame, drew, windowDirty, mCurrentFrameInfo, &requireSwap);
@@ -668,6 +672,26 @@
     return mFrameNumber;
 }
 
+void overrideBufferCount(const sp<Surface>& surface, int bufferCount) {
+    struct SurfaceExposer : Surface {
+        using Surface::setBufferCount;
+    };
+    // Protected is just a sign, not a cop
+    ((*surface.get()).*&SurfaceExposer::setBufferCount)(bufferCount);
+}
+
+void CanvasContext::updateBufferCount() {
+    overrideBufferCount(mNativeSurface, 3 + mRenderAheadDepth);
+}
+
+void CanvasContext::setRenderAheadDepth(int renderAhead) {
+    if (renderAhead < 0 || renderAhead > 2 || renderAhead == mRenderAheadDepth) {
+        return;
+    }
+    mRenderAheadDepth = renderAhead;
+    updateBufferCount();
+}
+
 SkRect CanvasContext::computeDirtyRect(const Frame& frame, SkRect* dirty) {
     if (frame.width() != mLastFrameWidth || frame.height() != mLastFrameHeight) {
         // can't rely on prior content of window if viewport size changes
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index aaef85a..930498af3 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -78,7 +78,7 @@
     bool createOrUpdateLayer(RenderNode* node, const DamageAccumulator& dmgAccumulator,
                              ErrorHandler* errorHandler) {
         return mRenderPipeline->createOrUpdateLayer(node, dmgAccumulator, mWideColorGamut,
-                errorHandler);
+                                                    errorHandler);
     }
 
     /**
@@ -188,6 +188,8 @@
 
     IRenderPipeline* getRenderPipeline() { return mRenderPipeline.get(); }
 
+    void setRenderAheadDepth(int renderAhead);
+
 private:
     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
                   IContextFactory* contextFactory, std::unique_ptr<IRenderPipeline> renderPipeline);
@@ -200,6 +202,7 @@
     void freePrefetchedLayers();
 
     bool isSwapChainStuffed();
+    void updateBufferCount();
 
     SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
 
@@ -225,6 +228,7 @@
 
     RingBuffer<SwapHistory, 3> mSwapHistory;
     int64_t mFrameNumber = -1;
+    int mRenderAheadDepth = 0;
 
     // last vsync for a dropped frame due to stuffed queue
     nsecs_t mLastDropVsync = 0;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 778e768..5b0e281 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -103,9 +103,8 @@
 
     // Even if we aren't drawing this vsync pulse the next frame number will still be accurate
     if (CC_UNLIKELY(callback)) {
-        context->enqueueFrameWork([callback, frameNr = context->getFrameNumber()]() {
-            callback(frameNr);
-        });
+        context->enqueueFrameWork(
+                [ callback, frameNr = context->getFrameNumber() ]() { callback(frameNr); });
     }
 
     if (CC_LIKELY(canDrawThisFrame)) {
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 6e239e3..3a49beb 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -83,6 +83,7 @@
     bool glColorSpace = false;
     bool scRGB = false;
     bool contextPriority = false;
+    bool presentTime = false;
 } EglExtensions;
 
 EglManager::EglManager(RenderThread& thread)
@@ -170,6 +171,7 @@
     EglExtensions.scRGB = extensions.has("EGL_EXT_gl_colorspace_scrgb");
 #endif
     EglExtensions.contextPriority = extensions.has("EGL_IMG_context_priority");
+    EglExtensions.presentTime = extensions.has("EGL_ANDROID_presentation_time");
 }
 
 bool EglManager::hasEglContext() {
@@ -242,7 +244,7 @@
                              &numConfigs) ||
             numConfigs != 1) {
             ALOGE("Device claims wide gamut support, cannot find matching config, error = %s",
-                    eglErrorString());
+                  eglErrorString());
             EglExtensions.pixelFormatFloat = false;
         }
     }
@@ -437,6 +439,13 @@
         fence();
     }
 
+    if (EglExtensions.presentTime && Properties::usePresentTime) {
+        if (!eglPresentationTimeANDROID(mEglDisplay, frame.mSurface, frame.mPresentTime)) {
+            LOG_ALWAYS_FATAL("Failed to set presentation time on surface %p, error=%s",
+                             (void*)frame.mSurface, eglErrorString());
+        }
+    }
+
     EGLint rects[4];
     frame.map(screenDirty, rects);
     eglSwapBuffersWithDamageKHR(mEglDisplay, frame.mSurface, rects, screenDirty.isEmpty() ? 0 : 1);
diff --git a/libs/hwui/renderthread/Frame.h b/libs/hwui/renderthread/Frame.h
index d266faa..03cf95d 100644
--- a/libs/hwui/renderthread/Frame.h
+++ b/libs/hwui/renderthread/Frame.h
@@ -37,6 +37,8 @@
     // for what this means
     int32_t bufferAge() const { return mBufferAge; }
 
+    void setPresentTime(int64_t presentTime) { mPresentTime = presentTime; }
+
 private:
     Frame() {}
     friend class EglManager;
@@ -44,6 +46,7 @@
     int32_t mWidth;
     int32_t mHeight;
     int32_t mBufferAge;
+    int64_t mPresentTime;
 
     EGLSurface mSurface;
 
diff --git a/libs/hwui/renderthread/OpenGLPipeline.cpp b/libs/hwui/renderthread/OpenGLPipeline.cpp
index 876af47..1925808 100644
--- a/libs/hwui/renderthread/OpenGLPipeline.cpp
+++ b/libs/hwui/renderthread/OpenGLPipeline.cpp
@@ -22,8 +22,8 @@
 #include "GlLayer.h"
 #include "OpenGLReadback.h"
 #include "ProfileRenderer.h"
-#include "renderstate/RenderState.h"
 #include "TreeInfo.h"
+#include "renderstate/RenderState.h"
 
 #include <cutils/properties.h>
 #include <strings.h>
@@ -203,8 +203,7 @@
 
 bool OpenGLPipeline::createOrUpdateLayer(RenderNode* node,
                                          const DamageAccumulator& damageAccumulator,
-                                         bool wideColorGamut,
-                                         ErrorHandler* errorHandler) {
+                                         bool wideColorGamut, ErrorHandler* errorHandler) {
     RenderState& renderState = mRenderThread.renderState();
     OffscreenBufferPool& layerPool = renderState.layerPool();
     bool transformUpdateNeeded = false;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 39dcde0..a1a2bad 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -286,6 +286,12 @@
     });
 }
 
+void RenderProxy::setRenderAheadDepth(int renderAhead) {
+    mRenderThread.queue().post([ context = mContext, renderAhead ]() {
+        context->setRenderAheadDepth(renderAhead);
+    });
+}
+
 int RenderProxy::copySurfaceInto(sp<Surface>& surface, int left, int top, int right, int bottom,
                                  SkBitmap* bitmap) {
     auto& thread = RenderThread::getInstance();
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 433adeb..ca20755 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -117,7 +117,23 @@
 
     ANDROID_API void addFrameMetricsObserver(FrameMetricsObserver* observer);
     ANDROID_API void removeFrameMetricsObserver(FrameMetricsObserver* observer);
-    ANDROID_API long getDroppedFrameReportCount();
+
+    /**
+     * Sets a render-ahead depth on the backing renderer. This will increase latency by
+     * <swapInterval> * renderAhead and increase memory usage by (3 + renderAhead) * <resolution>.
+     * In return the renderer will be less susceptible to jitter, resulting in a smoother animation.
+     *
+     * Not recommended to use in response to anything touch driven, but for canned animations
+     * where latency is not a concern careful use may be beneficial.
+     *
+     * Note that when increasing this there will be a frame gap of N frames where N is
+     * renderAhead - <current renderAhead>. When decreasing this if there are any pending
+     * frames they will retain their prior renderAhead value, so it will take a few frames
+     * for the decrease to flush through.
+     *
+     * @param renderAhead How far to render ahead, must be in the range [0..2]
+     */
+    ANDROID_API void setRenderAheadDepth(int renderAhead);
 
     ANDROID_API static int copySurfaceInto(sp<Surface>& surface, int left, int top, int right,
                                            int bottom, SkBitmap* bitmap);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 6a2a025..4b154e6 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -25,8 +25,8 @@
 #include "hwui/Bitmap.h"
 #include "pipeline/skia/SkiaOpenGLPipeline.h"
 #include "pipeline/skia/SkiaOpenGLReadback.h"
-#include "pipeline/skia/SkiaVulkanReadback.h"
 #include "pipeline/skia/SkiaVulkanPipeline.h"
+#include "pipeline/skia/SkiaVulkanReadback.h"
 #include "renderstate/RenderState.h"
 #include "renderthread/OpenGLPipeline.h"
 #include "utils/FatVector.h"
@@ -93,14 +93,11 @@
     DummyVsyncSource(RenderThread* renderThread) : mRenderThread(renderThread) {}
 
     virtual void requestNextVsync() override {
-        mRenderThread->queue().postDelayed(16_ms, [this]() {
-            mRenderThread->drainDisplayEventQueue();
-        });
+        mRenderThread->queue().postDelayed(16_ms,
+                                           [this]() { mRenderThread->drainDisplayEventQueue(); });
     }
 
-    virtual nsecs_t latestVsyncEvent() override {
-        return systemTime(CLOCK_MONOTONIC);
-    }
+    virtual nsecs_t latestVsyncEvent() override { return systemTime(CLOCK_MONOTONIC); }
 
 private:
     RenderThread* mRenderThread;
@@ -147,13 +144,13 @@
         auto receiver = std::make_unique<DisplayEventReceiver>();
         status_t status = receiver->initCheck();
         LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
-                "Initialization of DisplayEventReceiver "
-                        "failed with status: %d",
-                status);
+                            "Initialization of DisplayEventReceiver "
+                            "failed with status: %d",
+                            status);
 
         // Register the FD
         mLooper->addFd(receiver->getFd(), 0, Looper::EVENT_INPUT,
-                RenderThread::displayEventReceiverCallback, this);
+                       RenderThread::displayEventReceiverCallback, this);
         mVsyncSource = new DisplayEventReceiverWrapper(std::move(receiver));
     } else {
         mVsyncSource = new DummyVsyncSource(this);
diff --git a/libs/hwui/tests/common/TestScene.h b/libs/hwui/tests/common/TestScene.h
index 91022cf..74a039b 100644
--- a/libs/hwui/tests/common/TestScene.h
+++ b/libs/hwui/tests/common/TestScene.h
@@ -38,6 +38,7 @@
         int count = 0;
         int reportFrametimeWeight = 0;
         bool renderOffscreen = true;
+        int renderAhead = 0;
     };
 
     template <class T>
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 9428f53..854a449 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -153,6 +153,12 @@
     proxy->resetProfileInfo();
     proxy->fence();
 
+    if (opts.renderAhead) {
+        // Need to let the queue drain to see render-ahead in action.
+        usleep(33000);
+    }
+    proxy->setRenderAheadDepth(opts.renderAhead);
+
     ModifiedMovingAverage<double> avgMs(opts.reportFrametimeWeight);
 
     nsecs_t start = systemTime(CLOCK_MONOTONIC);
diff --git a/libs/hwui/tests/macrobench/main.cpp b/libs/hwui/tests/macrobench/main.cpp
index a56b1dd..072719b 100644
--- a/libs/hwui/tests/macrobench/main.cpp
+++ b/libs/hwui/tests/macrobench/main.cpp
@@ -67,6 +67,7 @@
                        are offscreen rendered
   --benchmark_format   Set output format. Possible values are tabular, json, csv
   --renderer=TYPE      Sets the render pipeline to use. May be opengl, skiagl, or skiavk
+  --render-ahead=NUM   Sets how far to render-ahead. Must be 0 (default), 1, or 2.
 )");
 }
 
@@ -172,6 +173,7 @@
     Onscreen,
     Offscreen,
     Renderer,
+    RenderAhead,
 };
 }
 
@@ -187,6 +189,7 @@
         {"onscreen", no_argument, nullptr, LongOpts::Onscreen},
         {"offscreen", no_argument, nullptr, LongOpts::Offscreen},
         {"renderer", required_argument, nullptr, LongOpts::Renderer},
+        {"render-ahead", required_argument, nullptr, LongOpts::RenderAhead},
         {0, 0, 0, 0}};
 
 static const char* SHORT_OPTIONS = "c:r:h";
@@ -285,6 +288,16 @@
                 gOpts.renderOffscreen = true;
                 break;
 
+            case LongOpts::RenderAhead:
+                if (!optarg) {
+                    error = true;
+                }
+                gOpts.renderAhead = atoi(optarg);
+                if (gOpts.renderAhead < 0 || gOpts.renderAhead > 2) {
+                    error = true;
+                }
+                break;
+
             case 'h':
                 printHelp();
                 exit(EXIT_SUCCESS);
diff --git a/media/java/android/media/PlaybackParams.java b/media/java/android/media/PlaybackParams.java
index 938a953..b85e4d0 100644
--- a/media/java/android/media/PlaybackParams.java
+++ b/media/java/android/media/PlaybackParams.java
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.annotation.IntDef;
+import android.annotation.TestApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -151,6 +152,7 @@
      * @param audioStretchMode
      * @return this <code>PlaybackParams</code> instance.
      */
+    @TestApi
     public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) {
         mAudioStretchMode = audioStretchMode;
         mSet |= SET_AUDIO_STRETCH_MODE;
@@ -163,6 +165,7 @@
      * @return audio stretch mode
      * @throws IllegalStateException if the audio stretch mode is not set.
      */
+    @TestApi
     public @AudioStretchMode int getAudioStretchMode() {
         if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) {
             throw new IllegalStateException("audio stretch mode not set");
diff --git a/packages/SettingsLib/res/layout/preference_category_material_settings.xml b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
index 245e3b7..1086106 100644
--- a/packages/SettingsLib/res/layout/preference_category_material_settings.xml
+++ b/packages/SettingsLib/res/layout/preference_category_material_settings.xml
@@ -50,6 +50,7 @@
             android:layout_marginTop="16dp"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
             android:textAppearance="@android:style/TextAppearance.Material.Body2"
             android:textAlignment="viewStart"
             android:textColor="?android:attr/colorAccent"
diff --git a/packages/SettingsLib/res/values/dimens.xml b/packages/SettingsLib/res/values/dimens.xml
index 7b09ef7..cf4261c 100644
--- a/packages/SettingsLib/res/values/dimens.xml
+++ b/packages/SettingsLib/res/values/dimens.xml
@@ -33,6 +33,8 @@
     <dimen name="user_spinner_item_height">56dp</dimen>
 
     <dimen name="two_target_pref_small_icon_size">24dp</dimen>
+    <dimen name="two_target_pref_medium_icon_size">32dp</dimen>
+
     <!-- Lock icon for preferences locked by admin -->
     <dimen name="restricted_icon_size">16dp</dimen>
     <dimen name="restricted_icon_padding">4dp</dimen>
diff --git a/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java b/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
index 8b39f60..02b68d8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/TwoTargetPreference.java
@@ -16,6 +16,7 @@
 
 package com.android.settingslib;
 
+import android.annotation.IntDef;
 import android.content.Context;
 import android.support.v7.preference.Preference;
 import android.support.v7.preference.PreferenceViewHolder;
@@ -24,10 +25,24 @@
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 public class TwoTargetPreference extends Preference {
 
-    private boolean mUseSmallIcon;
+    @IntDef({ICON_SIZE_DEFAULT, ICON_SIZE_MEDIUM, ICON_SIZE_SMALL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface IconSize {
+    }
+
+    public static final int ICON_SIZE_DEFAULT = 0;
+    public static final int ICON_SIZE_MEDIUM = 1;
+    public static final int ICON_SIZE_SMALL = 2;
+
+    @IconSize
+    private int mIconSize;
     private int mSmallIconSize;
+    private int mMediumIconSize;
 
     public TwoTargetPreference(Context context, AttributeSet attrs,
             int defStyleAttr, int defStyleRes) {
@@ -54,22 +69,30 @@
         setLayoutResource(R.layout.preference_two_target);
         mSmallIconSize = context.getResources().getDimensionPixelSize(
                 R.dimen.two_target_pref_small_icon_size);
+        mMediumIconSize = context.getResources().getDimensionPixelSize(
+                R.dimen.two_target_pref_medium_icon_size);
         final int secondTargetResId = getSecondTargetResId();
         if (secondTargetResId != 0) {
             setWidgetLayoutResource(secondTargetResId);
         }
     }
 
-    public void setUseSmallIcon(boolean useSmallIcon) {
-        mUseSmallIcon = useSmallIcon;
+    public void setIconSize(@IconSize int iconSize) {
+        mIconSize = iconSize;
     }
 
     @Override
     public void onBindViewHolder(PreferenceViewHolder holder) {
         super.onBindViewHolder(holder);
-        if (mUseSmallIcon) {
-            ImageView icon = holder.itemView.findViewById(android.R.id.icon);
-            icon.setLayoutParams(new LinearLayout.LayoutParams(mSmallIconSize, mSmallIconSize));
+        final ImageView icon = holder.itemView.findViewById(android.R.id.icon);
+        switch (mIconSize) {
+            case ICON_SIZE_SMALL:
+                icon.setLayoutParams(new LinearLayout.LayoutParams(mSmallIconSize, mSmallIconSize));
+                break;
+            case ICON_SIZE_MEDIUM:
+                icon.setLayoutParams(
+                        new LinearLayout.LayoutParams(mMediumIconSize, mMediumIconSize));
+                break;
         }
         final View divider = holder.findViewById(R.id.two_target_divider);
         final View widgetFrame = holder.findViewById(android.R.id.widget_frame);
diff --git a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
index 835ff07..f7b16f8 100644
--- a/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/fuelgauge/BatterySaverUtils.java
@@ -148,15 +148,32 @@
         Secure.putInt(context.getContentResolver(), Secure.LOW_POWER_WARNING_ACKNOWLEDGED, 1);
     }
 
+    /**
+     * Don't show the automatic battery suggestion notification in the future.
+     */
     public static void suppressAutoBatterySaver(Context context) {
         Secure.putInt(context.getContentResolver(),
                 Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, 1);
     }
 
-    public static void scheduleAutoBatterySaver(Context context, int level) {
+    /**
+     * Set the automatic battery saver trigger level to {@code level}.
+     */
+    public static void setAutoBatterySaverTriggerLevel(Context context, int level) {
+        if (level > 0) {
+            suppressAutoBatterySaver(context);
+        }
+        Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level);
+    }
+
+    /**
+     * Set the automatic battery saver trigger level to {@code level}, but only when
+     * automatic battery saver isn't enabled yet.
+     */
+    public static void ensureAutoBatterySaver(Context context, int level) {
         if (Global.getInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, 0)
                 == 0) {
-            Global.putInt(context.getContentResolver(), Global.LOW_POWER_MODE_TRIGGER_LEVEL, level);
+            setAutoBatterySaverTriggerLevel(context, level);
         }
     }
 }
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
index 55be137..e63bdd6 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodAndSubtypeUtil.java
@@ -35,7 +35,6 @@
 import android.view.inputmethod.InputMethodSubtype;
 
 import com.android.internal.app.LocaleHelper;
-import com.android.internal.inputmethod.InputMethodUtils;
 
 import java.util.HashMap;
 import java.util.HashSet;
@@ -176,7 +175,7 @@
                     ((TwoStatePreference) pref).isChecked()
                     : enabledIMEsAndSubtypesMap.containsKey(imiId);
             final boolean isCurrentInputMethod = imiId.equals(currentInputMethodId);
-            final boolean systemIme = InputMethodUtils.isSystemIme(imi);
+            final boolean systemIme = imi.isSystem();
             if ((!hasHardKeyboard && InputMethodSettingValuesWrapper.getInstance(
                     context.getActivity()).isAlwaysCheckedIme(imi, context.getActivity()))
                     || isImeChecked) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
index 5e25f51..649a864 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodPreference.java
@@ -35,7 +35,6 @@
 import android.widget.Toast;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.inputmethod.InputMethodUtils;
 import com.android.settingslib.R;
 import com.android.settingslib.RestrictedLockUtils;
 import com.android.settingslib.RestrictedSwitchPreference;
@@ -124,7 +123,7 @@
             setIntent(intent);
         }
         mInputMethodSettingValues = InputMethodSettingValuesWrapper.getInstance(context);
-        mHasPriorityInSorting = InputMethodUtils.isSystemIme(imi)
+        mHasPriorityInSorting = imi.isSystem()
                 && mInputMethodSettingValues.isValidSystemNonAuxAsciiCapableIme(imi, context);
         setOnPreferenceClickListener(this);
         setOnPreferenceChangeListener(this);
@@ -153,7 +152,7 @@
             setCheckedInternal(false);
             return false;
         }
-        if (InputMethodUtils.isSystemIme(mImi)) {
+        if (mImi.isSystem()) {
             // Enable a system IME. No need to show a security warning dialog,
             // but we might need to prompt if it's not Direct Boot aware.
             // TV doesn't doesn't need to worry about this, but other platforms should show
diff --git a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
index fac50bd..554fb35 100644
--- a/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/inputmethod/InputMethodSettingValuesWrapper.java
@@ -129,7 +129,7 @@
 
         return enabledValidSystemNonAuxAsciiCapableImeCount <= 1
                 && !(enabledValidSystemNonAuxAsciiCapableImeCount == 1 && !isEnabled)
-                && InputMethodUtils.isSystemIme(imi)
+                && imi.isSystem()
                 && isValidSystemNonAuxAsciiCapableIme(imi, context);
 
     }
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
index c5e93f0..480143a7 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/TwoTargetPreferenceTest.java
@@ -16,6 +16,9 @@
 
 package com.android.settingslib;
 
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_DEFAULT;
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_MEDIUM;
+import static com.android.settingslib.TwoTargetPreference.ICON_SIZE_SMALL;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
@@ -75,8 +78,8 @@
     }
 
     @Test
-    public void bind_smallIcon_shouldUseSmallIcon() {
-        mPreference.setUseSmallIcon(true);
+    public void bind_smallIcon_shouldUseSmallIconSize() {
+        mPreference.setIconSize(ICON_SIZE_SMALL);
 
         mPreference.onBindViewHolder(mViewHolder);
 
@@ -91,8 +94,24 @@
     }
 
     @Test
-    public void bind_normalIcon_shouldUseNormalIcon() {
-        mPreference.setUseSmallIcon(false);
+    public void bind_mediumIcon_shouldUseMediumIconSize() {
+        mPreference.setIconSize(ICON_SIZE_MEDIUM);
+
+        mPreference.onBindViewHolder(mViewHolder);
+
+        final int size = mContext.getResources().getDimensionPixelSize(
+                R.dimen.two_target_pref_medium_icon_size);
+        final LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mViewHolder
+                .findViewById(android.R.id.icon)
+                .getLayoutParams();
+
+        assertThat(layoutParams.width).isEqualTo(size);
+        assertThat(layoutParams.height).isEqualTo(size);
+    }
+
+    @Test
+    public void bind_defaultIcon_shouldUseDefaultIconSize() {
+        mPreference.setIconSize(ICON_SIZE_DEFAULT);
 
         mPreference.onBindViewHolder(mViewHolder);
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
index b33df30..ba5a2c5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/fuelgauge/BatterySaverUtilsTest.java
@@ -16,7 +16,9 @@
 
 package com.android.settingslib.fuelgauge;
 
+import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.eq;
@@ -28,6 +30,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.PowerManager;
+import android.provider.Settings.Global;
 import android.provider.Settings.Secure;
 
 import com.android.settingslib.SettingsLibRobolectricTestRunner;
@@ -41,6 +44,9 @@
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class BatterySaverUtilsTest {
+    final int BATTERY_SAVER_THRESHOLD_1 = 15;
+    final int BATTERY_SAVER_THRESHOLD_2 = 20;
+
     @Mock
     Context mMockContext;
 
@@ -149,4 +155,37 @@
         assertEquals(-2,
                 Secure.getInt(mMockResolver, Secure.LOW_POWER_MANUAL_ACTIVATION_COUNT, -2));
     }
+
+    @Test
+    public void testEnsureAutoBatterysaver_setNewPositiveValue_doNotOverwrite() throws Exception {
+        Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
+
+        BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_1);
+
+        assertThat(Secure.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+                .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+
+        // Once a positive number is set, ensureAutoBatterySaver() won't overwrite it.
+        BatterySaverUtils.ensureAutoBatterySaver(mMockContext, BATTERY_SAVER_THRESHOLD_2);
+        assertThat(Secure.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+                .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+    }
+
+    @Test
+    public void testSetAutoBatterySaverTriggerLevel_setSuppressSuggestion() throws Exception {
+        Global.putString(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, "null");
+        Secure.putString(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, "null");
+
+        BatterySaverUtils.setAutoBatterySaverTriggerLevel(mMockContext, 0);
+        assertThat(Global.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+                .isEqualTo(0);
+        assertThat(Secure.getInt(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, -1))
+                .isEqualTo(-1); // not set.
+
+        BatterySaverUtils.setAutoBatterySaverTriggerLevel(mMockContext, BATTERY_SAVER_THRESHOLD_1 );
+        assertThat( Global.getInt(mMockResolver, Global.LOW_POWER_MODE_TRIGGER_LEVEL, -1))
+                .isEqualTo(BATTERY_SAVER_THRESHOLD_1);
+        assertThat(Secure.getInt(mMockResolver, Secure.SUPPRESS_AUTO_BATTERY_SAVER_SUGGESTION, -1))
+                .isEqualTo(1);
+    }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 67053d8..a2263b4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2231,6 +2231,12 @@
                 Settings.Secure.WAKE_GESTURE_ENABLED,
                 SecureSettingsProto.WAKE_GESTURE_ENABLED);
 
+        final long launcherToken = p.start(SecureSettingsProto.LAUNCHER);
+        dumpSetting(s, p,
+                Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED,
+                SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+        p.end(launcherToken);
+
         // Please insert new settings using the same order as in SecureSettingsProto.
         p.end(token);
 
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
index 18301a8..02be457 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
index 9ff16a2..d568d0d 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar.xml
@@ -38,7 +38,7 @@
             android:id="@+id/home"
             android:layout_height="match_parent"
             android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
index b0488ae..4ba6c06 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
@@ -38,7 +38,7 @@
             android:id="@+id/home"
             android:layout_height="match_parent"
             android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
index 99bd23c..91ba026 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index e4ea08e..b5d48b4 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -51,12 +51,10 @@
 
         <ImageButton
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_height="match_parent"
                 android:layout_gravity="center"
                 android:paddingStart="12dp"
                 android:paddingEnd="24dp"
-                android:paddingTop="16dp"
-                android:paddingBottom="16dp"
                 android:id="@+id/remote_input_send"
                 android:src="@drawable/ic_send"
                 android:contentDescription="@*android:string/ime_action_send"
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
index 6fa7db3..32e4bbf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
@@ -18,23 +18,24 @@
 
 import android.app.AppGlobals;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 
-import java.util.ArrayList;
 import java.util.List;
 
 public class PackageManagerWrapper {
 
-    private static final String TAG = "PackageManagerWrapper";
-
     private static final PackageManagerWrapper sInstance = new PackageManagerWrapper();
 
     private static final IPackageManager mIPackageManager = AppGlobals.getPackageManager();
 
+    public static final String ACTION_PREFERRED_ACTIVITY_CHANGED =
+            Intent.ACTION_PREFERRED_ACTIVITY_CHANGED;
+
     public static PackageManagerWrapper getInstance() {
         return sInstance;
     }
@@ -53,40 +54,15 @@
     }
 
     /**
-     * @return true if the packageName belongs to the current preferred home app on the device.
-     *
-     * If will also return false if there are multiple home apps and the user has not picked any
-     * preferred home, in which case the user would see a disambiguation screen on going to home.
+     * Report the set of 'Home' activity candidates, plus (if any) which of them
+     * is the current "always use this one" setting.
      */
-    public boolean isDefaultHomeActivity(String packageName) {
-        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
-        ComponentName home;
+    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
         try {
-            home = mIPackageManager.getHomeActivities(allHomeCandidates);
+            return mIPackageManager.getHomeActivities(allHomeCandidates);
         } catch (RemoteException e) {
             e.printStackTrace();
-            return false;
+            return null;
         }
-
-        if (home != null && packageName.equals(home.getPackageName())) {
-            return true;
-        }
-
-        // Find the launcher with the highest priority and return that component if there are no
-        // other home activity with the same priority.
-        int lastPriority = Integer.MIN_VALUE;
-        ComponentName lastComponent = null;
-        final int size = allHomeCandidates.size();
-        for (int i = 0; i < size; i++) {
-            final ResolveInfo ri = allHomeCandidates.get(i);
-            if (ri.priority > lastPriority) {
-                lastComponent = ri.activityInfo.getComponentName();
-                lastPriority = ri.priority;
-            } else if (ri.priority == lastPriority) {
-                // Two components found with same priority.
-                lastComponent = null;
-            }
-        }
-        return lastComponent != null && packageName.equals(lastComponent.getPackageName());
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index a70b358..40ce69b 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -514,7 +514,7 @@
             autoTriggerThreshold = 15;
         }
 
-        BatterySaverUtils.scheduleAutoBatterySaver(mContext, autoTriggerThreshold);
+        BatterySaverUtils.ensureAutoBatterySaver(mContext, autoTriggerThreshold);
         showAutoSaverEnabledConfirmation();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
index 28917ab..f7cbee6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DndTile.java
@@ -210,7 +210,7 @@
         state.slash.isSlashed = !state.value;
         state.label = getTileLabel();
         state.secondaryLabel = ZenModeConfig.getDescription(mContext,zen != Global.ZEN_MODE_OFF,
-                mController.getConfig());
+                mController.getConfig(), false);
         state.icon = ResourceIcon.get(R.drawable.ic_qs_dnd_on);
         checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
         switch (zen) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 75bc955..30e9afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -21,7 +21,6 @@
 
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -62,6 +61,7 @@
 
     private static final String TAG = "RecentsOnboarding";
     private static final boolean RESET_PREFS_FOR_DEBUG = false;
+    private static final boolean ONBOARDING_ENABLED = false;
     private static final long SHOW_DELAY_MS = 500;
     private static final long SHOW_HIDE_DURATION_MS = 300;
     // Don't show the onboarding until the user has launched this number of apps.
@@ -184,6 +184,9 @@
     }
 
     public void onConnectedToLauncher() {
+        if (!ONBOARDING_ENABLED) {
+            return;
+        }
         boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
                 Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
         if (!mTaskListenerRegistered && !alreadySeenRecentsOnboarding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index b81e9af..29c2edc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -26,6 +26,7 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
 import android.view.View;
 import android.view.ViewGroup;
@@ -1631,6 +1632,42 @@
         return null;
     }
 
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        float y = ev.getY();
+        // We still want to distribute touch events to the remote input even if it's outside the
+        // view boundary. We're therefore manually dispatching these events to the remote view
+        RemoteInputView riv = getRemoteInputForView(getViewForVisibleType(mVisibleType));
+        if (riv != null && riv.getVisibility() == VISIBLE) {
+            int inputStart = mUnrestrictedContentHeight - riv.getHeight();
+            if (y <= mUnrestrictedContentHeight && y >= inputStart) {
+                ev.offsetLocation(0, -inputStart);
+                return riv.dispatchTouchEvent(ev);
+            }
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
+    /**
+     * Overridden to make sure touches to the reply action bar actually go through to this view
+     */
+    @Override
+    public boolean pointInView(float localX, float localY, float slop) {
+        float top = mClipTopAmount;
+        float bottom = mUnrestrictedContentHeight;
+        return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
+                localY < (bottom + slop);
+    }
+
+    private RemoteInputView getRemoteInputForView(View child) {
+        if (child == mExpandedChild) {
+            return mExpandedRemoteInput;
+        } else if (child == mHeadsUpChild) {
+            return mHeadsUpRemoteInput;
+        }
+        return null;
+    }
+
     public int getExpandHeight() {
         int viewType = VISIBLE_TYPE_EXPANDED;
         if (mExpandedChild == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index e248db4..ec243fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -24,8 +24,8 @@
     private String mLongIntent;
     private boolean mBroadcastIntent;
     private boolean mSelected = false;
-    private float mSelectedAlpha;
-    private float mUnselectedAlpha;
+    private float mSelectedAlpha = 1f;
+    private float mUnselectedAlpha = 1f;
     private int mSelectedIconResourceId;
     private int mIconResourceId;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 3dbac51..2c335a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -196,6 +196,9 @@
         }
         mState = ScrimState.UNINITIALIZED;
 
+        mScrimBehind.setDefaultFocusHighlightEnabled(false);
+        mScrimInFront.setDefaultFocusHighlightEnabled(false);
+
         updateScrims();
     }
 
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 7987bfd..46b6c4c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -1428,13 +1428,13 @@
     }
 
     public void addQsTile(ComponentName tile) {
-        if (mQSPanel.getHost() != null) {
+        if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().addTile(tile);
         }
     }
 
     public void remQsTile(ComponentName tile) {
-        if (mQSPanel.getHost() != null) {
+        if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().removeTile(tile);
         }
     }
@@ -3899,7 +3899,11 @@
     }
 
     public boolean onBackPressed() {
-        if (mStatusBarKeyguardViewManager.onBackPressed()) {
+        boolean isScrimmedBouncer = mScrimController.getState() == ScrimState.BOUNCER_SCRIMMED;
+        if (mStatusBarKeyguardViewManager.onBackPressed(isScrimmedBouncer /* hideImmediately */)) {
+            if (!isScrimmedBouncer) {
+                mNotificationPanel.expandWithoutQs();
+            }
             return true;
         }
         if (mNotificationPanel.isQsExpanded()) {
@@ -4994,6 +4998,14 @@
 
     @Override
     public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
+        RemoteInputController controller = mRemoteInputManager.getController();
+        if (controller.isRemoteInputActive(row.getEntry())
+                && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
+            // We have an active remote input typed and the user clicked on the notification.
+            // this was probably unintentional, so we're closing the edit text instead.
+            controller.closeRemoteInputs();
+            return;
+        }
         Notification notification = sbn.getNotification();
         final PendingIntent intent = notification.contentIntent != null
                 ? notification.contentIntent
@@ -5057,12 +5069,7 @@
                     Intent fillInIntent = null;
                     Entry entry = row.getEntry();
                     CharSequence remoteInputText = null;
-                    RemoteInputController controller = mRemoteInputManager.getController();
-                    if (controller.isRemoteInputActive(entry)) {
-                        remoteInputText = row.getActiveRemoteInputText();
-                    }
-                    if (TextUtils.isEmpty(remoteInputText)
-                            && !TextUtils.isEmpty(entry.remoteInputText)) {
+                    if (!TextUtils.isEmpty(entry.remoteInputText)) {
                         remoteInputText = entry.remoteInputText;
                     }
                     if (!TextUtils.isEmpty(remoteInputText)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 2727b30..670c68f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -512,12 +512,15 @@
     /**
      * Notifies this manager that the back button has been pressed.
      *
+     * @param hideImmediately Hide bouncer when {@code true}, keep it around otherwise.
+     *                        Non-scrimmed bouncers have a special animation tied to the expansion
+     *                        of the notification panel.
      * @return whether the back press has been handled
      */
-    public boolean onBackPressed() {
+    public boolean onBackPressed(boolean hideImmediately) {
         if (mBouncer.isShowing()) {
             mStatusBar.endAffordanceLaunch();
-            reset(true /* hideBouncerWhenShowing */);
+            reset(hideImmediately);
             return true;
         }
         return false;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 27c00c0..82129a1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -469,6 +469,14 @@
                 ScrimState.AOD.getAnimateChange());
     }
 
+    @Test
+    public void testViewsDontHaveFocusHighlight() {
+        Assert.assertFalse("Scrim shouldn't have focus highlight",
+                mScrimInFront.getDefaultFocusHighlightEnabled());
+        Assert.assertFalse("Scrim shouldn't have focus highlight",
+                mScrimBehind.getDefaultFocusHighlightEnabled());
+    }
+
     /**
      * Conserves old notification density after leaving state and coming back.
      *
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 0ee026e..739b716 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -5578,6 +5578,11 @@
     // OS: P
     WIFI_SCANNING_NEEDED_DIALOG = 1373;
 
+    // OPEN: Settings > System > Gestures > Swipe up gesture
+    // CATEGORY: SETTINGS
+    // OS: P
+    SETTINGS_GESTURE_SWIPE_UP = 1374;
+
     // ---- End P Constants, all P constants go above this line ----
 
     // First Q constant in master goes here:
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index f678eed..325dabe 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -1404,7 +1404,7 @@
 
     private void resetDefaultImeLocked(Context context) {
         // Do not reset the default (current) IME when it is a 3rd-party IME
-        if (mCurMethodId != null && !InputMethodUtils.isSystemIme(mMethodMap.get(mCurMethodId))) {
+        if (mCurMethodId != null && !mMethodMap.get(mCurMethodId).isSystem()) {
             return;
         }
         final List<InputMethodInfo> suitableImes = InputMethodUtils.getDefaultEnabledImes(
@@ -3068,7 +3068,7 @@
                             : mCurrentSubtype.getLocale();
                     for (int i = 0; i < N; ++i) {
                         final InputMethodInfo imi = enabled.get(i);
-                        if (imi.getSubtypeCount() > 0 && InputMethodUtils.isSystemIme(imi)) {
+                        if (imi.getSubtypeCount() > 0 && imi.isSystem()) {
                             InputMethodSubtype keyboardSubtype =
                                     InputMethodUtils.findLastResortApplicableSubtypeLocked(mRes,
                                             InputMethodUtils.getSubtypes(imi),
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 3868ea6..906a6a3 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -57,6 +57,7 @@
 import android.telephony.TelephonyManager;
 import android.util.DebugUtils;
 import android.util.Pair;
+import android.util.Range;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -266,9 +267,9 @@
         }
 
         private long getRemainingDailyBudget(long limitBytes,
-                Pair<ZonedDateTime, ZonedDateTime> cycle) {
-            final long start = cycle.first.toInstant().toEpochMilli();
-            final long end = cycle.second.toInstant().toEpochMilli();
+                Range<ZonedDateTime> cycle) {
+            final long start = cycle.getLower().toInstant().toEpochMilli();
+            final long end = cycle.getUpper().toInstant().toEpochMilli();
             final long totalBytes = getNetworkTotalBytes(start, end);
             final long remainingBytes = totalBytes == -1 ? 0 : Math.max(0, limitBytes - totalBytes);
             // 1 + ((end - now - 1) / millisInDay with integers is equivalent to:
@@ -389,7 +390,7 @@
 
     private static boolean hasActiveCycle(NetworkPolicy policy) {
         return policy.hasCycle() && policy.lastLimitSnooze <
-                policy.cycleIterator().next().first.toInstant().toEpochMilli();
+                policy.cycleIterator().next().getLower().toInstant().toEpochMilli();
     }
 
     // Only ever updated on the handler thread. Accessed from other binder threads to retrieve
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index b7bbb3b..e3d0bdd 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -79,7 +79,7 @@
  */
 public final class ContentService extends IContentService.Stub {
     static final String TAG = "ContentService";
-    static final boolean DEBUG = true;
+    static final boolean DEBUG = false;
 
     public static class Lifecycle extends SystemService {
         private ContentService mService;
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 224d085..98f69d1 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -70,6 +70,12 @@
 import static android.net.NetworkTemplate.MATCH_WIFI;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
 import static android.net.TrafficStats.MB_IN_BYTES;
+import static android.provider.Settings.Global.NETPOLICY_OVERRIDE_ENABLED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_ENABLED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_JOBS;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_FRAC_MULTIPATH;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_LIMITED;
+import static android.provider.Settings.Global.NETPOLICY_QUOTA_UNLIMITED;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_USE_PLATFORM_DEFAULT;
@@ -115,6 +121,7 @@
 import android.app.usage.UsageStatsManagerInternal;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -188,6 +195,7 @@
 import android.util.DataUnit;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -351,6 +359,11 @@
      */
     private static final long WAIT_FOR_ADMIN_DATA_TIMEOUT_MS = 10_000;
 
+    private static final long QUOTA_UNLIMITED_DEFAULT = DataUnit.MEBIBYTES.toBytes(20);
+    private static final float QUOTA_LIMITED_DEFAULT = 0.1f;
+    private static final float QUOTA_FRAC_JOBS_DEFAULT = 0.5f;
+    private static final float QUOTA_FRAC_MULTIPATH_DEFAULT = 0.5f;
+
     private static final int MSG_RULES_CHANGED = 1;
     private static final int MSG_METERED_IFACES_CHANGED = 2;
     private static final int MSG_LIMIT_REACHED = 5;
@@ -1739,10 +1752,18 @@
         }
         mMeteredIfaces = newMeteredIfaces;
 
+        final ContentResolver cr = mContext.getContentResolver();
+        final boolean quotaEnabled = Settings.Global.getInt(cr,
+                NETPOLICY_QUOTA_ENABLED, 1) != 0;
+        final long quotaUnlimited = Settings.Global.getLong(cr,
+                NETPOLICY_QUOTA_UNLIMITED, QUOTA_UNLIMITED_DEFAULT);
+        final float quotaLimited = Settings.Global.getFloat(cr,
+                NETPOLICY_QUOTA_LIMITED, QUOTA_LIMITED_DEFAULT);
+
         // Finally, calculate our opportunistic quotas
-        // TODO: add experiments support to disable or tweak ratios
         mSubscriptionOpportunisticQuota.clear();
         for (NetworkState state : states) {
+            if (!quotaEnabled) continue;
             if (state.network == null) continue;
             final int subId = getSubIdLocked(state.network);
             final SubscriptionPlan plan = getPrimarySubscriptionPlanLocked(subId);
@@ -1754,14 +1775,14 @@
                 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
             } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
                 // Unlimited data; let's use 20MiB/day (600MiB/month)
-                quotaBytes = DataUnit.MEBIBYTES.toBytes(20);
+                quotaBytes = quotaUnlimited;
             } else {
                 // Limited data; let's only use 10% of remaining budget
-                final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next();
-                final long start = cycle.first.toInstant().toEpochMilli();
-                final long end = cycle.second.toInstant().toEpochMilli();
+                final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
+                final long start = cycle.getLower().toInstant().toEpochMilli();
+                final long end = cycle.getUpper().toInstant().toEpochMilli();
                 final Instant now = mClock.instant();
-                final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone())
+                final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
                         .truncatedTo(ChronoUnit.DAYS)
                         .toInstant().toEpochMilli();
                 final long totalBytes = getTotalBytes(
@@ -1772,7 +1793,7 @@
                 final long remainingDays =
                         1 + ((end - now.toEpochMilli() - 1) / TimeUnit.DAYS.toMillis(1));
 
-                quotaBytes = Math.max(0, (remainingBytes / remainingDays) / 10);
+                quotaBytes = Math.max(0, (long) ((remainingBytes / remainingDays) * quotaLimited));
             }
 
             mSubscriptionOpportunisticQuota.put(subId, quotaBytes);
@@ -3048,11 +3069,17 @@
             }
         }
 
-        mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
-                overrideMask, overrideValue, subId));
-        if (timeoutMillis > 0) {
-            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
-                    overrideMask, 0, subId), timeoutMillis);
+        // Only allow overrides when feature is enabled. However, we always
+        // allow disabling of overrides for safety reasons.
+        final boolean overrideEnabled = Settings.Global.getInt(mContext.getContentResolver(),
+                NETPOLICY_OVERRIDE_ENABLED, 1) != 0;
+        if (overrideEnabled || overrideValue == 0) {
+            mHandler.sendMessage(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
+                    overrideMask, overrideValue, subId));
+            if (timeoutMillis > 0) {
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SUBSCRIPTION_OVERRIDE,
+                        overrideMask, 0, subId), timeoutMillis);
+            }
         }
     }
 
@@ -4695,11 +4722,24 @@
 
         @Override
         public long getSubscriptionOpportunisticQuota(Network network, int quotaType) {
+            final long quotaBytes;
             synchronized (mNetworkPoliciesSecondLock) {
-                // TODO: handle splitting quota between use-cases
-                return mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
+                quotaBytes = mSubscriptionOpportunisticQuota.get(getSubIdLocked(network),
                         OPPORTUNISTIC_QUOTA_UNKNOWN);
             }
+            if (quotaBytes == OPPORTUNISTIC_QUOTA_UNKNOWN) {
+                return OPPORTUNISTIC_QUOTA_UNKNOWN;
+            }
+
+            if (quotaType == QUOTA_TYPE_JOBS) {
+                return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
+                        NETPOLICY_QUOTA_FRAC_JOBS, QUOTA_FRAC_JOBS_DEFAULT));
+            } else if (quotaType == QUOTA_TYPE_MULTIPATH) {
+                return (long) (quotaBytes * Settings.Global.getFloat(mContext.getContentResolver(),
+                        NETPOLICY_QUOTA_FRAC_MULTIPATH, QUOTA_FRAC_MULTIPATH_DEFAULT));
+            } else {
+                return OPPORTUNISTIC_QUOTA_UNKNOWN;
+            }
         }
 
         @Override
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 2ef754e..ab52523 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -47,7 +47,7 @@
 import android.util.AtomicFile;
 import android.util.IntArray;
 import android.util.MathUtils;
-import android.util.Pair;
+import android.util.Range;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -266,11 +266,11 @@
         long collectEnd = end;
 
         if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
-            final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator();
+            final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
             while (it.hasNext()) {
-                final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
-                final long cycleStart = cycle.first.toInstant().toEpochMilli();
-                final long cycleEnd = cycle.second.toInstant().toEpochMilli();
+                final Range<ZonedDateTime> cycle = it.next();
+                final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
+                final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
                 if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
                     augmentStart = cycleStart;
                     collectStart = Long.min(collectStart, augmentStart);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index cf7dfd0..79f80e6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -618,6 +618,7 @@
     boolean mTranslucentDecorEnabled = true;
     boolean mUseTvRouting;
     int mVeryLongPressTimeout;
+    boolean mAllowStartActivityForLongPressOnPowerDuringSetup;
 
     private boolean mHandleVolumeKeysInWM;
 
@@ -1622,7 +1623,11 @@
                     : mKeyguardDelegate.isShowing();
             if (!keyguardActive) {
                 Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST);
-                startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+                if (mAllowStartActivityForLongPressOnPowerDuringSetup) {
+                    mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+                } else {
+                    startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF);
+                }
             }
             break;
         }
@@ -2134,6 +2139,8 @@
                 com.android.internal.R.integer.config_shortPressOnSleepBehavior);
         mVeryLongPressTimeout = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_veryLongPressTimeout);
+        mAllowStartActivityForLongPressOnPowerDuringSetup = mContext.getResources().getBoolean(
+                com.android.internal.R.bool.config_allowStartActivityForLongPressOnPowerInSetup);
 
         mUseTvRouting = AudioSystem.getPlatformType(mContext) == AudioSystem.PLATFORM_TELEVISION;
 
@@ -8661,6 +8668,9 @@
                 pw.print("mShortPressOnWindowBehavior=");
                 pw.println(shortPressOnWindowBehaviorToString(mShortPressOnWindowBehavior));
         pw.print(prefix);
+                pw.print("mAllowStartActivityForLongPressOnPowerDuringSetup=");
+                pw.println(mAllowStartActivityForLongPressOnPowerDuringSetup);
+        pw.print(prefix);
                 pw.print("mHasSoftInput="); pw.print(mHasSoftInput);
                 pw.print(" mDismissImeOnBackKeyPressed="); pw.println(mDismissImeOnBackKeyPressed);
         pw.print(prefix);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index e8f4545..318b3d2 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -51,6 +51,7 @@
 import android.view.SurfaceControl;
 import android.view.SurfaceControl.Transaction;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.google.android.collect.Sets;
 
 import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
@@ -290,8 +291,10 @@
         mService.mWindowPlacerLocked.performSurfacePlacement();
     }
 
-    private void addAnimation(Task task, boolean isRecentTaskInvisible) {
+    @VisibleForTesting
+    AnimationAdapter addAnimation(Task task, boolean isRecentTaskInvisible) {
         if (DEBUG) Log.d(TAG, "addAnimation(" + task.getName() + ")");
+        // TODO: Refactor this to use the task's animator
         final SurfaceAnimator anim = new SurfaceAnimator(task, null /* animationFinishedCallback */,
                 mService);
         final TaskAnimationAdapter taskAdapter = new TaskAnimationAdapter(task,
@@ -299,6 +302,15 @@
         anim.startAnimation(task.getPendingTransaction(), taskAdapter, false /* hidden */);
         task.commitPendingTransaction();
         mPendingAnimations.add(taskAdapter);
+        return taskAdapter;
+    }
+
+    @VisibleForTesting
+    void removeAnimation(TaskAnimationAdapter taskAdapter) {
+        if (DEBUG) Log.d(TAG, "removeAnimation(" + taskAdapter.mTask.getName() + ")");
+        taskAdapter.mTask.setCanAffectSystemUiFlags(true);
+        taskAdapter.mCapturedFinishCallback.onAnimationFinished(taskAdapter);
+        mPendingAnimations.remove(taskAdapter);
     }
 
     void startAnimation() {
@@ -311,12 +323,21 @@
         try {
             final ArrayList<RemoteAnimationTarget> appAnimations = new ArrayList<>();
             for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
-                final RemoteAnimationTarget target =
-                        mPendingAnimations.get(i).createRemoteAnimationApp();
+                final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
+                final RemoteAnimationTarget target = taskAdapter.createRemoteAnimationApp();
                 if (target != null) {
                     appAnimations.add(target);
+                } else {
+                    removeAnimation(taskAdapter);
                 }
             }
+
+            // Skip the animation if there is nothing to animate
+            if (appAnimations.isEmpty()) {
+                cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION);
+                return;
+            }
+
             final RemoteAnimationTarget[] appTargets = appAnimations.toArray(
                     new RemoteAnimationTarget[appAnimations.size()]);
             mPendingStart = false;
@@ -365,14 +386,12 @@
         if (DEBUG) Log.d(TAG, "cleanupAnimation(): mPendingAnimations="
                 + mPendingAnimations.size());
         for (int i = mPendingAnimations.size() - 1; i >= 0; i--) {
-            final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
-            adapter.mTask.setCanAffectSystemUiFlags(true);
+            final TaskAnimationAdapter taskAdapter = mPendingAnimations.get(i);
             if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
-                adapter.mTask.dontAnimateDimExit();
+                taskAdapter.mTask.dontAnimateDimExit();
             }
-            adapter.mCapturedFinishCallback.onAnimationFinished(adapter);
+            removeAnimation(taskAdapter);
         }
-        mPendingAnimations.clear();
 
         mRunner.asBinder().unlinkToDeath(this, 0);
         // Clear associated input consumers
@@ -457,7 +476,8 @@
         return false;
     }
 
-    private class TaskAnimationAdapter implements AnimationAdapter {
+    @VisibleForTesting
+    class TaskAnimationAdapter implements AnimationAdapter {
 
         private final Task mTask;
         private SurfaceControl mCapturedLeash;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index d31d550..dc47821 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -37,9 +37,12 @@
 import static android.telephony.CarrierConfigManager.KEY_DATA_LIMIT_THRESHOLD_BYTES_LONG;
 import static android.telephony.CarrierConfigManager.KEY_DATA_WARNING_THRESHOLD_BYTES_LONG;
 import static android.telephony.CarrierConfigManager.KEY_MONTHLY_DATA_CYCLE_DAY_INT;
+import static android.telephony.SubscriptionPlan.BYTES_UNLIMITED;
 import static android.telephony.SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED;
 import static android.text.format.Time.TIMEZONE_UTC;
 
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
+import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
@@ -118,7 +121,7 @@
 import android.text.format.Time;
 import android.util.DataUnit;
 import android.util.Log;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.telephony.PhoneConstants;
@@ -818,11 +821,11 @@
     private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
                 ZoneId.systemDefault());
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = policy.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
         while (it.hasNext()) {
-            final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
-            if (cycle.first.toInstant().toEpochMilli() < currentTime) {
-                return cycle.first.toInstant().toEpochMilli();
+            final Range<ZonedDateTime> cycle = it.next();
+            if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
+                return cycle.getLower().toInstant().toEpochMilli();
             }
         }
         throw new IllegalStateException(
@@ -832,7 +835,7 @@
     private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
                 ZoneId.systemDefault());
-        return policy.cycleIterator().next().second.toInstant().toEpochMilli();
+        return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
     }
 
     @Test
@@ -1484,6 +1487,102 @@
                 true);
     }
 
+    @Test
+    public void testOpportunisticQuota() throws Exception {
+        final Network net = new Network(TEST_NET_ID);
+        final NetworkPolicyManagerInternal internal = LocalServices
+                .getService(NetworkPolicyManagerInternal.class);
+
+        // Create a place to store fake usage
+        final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
+        final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
+        when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<Long>() {
+                    @Override
+                    public Long answer(InvocationOnMock invocation) throws Throwable {
+                        final NetworkStatsHistory.Entry entry = history.getValues(
+                                invocation.getArgument(1), invocation.getArgument(2), null);
+                        return entry.rxBytes + entry.txBytes;
+                    }
+                });
+        when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
+                .thenAnswer(new Answer<NetworkStats>() {
+                    @Override
+                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
+                        return stats;
+                    }
+                });
+
+        // Get active mobile network in place
+        expectMobileDefaults();
+        mService.updateNetworks();
+
+        // We're 20% through the month (6 days)
+        final long start = parseTime("2015-11-01T00:00Z");
+        final long end = parseTime("2015-11-07T00:00Z");
+        setCurrentTimeMillis(end);
+
+        // Get some data usage in place
+        history.clear();
+        history.recordData(start, end,
+                new NetworkStats.Entry(DataUnit.MEGABYTES.toBytes(360), 0L, 0L, 0L, 0));
+
+        // No data plan
+        {
+            reset(mTelephonyManager, mNetworkManager, mNotifManager);
+            expectMobileDefaults();
+
+            mService.updateNetworks();
+
+            // No quotas
+            assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+        }
+
+        // Limited data plan
+        {
+            final SubscriptionPlan plan = SubscriptionPlan.Builder
+                    .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
+                    .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED)
+                    .build();
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+                    mServiceContext.getOpPackageName());
+
+            reset(mTelephonyManager, mNetworkManager, mNotifManager);
+            expectMobileDefaults();
+
+            mService.updateNetworks();
+
+            // We have 1440MB and 24 days left, which is 60MB/day; assuming 10%
+            // for quota split equally between two types gives 3MB.
+            assertEquals(DataUnit.MEGABYTES.toBytes(3),
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(DataUnit.MEGABYTES.toBytes(3),
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+        }
+
+        // Unlimited data plan
+        {
+            final SubscriptionPlan plan = SubscriptionPlan.Builder
+                    .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
+                    .setDataLimit(BYTES_UNLIMITED, LIMIT_BEHAVIOR_DISABLED)
+                    .build();
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+                    mServiceContext.getOpPackageName());
+
+            reset(mTelephonyManager, mNetworkManager, mNotifManager);
+            expectMobileDefaults();
+
+            mService.updateNetworks();
+
+            // 20MB/day, split equally between two types gives 10MB.
+            assertEquals(DataUnit.MEBIBYTES.toBytes(10),
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(DataUnit.MEBIBYTES.toBytes(10),
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+        }
+    }
+
     private ApplicationInfo buildApplicationInfo(String label) {
         final ApplicationInfo ai = new ApplicationInfo();
         ai.nonLocalizedLabel = label;
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
new file mode 100644
index 0000000..fbf6691
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.os.Binder;
+import android.os.IInterface;
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.view.IRecentsAnimationRunner;
+import android.view.SurfaceControl;
+import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
+ */
+@SmallTest
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class RecentsAnimationControllerTest extends WindowTestsBase {
+
+    @Mock SurfaceControl mMockLeash;
+    @Mock SurfaceControl.Transaction mMockTransaction;
+    @Mock OnAnimationFinishedCallback mFinishedCallback;
+    @Mock IRecentsAnimationRunner mMockRunner;
+    @Mock RecentsAnimationController.RecentsAnimationCallbacks mAnimationCallbacks;
+    private RecentsAnimationController mController;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MockitoAnnotations.initMocks(this);
+        when(mMockRunner.asBinder()).thenReturn(new Binder());
+        mController = new RecentsAnimationController(sWm, mMockRunner, mAnimationCallbacks,
+                DEFAULT_DISPLAY);
+    }
+
+    @Test
+    public void testRemovedBeforeStarted_expectCanceled() throws Exception {
+        final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+                WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+        AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
+                false /* isRecentTaskInvisible */);
+        adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
+
+        // Remove the app window so that the animation target can not be created
+        appWindow.removeImmediately();
+        mController.startAnimation();
+
+        // Verify that the finish callback to reparent the leash is called
+        verify(mFinishedCallback).onAnimationFinished(eq(adapter));
+        // Verify the animation canceled callback to the app was made
+        verify(mMockRunner).onAnimationCanceled();
+        verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
+    }
+
+    private static void verifyNoMoreInteractionsExceptAsBinder(IInterface binder) {
+        verify(binder, atLeast(0)).asBinder();
+        verifyNoMoreInteractions(binder);
+    }
+}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 754fe68..a9389be 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -477,6 +477,9 @@
      * <p>
      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
      * the user is interested in.
+     * <p>
+     * Receivers should protect themselves by checking that the sender holds the
+     * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @SystemApi
@@ -1719,6 +1722,8 @@
      * </ul>
      *
      * @param subId the subscriber this relationship applies to
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
@@ -1744,10 +1749,13 @@
      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
      * </ul>
      *
-     * @param subId the subscriber this relationship applies to
+     * @param subId the subscriber this relationship applies to. An empty list
+     *            may be sent to clear any existing plans.
      * @param plans the list of plans. The first plan is always the primary and
      *            most important plan. Any additional plans are secondary and
      *            may not be displayed or used by decision making logic.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
@@ -1788,6 +1796,8 @@
      *            be automatically cleared, or {@code 0} to leave in the
      *            requested state until explicitly cleared, or the next reboot,
      *            whichever happens first.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
@@ -1822,6 +1832,8 @@
      *            be automatically cleared, or {@code 0} to leave in the
      *            requested state until explicitly cleared, or the next reboot,
      *            whichever happens first.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index 4ffb70b..ef2a364 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -24,7 +24,7 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.util.Preconditions;
@@ -209,7 +209,7 @@
      * any recurrence rules. The iterator starts from the currently active cycle
      * and walks backwards through time.
      */
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         return cycleRule.cycleIterator();
     }
 
@@ -227,6 +227,9 @@
         /**
          * Start defining a {@link SubscriptionPlan} that covers a very specific
          * window of time, and never automatically recurs.
+         *
+         * @param start The exact time at which the plan starts.
+         * @param end The exact time at which the plan ends.
          */
         public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) {
             if (!end.isAfter(start)) {
@@ -237,28 +240,40 @@
         }
 
         /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every month. It will always recur on the same day of a
-         * particular month. When a particular month ends before the defined
-         * recurrence day, the plan will recur on the last instant of that
-         * month.
+         * Start defining a {@link SubscriptionPlan} that starts at a specific
+         * time, and automatically recurs after each specific period of time,
+         * repeating indefinitely.
+         * <p>
+         * When the given period is set to exactly one month, the plan will
+         * always recur on the day of the month defined by
+         * {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends
+         * before this day, the plan will recur on the last possible instant of
+         * that month.
+         *
+         * @param start The exact time at which the plan starts.
+         * @param period The period after which the plan automatically recurs.
          */
+        public static Builder createRecurring(ZonedDateTime start, Period period) {
+            return new Builder(start, null, period);
+        }
+
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringMonthly(ZonedDateTime start) {
             return new Builder(start, null, Period.ofMonths(1));
         }
 
-        /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every week.
-         */
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringWeekly(ZonedDateTime start) {
             return new Builder(start, null, Period.ofDays(7));
         }
 
-        /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every day.
-         */
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringDaily(ZonedDateTime start) {
             return new Builder(start, null, Period.ofDays(1));
         }
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 2f52c0a..dfb6e2c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -77,6 +77,11 @@
             result = 31 * result + featureType;
             return result;
         }
+
+        @Override
+        public String toString() {
+            return "{s=" + slotId + ", f=" + featureType + "}";
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 687a6b7..bb771bb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -823,6 +823,16 @@
     boolean isResolvingImsBinding();
 
     /**
+    *  @return true if the ImsService to bind to for the slot id specified was set, false otherwise.
+    */
+    boolean setImsService(int slotId, boolean isCarrierImsService, String packageName);
+
+    /**
+    * @return the package name of the carrier/device ImsService associated with this slot.
+    */
+    String getImsService(int slotId, boolean isCarrierImsService);
+
+    /**
      * Set the network selection mode to automatic.
      *
      * @param subId the id of the subscription to update.