Merge "Fixes null-ref when trying to start Guest session." into pi-dev
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 19ce180..b9abc1a 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -229,6 +229,7 @@
 Landroid/app/AppOpsManager;->OP_WRITE_CONTACTS:I
 Landroid/app/AppOpsManager;->OP_WRITE_SMS:I
 Landroid/app/AppOpsManager;->permissionToOpCode(Ljava/lang/String;)I
+Landroid/app/AppOpsManager;->setRestriction(III[Ljava/lang/String;)V
 Landroid/app/AppOpsManager;->sOpPerms:[Ljava/lang/String;
 Landroid/app/AppOpsManager;->strOpToOp(Ljava/lang/String;)I
 Landroid/app/backup/BackupDataInput$EntityHeader;->dataSize:I
@@ -420,6 +421,7 @@
 Landroid/app/PendingIntent;->getActivityAsUser(Landroid/content/Context;ILandroid/content/Intent;ILandroid/os/Bundle;Landroid/os/UserHandle;)Landroid/app/PendingIntent;
 Landroid/app/PendingIntent;->getIntent()Landroid/content/Intent;
 Landroid/app/PendingIntent;->isActivity()Z
+Landroid/app/PictureInPictureParams;->getAspectRatio()F
 Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
 Landroid/app/ProgressDialog;->mProgressNumber:Landroid/widget/TextView;
 Landroid/app/QueuedWork;->addFinisher(Ljava/lang/Runnable;)V
@@ -695,6 +697,7 @@
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
 Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
 Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDeleteObserver2;->onPackageDeleted(Ljava/lang/String;ILjava/lang/String;)V
@@ -738,6 +741,7 @@
 Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageStatsObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageStatsObserver$Stub;-><init>()V
+Landroid/content/pm/IPackageStatsObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageStatsObserver;
 Landroid/content/pm/IShortcutService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IShortcutService;
 Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo;
@@ -796,6 +800,7 @@
 Landroid/content/pm/PackageParser$Package;->configPreferences:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->instrumentation:Ljava/util/ArrayList;
 Landroid/content/pm/PackageParser$Package;->mAppMetaData:Landroid/os/Bundle;
+Landroid/content/pm/PackageParser$Package;->mKeySetMapping:Landroid/util/ArrayMap;
 Landroid/content/pm/PackageParser$Package;->mPreferredOrder:I
 Landroid/content/pm/PackageParser$Package;->mSharedUserId:Ljava/lang/String;
 Landroid/content/pm/PackageParser$Package;->mSharedUserLabel:I
@@ -891,6 +896,7 @@
 Landroid/content/res/Resources;->setCompatibilityInfo(Landroid/content/res/CompatibilityInfo;)V
 Landroid/content/res/Resources;->updateSystemConfiguration(Landroid/content/res/Configuration;Landroid/util/DisplayMetrics;Landroid/content/res/CompatibilityInfo;)V
 Landroid/content/res/ResourcesImpl;->getAssets()Landroid/content/res/AssetManager;
+Landroid/content/res/ResourcesImpl;->getValue(ILandroid/util/TypedValue;Z)V
 Landroid/content/res/ResourcesImpl;->mAccessLock:Ljava/lang/Object;
 Landroid/content/res/ResourcesImpl;->mAnimatorCache:Landroid/content/res/ConfigurationBoundResourceCache;
 Landroid/content/res/ResourcesImpl;->mAssets:Landroid/content/res/AssetManager;
@@ -1264,6 +1270,7 @@
 Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V
 Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V
 Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator;
+Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;)Landroid/icu/text/Transliterator;
 Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String;
 Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
 Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale;
@@ -2096,6 +2103,7 @@
 Landroid/R$styleable;->CheckedTextView_checkMark:I
 Landroid/R$styleable;->CompoundButton:[I
 Landroid/R$styleable;->CompoundButton_button:I
+Landroid/R$styleable;->DrawableStates:[I
 Landroid/R$styleable;->ImageView:[I
 Landroid/R$styleable;->ImageView_adjustViewBounds:I
 Landroid/R$styleable;->ImageView_baselineAlignBottom:I
@@ -2358,6 +2366,7 @@
 Landroid/telephony/CellSignalStrengthLte;->mRsrq:I
 Landroid/telephony/CellSignalStrengthLte;->mRssnr:I
 Landroid/telephony/CellSignalStrengthLte;->mSignalStrength:I
+Landroid/telephony/CellSignalStrengthLte;->mTimingAdvance:I
 Landroid/telephony/CellSignalStrengthWcdma;->mBitErrorRate:I
 Landroid/telephony/CellSignalStrengthWcdma;->mSignalStrength:I
 Landroid/telephony/PhoneNumberUtils;->isLocalEmergencyNumber(Landroid/content/Context;ILjava/lang/String;)Z
@@ -2367,6 +2376,7 @@
 Landroid/telephony/SignalStrength;->getAsuLevel()I
 Landroid/telephony/SignalStrength;->getCdmaLevel()I
 Landroid/telephony/SignalStrength;->getDbm()I
+Landroid/telephony/SignalStrength;->getGsmDbm()I
 Landroid/telephony/SignalStrength;->getLteDbm()I
 Landroid/telephony/SignalStrength;->getLteRsrp()I
 Landroid/telephony/SignalStrength;->getLteRsrq()I
@@ -2431,6 +2441,7 @@
 Landroid/telephony/TelephonyManager;->hasIccCard(I)Z
 Landroid/telephony/TelephonyManager;->isMultiSimEnabled()Z
 Landroid/telephony/TelephonyManager;->isNetworkRoaming(I)Z
+Landroid/telephony/TelephonyManager;->isVideoTelephonyAvailable()Z
 Landroid/telephony/TelephonyManager;->isVolteAvailable()Z
 Landroid/telephony/TelephonyManager;->isWifiCallingAvailable()Z
 Landroid/telephony/TelephonyManager;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
@@ -2609,6 +2620,7 @@
 Landroid/view/inputmethod/InputMethodManager;->finishInputLocked()V
 Landroid/view/inputmethod/InputMethodManager;->focusIn(Landroid/view/View;)V
 Landroid/view/inputmethod/InputMethodManager;->focusOut(Landroid/view/View;)V
+Landroid/view/inputmethod/InputMethodManager;->getClient()Lcom/android/internal/view/IInputMethodClient;
 Landroid/view/inputmethod/InputMethodManager;->getInputMethodWindowVisibleHeight()I
 Landroid/view/inputmethod/InputMethodManager;->getInstance()Landroid/view/inputmethod/InputMethodManager;
 Landroid/view/inputmethod/InputMethodManager;->mCurId:Ljava/lang/String;
@@ -2785,6 +2797,7 @@
 Landroid/view/View;->includeForAccessibility()Z
 Landroid/view/View;->initializeScrollbars(Landroid/content/res/TypedArray;)V
 Landroid/view/View;->internalSetPadding(IIII)V
+Landroid/view/View;->invalidateParentIfNeeded()V
 Landroid/view/View;->isPaddingResolved()Z
 Landroid/view/View;->isRootNamespace()Z
 Landroid/view/View;->isVisibleToUser()Z
@@ -3069,6 +3082,7 @@
 Landroid/widget/ImageView;->mDrawMatrix:Landroid/graphics/Matrix;
 Landroid/widget/ImageView;->mMaxHeight:I
 Landroid/widget/ImageView;->mMaxWidth:I
+Landroid/widget/ImageView;->mRecycleableBitmapDrawable:Landroid/graphics/drawable/BitmapDrawable;
 Landroid/widget/ImageView;->mResource:I
 Landroid/widget/ImageView;->mUri:Landroid/net/Uri;
 Landroid/widget/ImageView;->updateDrawable(Landroid/graphics/drawable/Drawable;)V
@@ -3573,11 +3587,13 @@
 Lcom/android/internal/telephony/ITelephony;->disableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->enableDataConnectivity()Z
 Lcom/android/internal/telephony/ITelephony;->endCall()Z
+Lcom/android/internal/telephony/ITelephony;->endCallForSubscriber(I)Z
 Lcom/android/internal/telephony/ITelephony;->getCallState()I
 Lcom/android/internal/telephony/ITelephony;->getDataState()I
 Lcom/android/internal/telephony/ITelephony;->isIdle(Ljava/lang/String;)Z
 Lcom/android/internal/telephony/ITelephony;->setRadio(Z)Z
 Lcom/android/internal/telephony/ITelephony;->silenceRinger()V
+Lcom/android/internal/telephony/ITelephonyRegistry$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/telephony/ITelephonyRegistry$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/ITelephonyRegistry;
 Lcom/android/internal/telephony/ITelephonyRegistry;->notifyCallState(ILjava/lang/String;)V
 Lcom/android/internal/telephony/SmsHeader$ConcatRef;->msgCount:I
@@ -3714,6 +3730,7 @@
 Ldalvik/system/VMDebug;->isDebuggerConnected()Z
 Ldalvik/system/VMRuntime;->addressOf(Ljava/lang/Object;)J
 Ldalvik/system/VMRuntime;->clearGrowthLimit()V
+Ldalvik/system/VMRuntime;->gcSoftReferences()V
 Ldalvik/system/VMRuntime;->getCurrentInstructionSet()Ljava/lang/String;
 Ldalvik/system/VMRuntime;->getExternalBytesAllocated()J
 Ldalvik/system/VMRuntime;->getInstructionSet(Ljava/lang/String;)Ljava/lang/String;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ab0001c..13389e3 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -109,6 +109,48 @@
      */
     public static final int MODE_DEFAULT = 3;
 
+    /**
+     * Metrics about an op when its uid is persistent.
+     * @hide
+     */
+    public static final int UID_STATE_PERSISTENT = 0;
+
+    /**
+     * Metrics about an op when its uid is at the top.
+     * @hide
+     */
+    public static final int UID_STATE_TOP = 1;
+
+    /**
+     * Metrics about an op when its uid is running a foreground service.
+     * @hide
+     */
+    public static final int UID_STATE_FOREGROUND_SERVICE = 2;
+
+    /**
+     * Metrics about an op when its uid is in the foreground for any other reasons.
+     * @hide
+     */
+    public static final int UID_STATE_FOREGROUND = 3;
+
+    /**
+     * Metrics about an op when its uid is in the background for any reason.
+     * @hide
+     */
+    public static final int UID_STATE_BACKGROUND = 4;
+
+    /**
+     * Metrics about an op when its uid is cached.
+     * @hide
+     */
+    public static final int UID_STATE_CACHED = 5;
+
+    /**
+     * Number of uid states we track.
+     * @hide
+     */
+    public static final int _NUM_UID_STATE = 6;
+
     // when adding one of these:
     //  - increment _NUM_OP
     //  - define an OPSTR_* constant (marked as @SystemApi)
@@ -1471,8 +1513,8 @@
     public static class OpEntry implements Parcelable {
         private final int mOp;
         private final int mMode;
-        private final long mTime;
-        private final long mRejectTime;
+        private final long[] mTimes;
+        private final long[] mRejectTimes;
         private final int mDuration;
         private final int mProxyUid;
         private final String mProxyPackageName;
@@ -1481,8 +1523,23 @@
                 int proxyUid, String proxyPackage) {
             mOp = op;
             mMode = mode;
-            mTime = time;
-            mRejectTime = rejectTime;
+            mTimes = new long[_NUM_UID_STATE];
+            mRejectTimes = new long[_NUM_UID_STATE];
+            mTimes[0] = time;
+            mRejectTimes[0] = rejectTime;
+            mDuration = duration;
+            mProxyUid = proxyUid;
+            mProxyPackageName = proxyPackage;
+        }
+
+        public OpEntry(int op, int mode, long[] times, long[] rejectTimes, int duration,
+                int proxyUid, String proxyPackage) {
+            mOp = op;
+            mMode = mode;
+            mTimes = new long[_NUM_UID_STATE];
+            mRejectTimes = new long[_NUM_UID_STATE];
+            System.arraycopy(times, 0, mTimes, 0, _NUM_UID_STATE);
+            System.arraycopy(rejectTimes, 0, mRejectTimes, 0, _NUM_UID_STATE);
             mDuration = duration;
             mProxyUid = proxyUid;
             mProxyPackageName = proxyPackage;
@@ -1497,11 +1554,31 @@
         }
 
         public long getTime() {
-            return mTime;
+            long time = 0;
+            for (int i = 0; i < _NUM_UID_STATE; i++) {
+                if (mTimes[i] > time) {
+                    time = mTimes[i];
+                }
+            }
+            return time;
+        }
+
+        public long getTimeFor(int uidState) {
+            return mTimes[uidState];
         }
 
         public long getRejectTime() {
-            return mRejectTime;
+            long time = 0;
+            for (int i = 0; i < _NUM_UID_STATE; i++) {
+                if (mRejectTimes[i] > time) {
+                    time = mTimes[i];
+                }
+            }
+            return time;
+        }
+
+        public long getRejectTimeFor(int uidState) {
+            return mRejectTimes[uidState];
         }
 
         public boolean isRunning() {
@@ -1509,7 +1586,7 @@
         }
 
         public int getDuration() {
-            return mDuration == -1 ? (int)(System.currentTimeMillis()-mTime) : mDuration;
+            return mDuration;
         }
 
         public int getProxyUid() {
@@ -1529,8 +1606,8 @@
         public void writeToParcel(Parcel dest, int flags) {
             dest.writeInt(mOp);
             dest.writeInt(mMode);
-            dest.writeLong(mTime);
-            dest.writeLong(mRejectTime);
+            dest.writeLongArray(mTimes);
+            dest.writeLongArray(mRejectTimes);
             dest.writeInt(mDuration);
             dest.writeInt(mProxyUid);
             dest.writeString(mProxyPackageName);
@@ -1539,8 +1616,8 @@
         OpEntry(Parcel source) {
             mOp = source.readInt();
             mMode = source.readInt();
-            mTime = source.readLong();
-            mRejectTime = source.readLong();
+            mTimes = source.createLongArray();
+            mRejectTimes = source.createLongArray();
             mDuration = source.readInt();
             mProxyUid = source.readInt();
             mProxyPackageName = source.readString();
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index e9b4853..4d238c0 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -349,6 +349,26 @@
             return new OneShot(mDuration, newAmplitude);
         }
 
+        /**
+         * Resolve default values into integer amplitude numbers.
+         *
+         * @param defaultAmplitude the default amplitude to apply, must be between 0 and
+         *         MAX_AMPLITUDE
+         * @return A {@link OneShot} effect with same physical meaning but explicitly set amplitude
+         *
+         * @hide
+         */
+        public OneShot resolve(int defaultAmplitude) {
+            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
+                throw new IllegalArgumentException(
+                        "Amplitude is negative or greater than MAX_AMPLITUDE");
+            }
+            if (mAmplitude == DEFAULT_AMPLITUDE) {
+                return new OneShot(mDuration, defaultAmplitude);
+            }
+            return this;
+        }
+
         @Override
         public void validate() {
             if (mAmplitude < -1 || mAmplitude == 0 || mAmplitude > 255) {
@@ -470,6 +490,30 @@
             return new Waveform(mTimings, scaledAmplitudes, mRepeat);
         }
 
+        /**
+         * Resolve default values into integer amplitude numbers.
+         *
+         * @param defaultAmplitude the default amplitude to apply, must be between 0 and
+         *         MAX_AMPLITUDE
+         * @return A {@link Waveform} effect with same physical meaning but explicitly set
+         *         amplitude
+         *
+         * @hide
+         */
+        public Waveform resolve(int defaultAmplitude) {
+            if (defaultAmplitude > MAX_AMPLITUDE || defaultAmplitude < 0) {
+                throw new IllegalArgumentException(
+                        "Amplitude is negative or greater than MAX_AMPLITUDE");
+            }
+            int[] resolvedAmplitudes = Arrays.copyOf(mAmplitudes, mAmplitudes.length);
+            for (int i = 0; i < resolvedAmplitudes.length; i++) {
+                if (resolvedAmplitudes[i] == DEFAULT_AMPLITUDE) {
+                    resolvedAmplitudes[i] = defaultAmplitude;
+                }
+            }
+            return new Waveform(mTimings, resolvedAmplitudes, mRepeat);
+        }
+
         @Override
         public void validate() {
             if (mTimings.length != mAmplitudes.length) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 6b6e14f..318265b 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -10796,15 +10796,28 @@
         public static final String SYNC_MANAGER_CONSTANTS = "sync_manager_constants";
 
         /**
-         * Whether or not App Standby feature is enabled. This controls throttling of apps
-         * based on usage patterns and predictions.
+         * Whether or not App Standby feature is enabled by system. This controls throttling of apps
+         * based on usage patterns and predictions. Platform will turn on this feature if both this
+         * flag and {@link #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED} is on.
          * Type: int (0 for false, 1 for true)
          * Default: 1
          * @hide
+         * @see #ADAPTIVE_BATTERY_MANAGEMENT_ENABLED
          */
         public static final String APP_STANDBY_ENABLED = "app_standby_enabled";
 
         /**
+         * Whether or not adaptive battery feature is enabled by user. Platform will turn on this
+         * feature if both this flag and {@link #APP_STANDBY_ENABLED} is on.
+         * Type: int (0 for false, 1 for true)
+         * Default: 1
+         * @hide
+         * @see #APP_STANDBY_ENABLED
+         */
+        public static final String ADAPTIVE_BATTERY_MANAGEMENT_ENABLED =
+                "adaptive_battery_management_enabled";
+
+        /**
          * Whether or not app auto restriction is enabled. When it is enabled, settings app will
          * auto restrict the app if it has bad behavior(e.g. hold wakelock for long time).
          *
diff --git a/core/java/android/service/autofill/BatchUpdates.java b/core/java/android/service/autofill/BatchUpdates.java
index 90acc88..2ba0376 100644
--- a/core/java/android/service/autofill/BatchUpdates.java
+++ b/core/java/android/service/autofill/BatchUpdates.java
@@ -82,6 +82,9 @@
          * {@link #transformChild(int, Transformation) transformations} are applied to the children
          * views.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param updates a {@link RemoteViews} with the updated actions to be applied in the
          * underlying presentation template.
          *
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index ccec483..5211767 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -336,6 +336,9 @@
          * higher, datasets that require authentication can be also be filtered by passing a
          * {@link AutofillValue#forText(CharSequence) text value} as the  {@code value} parameter.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param id id returned by {@link
          *         android.app.assist.AssistStructure.ViewNode#getAutofillId()}.
          * @param value the value to be autofilled. Pass {@code null} if you do not have the value
diff --git a/core/java/android/service/autofill/FillResponse.java b/core/java/android/service/autofill/FillResponse.java
index 2bc4b8f..7bf1f83 100644
--- a/core/java/android/service/autofill/FillResponse.java
+++ b/core/java/android/service/autofill/FillResponse.java
@@ -241,6 +241,9 @@
          * immutable by using {@link android.app.PendingIntent#FLAG_IMMUTABLE} as the
          * platform needs to fill in the authentication arguments.
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param authentication Intent to an activity with your authentication flow.
          * @param presentation The presentation to visualize the response.
          * @param ids id of Views that when focused will display the authentication UI.
@@ -449,6 +452,9 @@
          * authentication (as the header could have been set directly in the main presentation in
          * these cases).
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param header a presentation to represent the header. This presentation is not clickable
          * &mdash;calling
          * {@link RemoteViews#setOnClickPendingIntent(int, android.app.PendingIntent)} on it would
@@ -477,6 +483,9 @@
          * authentication (as the footer could have been set directly in the main presentation in
          * these cases).
          *
+         * <p>Theme does not work with RemoteViews layout. Avoid hardcoded text color
+         * or background color: Autofill on different platforms may have different themes.
+         *
          * @param footer a presentation to represent the footer. This presentation is not clickable
          * &mdash;calling
          * {@link RemoteViews#setOnClickPendingIntent(int, android.app.PendingIntent)} on it would
diff --git a/core/java/android/view/autofill/AutofillPopupWindow.java b/core/java/android/view/autofill/AutofillPopupWindow.java
index a6495d1..8266207 100644
--- a/core/java/android/view/autofill/AutofillPopupWindow.java
+++ b/core/java/android/view/autofill/AutofillPopupWindow.java
@@ -19,6 +19,7 @@
 import static android.view.autofill.Helper.sVerbose;
 
 import android.annotation.NonNull;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.IBinder;
@@ -79,11 +80,6 @@
     public AutofillPopupWindow(@NonNull IAutofillWindowPresenter presenter) {
         mWindowPresenter = new WindowPresenter(presenter);
 
-        // We want to show the window as system controlled one so it covers app windows, but it has
-        // to be an application type (so it's contained inside the application area).
-        // Hence, we set it to the application type with the highest z-order, which currently
-        // is TYPE_APPLICATION_ABOVE_SUB_PANEL.
-        setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
         setTouchModal(false);
         setOutsideTouchable(true);
         setInputMethodMode(INPUT_METHOD_NOT_NEEDED);
@@ -110,7 +106,16 @@
      */
     public void update(View anchor, int offsetX, int offsetY, int width, int height,
             Rect virtualBounds) {
-        mFullScreen = width == LayoutParams.MATCH_PARENT && height == LayoutParams.MATCH_PARENT;
+        mFullScreen = width == LayoutParams.MATCH_PARENT;
+        // For no fullscreen autofill window, we want to show the window as system controlled one
+        // so it covers app windows, but it has to be an application type (so it's contained inside
+        // the application area). Hence, we set it to the application type with the highest z-order,
+        // which currently is TYPE_APPLICATION_ABOVE_SUB_PANEL.
+        // For fullscreen mode, autofill window is at the bottom of screen, it should not be
+        // clipped by app activity window. Fullscreen autofill window does not need to follow app
+        // anchor view position.
+        setWindowLayoutType(mFullScreen ? WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG
+                : WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL);
         // If we are showing the popup for a virtual view we use a fake view which
         // delegates to the anchor but present itself with the same bounds as the
         // virtual view. This ensures that the location logic in popup works
@@ -119,6 +124,15 @@
         if (mFullScreen) {
             offsetX = 0;
             offsetY = 0;
+            // If it is not fullscreen height, put window at bottom. Computes absolute position.
+            // Note that we cannot easily change default gravity from Gravity.TOP to
+            // Gravity.BOTTOM because PopupWindow base class does not expose computeGravity().
+            final Point outPoint = new Point();
+            anchor.getContext().getDisplay().getSize(outPoint);
+            width = outPoint.x;
+            if (height != LayoutParams.MATCH_PARENT) {
+                offsetY = outPoint.y - height;
+            }
             actualAnchor = anchor;
         } else if (virtualBounds != null) {
             final int[] mLocationOnScreen = new int[] {virtualBounds.left, virtualBounds.top};
@@ -202,6 +216,16 @@
             actualAnchor = anchor;
         }
 
+        if (!mFullScreen) {
+            // No fullscreen window animation is controlled by PopupWindow.
+            setAnimationStyle(-1);
+        } else if (height == LayoutParams.MATCH_PARENT) {
+            // Complete fullscreen autofill window has no animation.
+            setAnimationStyle(0);
+        } else {
+            // Slide half screen height autofill window from bottom.
+            setAnimationStyle(com.android.internal.R.style.AutofillHalfScreenAnimation);
+        }
         if (!isShowing()) {
             setWidth(width);
             setHeight(height);
@@ -223,7 +247,12 @@
     protected boolean findDropDownPosition(View anchor, LayoutParams outParams,
             int xOffset, int yOffset, int width, int height, int gravity, boolean allowScroll) {
         if (mFullScreen) {
-            // Do not patch LayoutParams if force full screen
+            // In fullscreen mode, don't need consider the anchor view.
+            outParams.x = xOffset;
+            outParams.y = yOffset;
+            outParams.width = width;
+            outParams.height = height;
+            outParams.gravity = gravity;
             return false;
         }
         return super.findDropDownPosition(anchor, outParams, xOffset, yOffset,
@@ -316,11 +345,6 @@
     }
 
     @Override
-    public void setAnimationStyle(int animationStyle) {
-        throw new IllegalStateException("You can't call this!");
-    }
-
-    @Override
     public void setBackgroundDrawable(Drawable background) {
         throw new IllegalStateException("You can't call this!");
     }
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index cb362e6..f1a1457 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -170,7 +170,7 @@
             if (mWindow == null) {
                 synchronized (mLock) {
                     mWindow = new InternalPopupWindow(mView.getContext(), mView.getDisplay(),
-                            getValidViewSurface(),
+                            getValidParentSurfaceForMagnifier(),
                             mWindowWidth, mWindowHeight, mWindowElevation, mWindowCornerRadius,
                             Handler.getMain() /* draw the magnifier on the UI thread */, mLock,
                             mCallback);
@@ -245,18 +245,20 @@
     }
 
     @Nullable
-    private Surface getValidViewSurface() {
-        // TODO: deduplicate this against the first part of #performPixelCopy
-        final Surface surface;
-        if (mView instanceof SurfaceView) {
-            surface = ((SurfaceView) mView).getHolder().getSurface();
-        } else if (mView.getViewRootImpl() != null) {
-            surface = mView.getViewRootImpl().mSurface;
-        } else {
-            surface = null;
+    private Surface getValidParentSurfaceForMagnifier() {
+        if (mView.getViewRootImpl() != null) {
+            final Surface mainWindowSurface = mView.getViewRootImpl().mSurface;
+            if (mainWindowSurface != null && mainWindowSurface.isValid()) {
+                return mainWindowSurface;
+            }
         }
-
-        return (surface != null && surface.isValid()) ? surface : null;
+        if (mView instanceof SurfaceView) {
+            final Surface surfaceViewSurface = ((SurfaceView) mView).getHolder().getSurface();
+            if (surfaceViewSurface != null && surfaceViewSurface.isValid()) {
+                return surfaceViewSurface;
+            }
+        }
+        return null;
     }
 
     private void configureCoordinates(final float xPosInView, final float yPosInView) {
@@ -264,12 +266,12 @@
         // magnifier. These are relative to the surface the content is copied from.
         final float posX;
         final float posY;
+        mView.getLocationInSurface(mViewCoordinatesInSurface);
         if (mView instanceof SurfaceView) {
             // No offset required if the backing Surface matches the size of the SurfaceView.
             posX = xPosInView;
             posY = yPosInView;
         } else {
-            mView.getLocationInSurface(mViewCoordinatesInSurface);
             posX = xPosInView + mViewCoordinatesInSurface[0];
             posY = yPosInView + mViewCoordinatesInSurface[1];
         }
@@ -282,6 +284,14 @@
                 R.dimen.magnifier_offset);
         mWindowCoords.x = mCenterZoomCoords.x - mWindowWidth / 2;
         mWindowCoords.y = mCenterZoomCoords.y - mWindowHeight / 2 - verticalOffset;
+        if (mView instanceof SurfaceView && mView.getViewRootImpl() != null) {
+            // TODO: deduplicate against the first part of #getValidParentSurfaceForMagnifier()
+            final Surface mainWindowSurface = mView.getViewRootImpl().mSurface;
+            if (mainWindowSurface != null && mainWindowSurface.isValid()) {
+                mWindowCoords.x += mViewCoordinatesInSurface[0];
+                mWindowCoords.y += mViewCoordinatesInSurface[1];
+            }
+        }
     }
 
     private void performPixelCopy(final int startXInSurface, final int startYInSurface,
@@ -361,6 +371,9 @@
         // The alpha set on the magnifier's content, which defines how
         // prominent the white background is.
         private static final int CONTENT_BITMAP_ALPHA = 242;
+        // The z of the magnifier surface, defining its z order in the list of
+        // siblings having the same parent surface (usually the main app surface).
+        private static final int SURFACE_Z = 5;
 
         // Display associated to the view the magnifier is attached to.
         private final Display mDisplay;
@@ -602,6 +615,7 @@
                                     mSurfaceControl.setPosition(pendingX, pendingY);
                                 }
                                 if (firstDraw) {
+                                    mSurfaceControl.setLayer(SURFACE_Z);
                                     mSurfaceControl.show();
                                 }
                                 SurfaceControl.closeTransaction();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 5ecbf90a..4865dab 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -21,6 +21,7 @@
 import android.annotation.ColorInt;
 import android.annotation.DimenRes;
 import android.annotation.NonNull;
+import android.annotation.StyleRes;
 import android.app.ActivityOptions;
 import android.app.ActivityThread;
 import android.app.Application;
@@ -56,6 +57,7 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.Log;
+import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.LayoutInflater.Filter;
 import android.view.RemotableViewMethod;
@@ -182,6 +184,12 @@
     private boolean mIsRoot = true;
 
     /**
+     * Optional theme resource id applied in inflateView(). When 0, Theme.DeviceDefault will be
+     * used.
+     */
+    private int mApplyThemeResId;
+
+    /**
      * Whether reapply is disallowed on this remoteview. This maybe be true if some actions modify
      * the layout in a way that isn't recoverable, since views are being removed.
      */
@@ -3267,6 +3275,14 @@
     }
 
     /**
+     * Set the theme used in apply() and applyASync().
+     * @hide
+     */
+    public void setApplyTheme(@StyleRes int themeResId) {
+        mApplyThemeResId = themeResId;
+    }
+
+    /**
      * Inflates the view hierarchy represented by this object and applies
      * all of the actions.
      *
@@ -3301,6 +3317,10 @@
         final Context contextForResources = getContextForResources(context);
         Context inflationContext = new RemoteViewsContextWrapper(context, contextForResources);
 
+        // If mApplyThemeResId is not given, Theme.DeviceDefault will be used.
+        if (mApplyThemeResId != 0) {
+            inflationContext = new ContextThemeWrapper(inflationContext, mApplyThemeResId);
+        }
         LayoutInflater inflater = (LayoutInflater)
                 context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 63c2e96..f70c554 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -452,7 +452,7 @@
             mLineHeight = context.getResources()
                     .getDimensionPixelSize(R.dimen.floating_toolbar_height);
             mIconTextSpacing = context.getResources()
-                    .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_side_padding);
+                    .getDimensionPixelSize(R.dimen.floating_toolbar_icon_text_spacing);
 
             // Interpolators
             mLogAccelerateInterpolator = new LogAccelerateInterpolator();
@@ -481,7 +481,7 @@
             mOverflowButton = createOverflowButton();
             mOverflowButtonSize = measure(mOverflowButton);
             mMainPanel = createMainPanel();
-            mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext);
+            mOverflowPanelViewHelper = new OverflowPanelViewHelper(mContext, mIconTextSpacing);
             mOverflowPanel = createOverflowPanel();
 
             // Animation. Need views.
@@ -1573,10 +1573,9 @@
 
             private final Context mContext;
 
-            public OverflowPanelViewHelper(Context context) {
+            public OverflowPanelViewHelper(Context context, int iconTextSpacing) {
                 mContext = Preconditions.checkNotNull(context);
-                mIconTextSpacing = context.getResources()
-                        .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_side_padding);
+                mIconTextSpacing = iconTextSpacing;
                 mSidePadding = context.getResources()
                         .getDimensionPixelSize(R.dimen.floating_toolbar_overflow_side_padding);
                 mCalculator = createMenuButton(null);
diff --git a/core/res/res/anim-ldrtl/task_close_enter.xml b/core/res/res/anim-ldrtl/task_close_enter.xml
new file mode 100644
index 0000000..7abada3
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_close_enter.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_close_exit.xml b/core/res/res/anim-ldrtl/task_close_exit.xml
new file mode 100644
index 0000000..a017820
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_close_exit.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="283"/>
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="-105%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0"
+        android:toXScale="0.95"
+        android:fromYScale="1.0"
+        android:toYScale="0.95"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <!-- This is needed to keep the animation running while task_open_enter completes -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:duration="600"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_enter.xml b/core/res/res/anim-ldrtl/task_open_enter.xml
new file mode 100644
index 0000000..0433664
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_enter.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+<!-- This should in sync with task_open_enter_cross_profile_apps.xml -->
+<!-- This should in sync with cross_profile_apps_thumbnail_enter.xml -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="-105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml
new file mode 100644
index 0000000..45ca80e
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_enter_cross_profile_apps.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ 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
+  -->
+<!-- This should in sync with task_open_enter.xml -->
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:zAdjustment="top"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1"
+        android:toAlpha="1.0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="217"/>
+
+    <translate
+        android:fromXDelta="-105%"
+        android:toXDelta="0"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0526"
+        android:toXScale="1"
+        android:fromYScale="1.0526"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <scale
+        android:fromXScale="0.95"
+        android:toXScale="1"
+        android:fromYScale="0.95"
+        android:toYScale="1"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:startOffset="283"
+        android:duration="317"/>
+
+    <!-- To keep the transition around longer for the thumbnail, should be kept in sync with
+         cross_profile_apps_thumbmail.xml -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:startOffset="717"
+        android:duration="200"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim-ldrtl/task_open_exit.xml b/core/res/res/anim-ldrtl/task_open_exit.xml
new file mode 100644
index 0000000..f50494d
--- /dev/null
+++ b/core/res/res/anim-ldrtl/task_open_exit.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ 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
+  -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shareInterpolator="false"
+    android:showWallpaper="true">
+
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/linear"
+        android:startOffset="67"
+        android:duration="283"/>
+
+    <translate
+        android:fromXDelta="0"
+        android:toXDelta="105%"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:interpolator="@interpolator/aggressive_ease"
+        android:startOffset="50"
+        android:duration="383"/>
+
+    <scale
+        android:fromXScale="1.0"
+        android:toXScale="0.95"
+        android:fromYScale="1.0"
+        android:toYScale="0.95"
+        android:fillEnabled="true"
+        android:fillBefore="true"
+        android:fillAfter="true"
+        android:pivotX="50%"
+        android:pivotY="50%"
+        android:interpolator="@interpolator/fast_out_slow_in"
+        android:duration="283"/>
+
+    <!-- This is needed to keep the animation running while task_open_enter completes -->
+    <alpha
+        android:fromAlpha="1.0"
+        android:toAlpha="1.0"
+        android:duration="600"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/task_close_enter.xml b/core/res/res/anim/task_close_enter.xml
index c298b80..b059aa9 100644
--- a/core/res/res/anim/task_close_enter.xml
+++ b/core/res/res/anim/task_close_enter.xml
@@ -31,7 +31,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="105%"
+        android:fromXDelta="-105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_close_exit.xml b/core/res/res/anim/task_close_exit.xml
index 9394c57..c9ade22 100644
--- a/core/res/res/anim/task_close_exit.xml
+++ b/core/res/res/anim/task_close_exit.xml
@@ -32,7 +32,7 @@
 
     <translate
         android:fromXDelta="0"
-        android:toXDelta="-105%"
+        android:toXDelta="105%"
         android:fillEnabled="true"
         android:fillBefore="true"
         android:fillAfter="true"
diff --git a/core/res/res/anim/task_open_enter.xml b/core/res/res/anim/task_open_enter.xml
index e23201f..5c61859 100644
--- a/core/res/res/anim/task_open_enter.xml
+++ b/core/res/res/anim/task_open_enter.xml
@@ -33,7 +33,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="-105%"
+        android:fromXDelta="105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_open_enter_cross_profile_apps.xml b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
index defea08..6441047 100644
--- a/core/res/res/anim/task_open_enter_cross_profile_apps.xml
+++ b/core/res/res/anim/task_open_enter_cross_profile_apps.xml
@@ -33,7 +33,7 @@
         android:duration="217"/>
 
     <translate
-        android:fromXDelta="-105%"
+        android:fromXDelta="105%"
         android:toXDelta="0"
         android:fillEnabled="true"
         android:fillBefore="true"
diff --git a/core/res/res/anim/task_open_exit.xml b/core/res/res/anim/task_open_exit.xml
index c9ade22..9394c57 100644
--- a/core/res/res/anim/task_open_exit.xml
+++ b/core/res/res/anim/task_open_exit.xml
@@ -32,7 +32,7 @@
 
     <translate
         android:fromXDelta="0"
-        android:toXDelta="105%"
+        android:toXDelta="-105%"
         android:fillEnabled="true"
         android:fillBefore="true"
         android:fillAfter="true"
diff --git a/core/res/res/layout-television/autofill_save.xml b/core/res/res/layout-television/autofill_save.xml
new file mode 100644
index 0000000..ebd2dec
--- /dev/null
+++ b/core/res/res/layout-television/autofill_save.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- NOTE: outer layout is required to provide proper shadow. -->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:orientation="horizontal"
+        android:id="@+id/autofill_save"
+        android:background="?android:attr/colorBackground"
+        android:layout_marginTop="32dp"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingStart="40dp"
+        android:paddingEnd="40dp"
+        android:paddingTop="40dp"
+        android:paddingBottom="40dp">
+
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_marginEnd="32dp">
+
+            <LinearLayout
+                android:orientation="horizontal"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginBottom="6dp">
+
+                <ImageView
+                    android:id="@+id/autofill_save_icon"
+                    android:scaleType="fitStart"
+                    android:layout_marginEnd="10dp"
+                    android:layout_gravity="center_vertical"
+                    android:layout_width="48dp"
+                    android:layout_height="48dp"/>
+                <TextView
+                    android:id="@+id/autofill_save_title"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/autofill_save_title"
+                    android:layout_gravity="center_vertical"
+                    android:textSize="24sp" />
+            </LinearLayout>
+
+            <com.android.server.autofill.ui.CustomScrollView
+                android:id="@+id/autofill_save_custom_subtitle"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="4dp"
+                android:visibility="gone"/>
+
+        </LinearLayout>
+
+        <LinearLayout
+            android:layout_width="304dp"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+
+            <Button
+                android:id="@+id/autofill_save_no"
+                style="?attr/borderlessButtonStyle"
+                android:textAlignment="viewStart"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/autofill_save_no">
+            </Button>
+
+            <Button
+                android:id="@+id/autofill_save_yes"
+                style="?attr/borderlessButtonStyle"
+                android:textAlignment="viewStart"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/autofill_save_yes">
+            </Button>
+        </LinearLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker.xml b/core/res/res/layout/autofill_dataset_picker.xml
index ef19f87..a88836e 100644
--- a/core/res/res/layout/autofill_dataset_picker.xml
+++ b/core/res/res/layout/autofill_dataset_picker.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<view  xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
+<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -31,4 +30,4 @@
         android:visibility="gone">
     </ListView>
 
-</view>
+</FrameLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
index 07298c1..1d2b5e5 100644
--- a/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
+++ b/core/res/res/layout/autofill_dataset_picker_fullscreen.xml
@@ -14,35 +14,73 @@
      limitations under the License.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_dataset_picker"
-    style="@style/AutofillDatasetPicker"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:background="?android:attr/windowBackground"
+    android:paddingStart="40dp"
+    android:paddingEnd="40dp"
+    android:paddingTop="40dp"
+    android:paddingBottom="40dp">
 
-    <TextView
-        android:layout_width="wrap_content"
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:text="@string/autofill_window_title"
-        android:layout_above="@+id/autofill_dataset_container"
-        android:layout_alignStart="@+id/autofill_dataset_container"
-        android:textSize="16sp"/>
+        android:layout_weight="1"
+        android:layout_marginEnd="32dp">
+
+        <LinearLayout
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginBottom="6dp"
+            >
+            <ImageView
+                android:id="@+id/autofill_dataset_icon"
+                android:scaleType="fitStart"
+                android:layout_marginEnd="10dp"
+                android:layout_gravity="center_vertical"
+                android:layout_width="48dp"
+                android:layout_height="48dp"/>
+            <TextView
+                android:id="@+id/autofill_dataset_title"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:textSize="24sp" />
+        </LinearLayout>
+
+        <LinearLayout
+            android:id="@+id/autofill_dataset_header"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"/>
+
+    </LinearLayout>
 
     <!-- autofill_container is the common parent for inserting authentication item or
-         autofill_dataset_list-->
-    <FrameLayout
-        android:id="@+id/autofill_dataset_container"
-        android:layout_width="wrap_content"
+         autofill_dataset_list, autofill_dataset_foolter-->
+    <LinearLayout
+        android:layout_width="304dp"
         android:layout_height="wrap_content"
-        android:layout_centerInParent="true">
+        android:id="@+id/autofill_dataset_picker"
+        android:orientation="vertical">
         <ListView
             android:id="@+id/autofill_dataset_list"
-            android:layout_width="wrap_content"
+            android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:clickable="true"
             android:divider="@null"
             android:drawSelectorOnTop="true"
             android:visibility="gone"/>
-    </FrameLayout>
+        <LinearLayout
+            android:id="@+id/autofill_dataset_footer"
+            android:visibility="gone"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical"/>
+    </LinearLayout>
 
-</RelativeLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/res/res/layout/autofill_dataset_picker_header_footer.xml b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
index 048494a..093f035 100644
--- a/core/res/res/layout/autofill_dataset_picker_header_footer.xml
+++ b/core/res/res/layout/autofill_dataset_picker_header_footer.xml
@@ -14,8 +14,7 @@
      limitations under the License.
 -->
 
-<view  xmlns:android="http://schemas.android.com/apk/res/android"
-    class="com.android.server.autofill.ui.FillUi$AutofillFrameLayout"
+<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/autofill_dataset_picker"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
@@ -54,4 +53,4 @@
 
     </LinearLayout>
 
-</view>
+</FrameLayout>
diff --git a/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml b/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml
deleted file mode 100644
index 24b14a0..0000000
--- a/core/res/res/layout/autofill_dataset_picker_header_footer_fullscreen.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/autofill_dataset_picker"
-    style="@style/AutofillDatasetPicker"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent">
-
-    <TextView
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="@string/autofill_window_title"
-        android:layout_above="@+id/autofill_dataset_container"
-        android:layout_alignStart="@+id/autofill_dataset_container"
-        android:textSize="16sp"/>
-
-    <!-- autofill_container is the common parent for inserting authentication item or
-         autofill_dataset_list-->
-    <FrameLayout
-        android:id="@+id/autofill_dataset_container"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_centerInParent="true">
-
-        <LinearLayout
-            xmlns:android="http://schemas.android.com/apk/res/android"
-            android:layout_width="fill_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <LinearLayout
-                android:id="@+id/autofill_dataset_header"
-                android:visibility="gone"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"/>
-
-            <ListView
-                android:id="@+id/autofill_dataset_list"
-                android:layout_weight="1"
-                android:layout_width="fill_parent"
-                android:layout_height="0dp"
-                android:clickable="true"
-                android:divider="@null"
-                android:drawSelectorOnTop="true"
-                android:visibility="gone"/>
-
-            <LinearLayout
-                android:id="@+id/autofill_dataset_footer"
-                android:visibility="gone"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:orientation="vertical"/>
-
-        </LinearLayout>
-
-    </FrameLayout>
-
-</RelativeLayout>
diff --git a/core/res/res/values-television/dimens.xml b/core/res/res/values-television/dimens.xml
index aa56251..4c25225 100644
--- a/core/res/res/values-television/dimens.xml
+++ b/core/res/res/values-television/dimens.xml
@@ -20,8 +20,4 @@
      <item type="dimen" format="float" name="ambient_shadow_alpha">0.15</item>
      <item type="dimen" format="float" name="spot_shadow_alpha">0.3</item>
 
-     <!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
-     <dimen name="autofill_dataset_picker_max_width">60%</dimen>
-     <dimen name="autofill_dataset_picker_max_height">70%</dimen>
-
 </resources>
diff --git a/core/res/res/values-television/themes_device_defaults.xml b/core/res/res/values-television/themes_device_defaults.xml
index e01caa3..e380a7b 100644
--- a/core/res/res/values-television/themes_device_defaults.xml
+++ b/core/res/res/values-television/themes_device_defaults.xml
@@ -16,4 +16,6 @@
 <resources>
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Leanback.Dialog.Alert" />
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Leanback.Light.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill" />
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save" />
 </resources>
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index 3609fb8..2966aff 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -145,4 +145,8 @@
     <color name="datepicker_default_view_animator_color_material_light">#fff2f2f2</color>
     <color name="datepicker_default_view_animator_color_material_dark">#ff303030</color>
 
+    <!-- Autofill colors -->
+    <color name="autofill_background_material_dark">@color/material_blue_grey_900</color>
+    <color name="autofill_background_material_light">@color/material_grey_50</color>
+
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 84f23a9..860dd87 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -531,7 +531,7 @@
     <dimen name="floating_toolbar_menu_image_width">24dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_width">56dp</dimen>
     <dimen name="floating_toolbar_menu_image_button_vertical_padding">12dp</dimen>
-    <dimen name="floating_toolbar_menu_button_side_padding">8dp</dimen>
+    <dimen name="floating_toolbar_menu_button_side_padding">11dp</dimen>
     <dimen name="floating_toolbar_overflow_image_button_width">60dp</dimen>
     <dimen name="floating_toolbar_overflow_side_padding">18dp</dimen>
     <dimen name="floating_toolbar_text_size">14sp</dimen>
@@ -542,6 +542,7 @@
     <dimen name="floating_toolbar_horizontal_margin">16dp</dimen>
     <dimen name="floating_toolbar_vertical_margin">8dp</dimen>
     <dimen name="content_rect_bottom_clip_allowance">20dp</dimen>
+    <dimen name="floating_toolbar_icon_text_spacing">8dp</dimen>
 
     <!-- Magnifier dimensions -->
     <dimen name="magnifier_width">100dp</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e5bb587..b92052b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2196,8 +2196,8 @@
     <!-- Text to show in the auto complete drop down list on a text view when the WebView can auto fill the entire form but the user has not configured an AutoFill profile [CHAR-LIMIT=19] -->
     <string name="setup_autofill">Set up Autofill</string>
 
-    <!-- Title of fullscreen autofill window [CHAR-LIMIT=80] -->
-    <string name="autofill_window_title">Autofill</string>
+    <!-- Title of fullscreen autofill window, including the name of which autofill service it is using [CHAR-LIMIT=NONE] -->
+    <string name="autofill_window_title">Autofill with <xliff:g id="serviceName" example="MyPass">%1$s</xliff:g></string>
 
     <!-- String used to separate FirstName and LastName when writing out a local name
          e.g. John<separator>Smith [CHAR-LIMIT=NONE]-->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 984461b..50a6ff3 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -1487,13 +1487,19 @@
         <item name="successColor">@color/lock_pattern_view_success_color</item>
     </style>
 
-    <!-- @hide -->
+    <!-- @hide Autofill background for popup window (not for fullscreen) -->
     <style name="AutofillDatasetPicker">
         <item name="elevation">4dp</item>
         <item name="background">@drawable/autofill_dataset_picker_background</item>
     </style>
 
     <!-- @hide -->
+    <style name="AutofillHalfScreenAnimation">
+        <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
+        <item name="android:windowExitAnimation">@anim/slide_out_down</item>
+    </style>
+
+    <!-- @hide -->
     <style name="AutofillSaveAnimation">
         <item name="android:windowEnterAnimation">@anim/slide_in_up</item>
         <item name="android:windowExitAnimation">@anim/slide_out_down</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f01816e..b7f5b62 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -663,6 +663,7 @@
   <java-symbol type="string" name="autofill_state_re" />
   <java-symbol type="string" name="autofill_this_form" />
   <java-symbol type="string" name="autofill_username_re" />
+  <java-symbol type="string" name="autofill_window_title" />
   <java-symbol type="string" name="autofill_zip_4_re" />
   <java-symbol type="string" name="autofill_zip_code" />
   <java-symbol type="string" name="autofill_zip_code_re" />
@@ -2576,6 +2577,7 @@
   <java-symbol type="dimen" name="floating_toolbar_maximum_overflow_height" />
   <java-symbol type="dimen" name="floating_toolbar_horizontal_margin" />
   <java-symbol type="dimen" name="floating_toolbar_vertical_margin" />
+  <java-symbol type="dimen" name="floating_toolbar_icon_text_spacing" />
   <java-symbol type="dimen" name="content_rect_bottom_clip_allowance" />
   <java-symbol type="drawable" name="ft_avd_tooverflow" />
   <java-symbol type="drawable" name="ft_avd_toarrow" />
@@ -3052,13 +3054,13 @@
   <java-symbol type="layout" name="autofill_dataset_picker"/>
   <java-symbol type="layout" name="autofill_dataset_picker_fullscreen"/>
   <java-symbol type="layout" name="autofill_dataset_picker_header_footer"/>
-  <java-symbol type="layout" name="autofill_dataset_picker_header_footer_fullscreen"/>
   <java-symbol type="id" name="autofill" />
-  <java-symbol type="id" name="autofill_dataset_container"/>
   <java-symbol type="id" name="autofill_dataset_footer"/>
   <java-symbol type="id" name="autofill_dataset_header"/>
+  <java-symbol type="id" name="autofill_dataset_icon" />
   <java-symbol type="id" name="autofill_dataset_list"/>
   <java-symbol type="id" name="autofill_dataset_picker"/>
+  <java-symbol type="id" name="autofill_dataset_title" />
   <java-symbol type="id" name="autofill_save_custom_subtitle" />
   <java-symbol type="id" name="autofill_save_icon" />
   <java-symbol type="id" name="autofill_save_no" />
@@ -3083,6 +3085,7 @@
   <java-symbol type="string" name="autofill_save_type_email_address" />
   <java-symbol type="drawable" name="autofill_dataset_picker_background" />
   <java-symbol type="style" name="AutofillDatasetPicker" />
+  <java-symbol type="style" name="AutofillHalfScreenAnimation" />
   <java-symbol type="style" name="AutofillSaveAnimation" />
   <java-symbol type="dimen" name="autofill_dataset_picker_max_width"/>
   <java-symbol type="dimen" name="autofill_dataset_picker_max_height"/>
@@ -3090,6 +3093,9 @@
   <java-symbol type="dimen" name="autofill_save_icon_max_size"/>
   <java-symbol type="integer" name="autofill_max_visible_datasets" />
 
+  <java-symbol type="style" name="Theme.DeviceDefault.Autofill" />
+  <java-symbol type="style" name="Theme.DeviceDefault.Autofill.Save" />
+
   <java-symbol type="dimen" name="notification_big_picture_max_height"/>
   <java-symbol type="dimen" name="notification_big_picture_max_width"/>
   <java-symbol type="dimen" name="notification_media_image_max_width"/>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 92b2f33..14e5082 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1673,6 +1673,15 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
+
+    <!-- @hide DeviceDefault theme for the autofill FillUi -->
+    <style name="Theme.DeviceDefault.Autofill" parent="Theme.Material.Autofill.Light">
+    </style>
+
+    <!-- @hide DeviceDefault theme for the autofill SaveUi -->
+    <style name="Theme.DeviceDefault.Autofill.Save" parent="Theme.Material.Autofill.Save.Light">
+    </style>
+
     <!-- DeviceDefault theme for the default system theme.  -->
     <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault.Light.DarkActionBar" />
 
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 9b633fc..b3e33d5 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -1417,4 +1417,25 @@
         <item name="colorPrimaryDark">@color/primary_dark_material_settings</item>
         <item name="colorSecondary">@color/secondary_material_settings</item>
     </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill" parent="Theme.Material">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Light" parent="Theme.Material.Light">
+        <item name="colorBackground">@color/autofill_background_material_light</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Save" parent="Theme.Material.Panel">
+        <item name="colorBackground">@color/autofill_background_material_dark</item>
+    </style>
+
+    <!-- @hide -->
+    <style name="Theme.Material.Autofill.Save.Light" parent="Theme.Material.Light.Panel">
+        <item name="colorBackground">@color/autofill_background_material_light</item>
+    </style>
+
 </resources>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index 43e980e..dafd475 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -98,6 +98,7 @@
     private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS =
             newHashSet(
                     Settings.Global.ACTIVITY_MANAGER_CONSTANTS,
+                    Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED,
                     Settings.Global.ADB_ENABLED,
                     Settings.Global.ADD_USERS_WHEN_LOCKED,
                     Settings.Global.AIRPLANE_MODE_ON,
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index 0e2a0e0..91c04fa 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -321,6 +321,7 @@
         // TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
         new Thread(new Runnable() {
             public void run() {
+                final Network network = ResolvUtil.makeNetworkWithPrivateDnsBypass(mNetwork);
                 // Give time for captive portal to open.
                 try {
                     Thread.sleep(1000);
@@ -329,7 +330,7 @@
                 HttpURLConnection urlConnection = null;
                 int httpResponseCode = 500;
                 try {
-                    urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
+                    urlConnection = (HttpURLConnection) network.openConnection(mUrl);
                     urlConnection.setInstanceFollowRedirects(false);
                     urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
                     urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index aeb4a85..8bab3ca 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -46,6 +46,7 @@
 import com.android.internal.widget.LockPatternUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * Utility class to host methods usable in adding a restricted padlock icon and showing admin
@@ -90,29 +91,29 @@
             // Restriction is not enforced.
             return null;
         } else if (enforcingUsers.size() > 1) {
-            return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+            return EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         final int restrictionSource = enforcingUsers.get(0).getUserRestrictionSource();
         final int adminUserId = enforcingUsers.get(0).getUserHandle().getIdentifier();
-
         if (restrictionSource == UserManager.RESTRICTION_SOURCE_PROFILE_OWNER) {
             // Check if it is a profile owner of the user under consideration.
             if (adminUserId == userId) {
-                return getProfileOwner(context, adminUserId);
+                return getProfileOwner(context, userRestriction, adminUserId);
             } else {
                 // Check if it is a profile owner of a managed profile of the current user.
                 // Otherwise it is in a separate user and we return a default EnforcedAdmin.
                 final UserInfo parentUser = um.getProfileParent(adminUserId);
                 return (parentUser != null && parentUser.id == userId)
-                        ? getProfileOwner(context, adminUserId)
-                        : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                        ? getProfileOwner(context, userRestriction, adminUserId)
+                        : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
             }
         } else if (restrictionSource == UserManager.RESTRICTION_SOURCE_DEVICE_OWNER) {
             // When the restriction is enforced by device owner, return the device owner admin only
             // if the admin is for the {@param userId} otherwise return a default EnforcedAdmin.
             return adminUserId == userId
-                    ? getDeviceOwner(context) : EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN;
+                    ? getDeviceOwner(context, userRestriction)
+                    : EnforcedAdmin.createDefaultEnforcedAdminWithRestriction(userRestriction);
         }
 
         // If the restriction is enforced by system then return null.
@@ -406,7 +407,6 @@
      * or {@code null} if no quality requirements are set. If the requirements are set by
      * multiple device admins, then the admin component will be set to {@code null} and userId to
      * {@link UserHandle#USER_NULL}.
-     *
      */
     public static EnforcedAdmin checkIfPasswordQualityIsSet(Context context, int userId) {
         final LockSettingCheck check =
@@ -518,6 +518,11 @@
     }
 
     public static EnforcedAdmin getProfileOrDeviceOwner(Context context, int userId) {
+        return getProfileOrDeviceOwner(context, null, userId);
+    }
+
+    public static EnforcedAdmin getProfileOrDeviceOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -528,18 +533,22 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         if (dpm.getDeviceOwnerUserId() == userId) {
             adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
             if (adminComponent != null) {
-                return new EnforcedAdmin(adminComponent, userId);
+                return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
             }
         }
         return null;
     }
 
     public static EnforcedAdmin getDeviceOwner(Context context) {
+        return getDeviceOwner(context, null);
+    }
+
+    private static EnforcedAdmin getDeviceOwner(Context context, String enforcedRestriction) {
         final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
         if (dpm == null) {
@@ -547,12 +556,18 @@
         }
         ComponentName adminComponent = dpm.getDeviceOwnerComponentOnAnyUser();
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, dpm.getDeviceOwnerUserId());
+            return new EnforcedAdmin(
+                    adminComponent, enforcedRestriction, dpm.getDeviceOwnerUserId());
         }
         return null;
     }
 
     private static EnforcedAdmin getProfileOwner(Context context, int userId) {
+        return getProfileOwner(context, null, userId);
+    }
+
+    private static EnforcedAdmin getProfileOwner(
+            Context context, String enforcedRestriction, int userId) {
         if (userId == UserHandle.USER_NULL) {
             return null;
         }
@@ -563,7 +578,7 @@
         }
         ComponentName adminComponent = dpm.getProfileOwnerAsUser(userId);
         if (adminComponent != null) {
-            return new EnforcedAdmin(adminComponent, userId);
+            return new EnforcedAdmin(adminComponent, enforcedRestriction, userId);
         }
         return null;
     }
@@ -626,6 +641,7 @@
                 && isCurrentUserOrProfile(context, admin.userId)) {
             targetUserId = admin.userId;
         }
+        intent.putExtra(DevicePolicyManager.EXTRA_RESTRICTION, admin.enforcedRestriction);
         context.startActivityAsUser(intent, new UserHandle(targetUserId));
     }
 
@@ -700,53 +716,71 @@
     }
 
     public static class EnforcedAdmin {
+        @Nullable
         public ComponentName component = null;
+        /**
+         * The restriction enforced by admin. It could be any user restriction or policy like
+         * {@link DevicePolicyManager#POLICY_DISABLE_CAMERA}.
+         */
+        @Nullable
+        public String enforcedRestriction = null;
         public int userId = UserHandle.USER_NULL;
 
         // We use this to represent the case where a policy is enforced by multiple admins.
         public final static EnforcedAdmin MULTIPLE_ENFORCED_ADMIN = new EnforcedAdmin();
 
+        public static EnforcedAdmin createDefaultEnforcedAdminWithRestriction(
+                String enforcedRestriction) {
+            EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
+            enforcedAdmin.enforcedRestriction = enforcedRestriction;
+            return enforcedAdmin;
+        }
+
         public EnforcedAdmin(ComponentName component, int userId) {
             this.component = component;
             this.userId = userId;
         }
 
+        public EnforcedAdmin(ComponentName component, String enforcedRestriction, int userId) {
+            this.component = component;
+            this.enforcedRestriction = enforcedRestriction;
+            this.userId = userId;
+        }
+
         public EnforcedAdmin(EnforcedAdmin other) {
             if (other == null) {
                 throw new IllegalArgumentException();
             }
             this.component = other.component;
+            this.enforcedRestriction = other.enforcedRestriction;
             this.userId = other.userId;
         }
 
-        public EnforcedAdmin() {}
+        public EnforcedAdmin() {
+        }
 
         @Override
-        public boolean equals(Object object) {
-            if (object == this) return true;
-            if (!(object instanceof EnforcedAdmin)) return false;
-            EnforcedAdmin other = (EnforcedAdmin) object;
-            if (userId != other.userId) {
-                return false;
-            }
-            if ((component == null && other.component == null) ||
-                    (component != null && component.equals(other.component))) {
-                return true;
-            }
-            return false;
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            EnforcedAdmin that = (EnforcedAdmin) o;
+            return userId == that.userId &&
+                    Objects.equals(component, that.component) &&
+                    Objects.equals(enforcedRestriction, that.enforcedRestriction);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(component, enforcedRestriction, userId);
         }
 
         @Override
         public String toString() {
-            return "EnforcedAdmin{component=" + component + ",userId=" + userId + "}";
-        }
-
-        public void copyTo(EnforcedAdmin other) {
-            if (other == null) {
-                throw new IllegalArgumentException();
-            }
-            other.component = component;
-            other.userId = userId;
+            return "EnforcedAdmin{" +
+                    "component=" + component +
+                    ", enforcedRestriction='" + enforcedRestriction +
+                    ", userId=" + userId +
+                    '}';
         }
     }
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
index 5f60868..710dbc22 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/RestrictedLockUtilsTest.java
@@ -32,6 +32,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.content.pm.UserInfo;
+import android.os.UserHandle;
 import android.os.UserManager;
 
 import org.junit.Before;
@@ -42,6 +43,7 @@
 import org.mockito.MockitoAnnotations;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 @RunWith(SettingsLibRobolectricTestRunner.class)
 public class RestrictedLockUtilsTest {
@@ -77,6 +79,42 @@
     }
 
     @Test
+    public void checkIfRestrictionEnforced_deviceOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpDeviceOwner(mAdmin1);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
+    public void checkIfRestrictionEnforced_profileOwner() {
+        UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
+                UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
+        final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
+        when(mUserManager.getUserRestrictionSources(userRestriction,
+                UserHandle.of(mUserId))).
+                thenReturn(Collections.singletonList(enforcingUser));
+        setUpProfileOwner(mAdmin1, mUserId);
+
+        EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfRestrictionEnforced(mContext,
+                userRestriction, mUserId);
+
+        assertThat(enforcedAdmin).isNotNull();
+        assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
+        assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
+    }
+
+    @Test
     public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
         final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfAccountManagementDisabled(
@@ -263,4 +301,12 @@
         when(mDevicePolicyManager.getActiveAdminsAsUser(userId))
                 .thenReturn(Arrays.asList(activeAdmins));
     }
+
+    private void setUpDeviceOwner(ComponentName admin) {
+        when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
+    }
+
+    private void setUpProfileOwner(ComponentName admin, int userId) {
+        when(mDevicePolicyManager.getProfileOwnerAsUser(userId)).thenReturn(admin);
+    }
 }
diff --git a/packages/SystemUI/res/layout/quick_qs_status_icons.xml b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
index 5f73bef..4301fdb 100644
--- a/packages/SystemUI/res/layout/quick_qs_status_icons.xml
+++ b/packages/SystemUI/res/layout/quick_qs_status_icons.xml
@@ -18,13 +18,15 @@
     xmlns:systemui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/quick_qs_status_icons"
     android:layout_width="match_parent"
-    android:layout_height="20dp"
+    android:layout_height="wrap_content"
     android:layout_marginTop="8dp"
     android:layout_marginBottom="14dp"
-    android:layout_marginStart="8dp"
-    android:layout_marginEnd="@dimen/notification_side_paddings"
+    android:layout_marginStart="@dimen/status_bar_padding_start"
+    android:layout_marginEnd="@dimen/status_bar_padding_end"
     android:layout_below="@id/quick_status_bar_system_icons"
-    android:paddingEnd="@dimen/status_bar_padding_end" >
+    android:clipChildren="false"
+    android:clipToPadding="false"
+    android:minHeight="20dp" >
 
     <com.android.systemui.statusbar.policy.DateView
         android:id="@+id/date"
diff --git a/packages/SystemUI/res/layout/quick_settings_header_info.xml b/packages/SystemUI/res/layout/quick_settings_header_info.xml
index 54baa4a..0892f73 100644
--- a/packages/SystemUI/res/layout/quick_settings_header_info.xml
+++ b/packages/SystemUI/res/layout/quick_settings_header_info.xml
@@ -45,14 +45,16 @@
             android:layout_width="@dimen/qs_header_alarm_icon_size"
             android:layout_height="@dimen/qs_header_alarm_icon_size"
             android:src="@drawable/stat_sys_alarm"
-            android:tint="?android:attr/textColorPrimary" />
+            android:tint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <TextView
             android:id="@+id/next_alarm_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-            android:textAppearance="@style/TextAppearance.QS.TileLabel" />
+            android:textAppearance="@style/TextAppearance.QS.TileLabel"
+            android:visibility="gone"/>
 
         <View
             android:id="@+id/status_separator"
@@ -61,20 +63,23 @@
             android:layout_marginStart="10dp"
             android:layout_marginEnd="10dp"
             android:background="@android:color/white"
-            android:backgroundTint="?android:attr/textColorPrimary" />
+            android:backgroundTint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <ImageView
             android:id="@+id/ringer_mode_icon"
             android:layout_width="@dimen/qs_header_alarm_icon_size"
             android:layout_height="@dimen/qs_header_alarm_icon_size"
-            android:tint="?android:attr/textColorPrimary" />
+            android:tint="?android:attr/textColorPrimary"
+            android:visibility="gone"/>
 
         <TextView
             android:id="@+id/ringer_mode_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/qs_header_alarm_text_margin_start"
-            android:textAppearance="@style/TextAppearance.QS.TileLabel" />
+            android:textAppearance="@style/TextAppearance.QS.TileLabel"
+            android:visibility="gone"/>
 
     </LinearLayout>
 
diff --git a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
index a9fe862..d40534e 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_header_system_icons.xml
@@ -20,15 +20,12 @@
     android:id="@+id/quick_status_bar_system_icons"
     android:layout_width="match_parent"
     android:layout_height="@*android:dimen/quick_qs_offset_height"
-    android:layout_marginRight="@dimen/notification_side_paddings"
-    android:layout_marginLeft="@dimen/notification_side_paddings"
-    android:layout_alignParentEnd="true"
     android:clipChildren="false"
     android:clipToPadding="false"
     android:gravity="center"
+    android:orientation="horizontal"
     android:paddingStart="@dimen/status_bar_padding_start"
-    android:paddingEnd="@dimen/status_bar_padding_end"
-    android:orientation="horizontal">
+    android:paddingEnd="@dimen/status_bar_padding_end" >
 
     <com.android.systemui.statusbar.policy.Clock
         android:id="@+id/clock"
diff --git a/packages/SystemUI/res/layout/volume_dnd_icon.xml b/packages/SystemUI/res/layout/volume_dnd_icon.xml
index acf9aed..215b230 100644
--- a/packages/SystemUI/res/layout/volume_dnd_icon.xml
+++ b/packages/SystemUI/res/layout/volume_dnd_icon.xml
@@ -15,16 +15,16 @@
 -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="@dimen/volume_dialog_panel_width"
-    android:layout_height="wrap_content">
+    android:layout_width="14dp"
+    android:layout_height="14dp"
+    android:layout_marginTop="6dp"
+    android:layout_marginRight="6dp"
+    android:layout_gravity="right|top">
 
     <ImageView
         android:id="@+id/dnd_icon"
-        android:layout_width="14dp"
-        android:layout_height="14dp"
-        android:layout_marginTop="6dp"
-        android:layout_marginRight="6dp"
-        android:layout_gravity="right|top"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
         android:src="@drawable/ic_dnd"
         android:tint="?android:attr/textColorTertiary"/>
 </FrameLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 875000c..ac9fb2b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -326,7 +326,7 @@
     <dimen name="pull_span_min">25dp</dimen>
 
     <dimen name="qs_tile_height">106dp</dimen>
-    <dimen name="qs_tile_layout_margin_side">9dp</dimen>
+    <dimen name="qs_tile_layout_margin_side">6dp</dimen>
     <dimen name="qs_tile_margin_horizontal">18dp</dimen>
     <dimen name="qs_tile_margin_vertical">24dp</dimen>
     <dimen name="qs_tile_margin_top_bottom">12dp</dimen>
@@ -917,6 +917,8 @@
     <dimen name="edge_margin">8dp</dimen>
 
     <dimen name="rounded_corner_radius">0dp</dimen>
+    <dimen name="rounded_corner_radius_top">0dp</dimen>
+    <dimen name="rounded_corner_radius_bottom">0dp</dimen>
     <dimen name="rounded_corner_content_padding">0dp</dimen>
     <dimen name="nav_content_padding">0dp</dimen>
     <dimen name="nav_quick_scrub_track_edge_padding">42dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 72f6cdc..8d32e4d 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -78,6 +78,8 @@
             SystemProperties.getBoolean("debug.screenshot_rounded_corners", false);
 
     private int mRoundedDefault;
+    private int mRoundedDefaultTop;
+    private int mRoundedDefaultBottom;
     private View mOverlay;
     private View mBottomOverlay;
     private float mDensity;
@@ -89,9 +91,14 @@
         mWindowManager = mContext.getSystemService(WindowManager.class);
         mRoundedDefault = mContext.getResources().getDimensionPixelSize(
                 R.dimen.rounded_corner_radius);
-        if (mRoundedDefault != 0 || shouldDrawCutout()) {
+        mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_top);
+        mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize(
+                R.dimen.rounded_corner_radius_bottom);
+        if (hasRoundedCorners() || shouldDrawCutout()) {
             setupDecorations();
         }
+
         int padding = mContext.getResources().getDimensionPixelSize(
                 R.dimen.rounded_corner_content_padding);
         if (padding != 0) {
@@ -208,11 +215,15 @@
     private void updateWindowVisibility(View overlay) {
         boolean visibleForCutout = shouldDrawCutout()
                 && overlay.findViewById(R.id.display_cutout).getVisibility() == View.VISIBLE;
-        boolean visibleForRoundedCorners = mRoundedDefault > 0;
+        boolean visibleForRoundedCorners = hasRoundedCorners();
         overlay.setVisibility(visibleForCutout || visibleForRoundedCorners
                 ? View.VISIBLE : View.GONE);
     }
 
+    private boolean hasRoundedCorners() {
+        return mRoundedDefault > 0 || mRoundedDefaultBottom > 0 || mRoundedDefaultTop > 0;
+    }
+
     private boolean shouldDrawCutout() {
         return shouldDrawCutout(mContext);
     }
@@ -284,14 +295,26 @@
         if (mOverlay == null) return;
         if (SIZE.equals(key)) {
             int size = mRoundedDefault;
-            try {
-                size = (int) (Integer.parseInt(newValue) * mDensity);
-            } catch (Exception e) {
+            int sizeTop = mRoundedDefaultTop;
+            int sizeBottom = mRoundedDefaultBottom;
+            if (newValue != null) {
+                try {
+                    size = (int) (Integer.parseInt(newValue) * mDensity);
+                } catch (Exception e) {
+                }
             }
-            setSize(mOverlay.findViewById(R.id.left), size);
-            setSize(mOverlay.findViewById(R.id.right), size);
-            setSize(mBottomOverlay.findViewById(R.id.left), size);
-            setSize(mBottomOverlay.findViewById(R.id.right), size);
+
+            if (sizeTop == 0) {
+                sizeTop = size;
+            }
+            if (sizeBottom == 0) {
+                sizeBottom = size;
+            }
+
+            setSize(mOverlay.findViewById(R.id.left), sizeTop);
+            setSize(mOverlay.findViewById(R.id.right), sizeTop);
+            setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom);
+            setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom);
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index a44f9433..d8bf990 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -40,7 +40,7 @@
     private int mHeightOverride = -1;
     private QSPanel mQSPanel;
     private View mQSDetail;
-    private View mHeader;
+    private QuickStatusBarHeader mHeader;
     private float mQsExpansion;
     private QSCustomizer mQSCustomizer;
     private View mQSFooter;
@@ -178,7 +178,7 @@
         setMargins(mBackground);
         setMargins(mQSFooter);
         mQSPanel.setMargins(mSideMargins);
-        setMargins(mHeader);
+        mHeader.setMargins(mSideMargins);
     }
 
     private void setMargins(View view) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index f027c4b..ad2efbd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -41,6 +41,7 @@
 import android.view.View;
 import android.view.WindowInsets;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
@@ -591,4 +592,16 @@
     public static float getColorIntensity(@ColorInt int color) {
         return color == Color.WHITE ? 0 : 1;
     }
+
+    public void setMargins(int sideMargins) {
+        for (int i = 0; i < getChildCount(); i++) {
+            View v = getChildAt(i);
+            if (v == mSystemIconsView || v == mQuickQsStatusIcons || v == mHeaderQsPanel) {
+                continue;
+            }
+            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) v.getLayoutParams();
+            lp.leftMargin = sideMargins;
+            lp.rightMargin = sideMargins;
+        }
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 66176b3..5597ffd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -521,7 +521,7 @@
 
         // Clear any pending suggestion flag as it has either been nullified or is being shown
         mPendingRotationSuggestion = false;
-        getView().removeCallbacks(mCancelPendingRotationProposal);
+        if (getView() != null) getView().removeCallbacks(mCancelPendingRotationProposal);
 
         // Handle the visibility change and animation
         if (visible) { // Appear and change (cannot force)
@@ -1141,6 +1141,7 @@
         private final Runnable mRipple = new Runnable() {
             @Override
             public void run() { // Cause the ripple to fire via false presses
+                if (!mRoot.isAttachedToWindow()) return;
                 mRoot.setPressed(true);
                 mRoot.setPressed(false);
             }
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index e6b2a35..c055060 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -2079,7 +2079,8 @@
         }
 
         getUiForShowing().showFillUi(filledId, response, filterText,
-                mService.getServicePackageName(), mComponentName.getPackageName(), this);
+                mService.getServicePackageName(), mComponentName.getPackageName(),
+                mService.getServiceLabel(), mService.getServiceIcon(), this);
 
         synchronized (mLock) {
             if (mUiShownTime == 0) {
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 21a39e4..ee18dc2 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -163,11 +163,14 @@
      * @param filterText text of the view to be filled
      * @param servicePackageName package name of the autofill service filling the activity
      * @param packageName package name of the activity that is filled
+     * @param serviceLabel label of autofill service
+     * @param serviceIcon icon of autofill service
      * @param callback Identifier for the caller
      */
     public void showFillUi(@NonNull AutofillId focusedId, @NonNull FillResponse response,
             @Nullable String filterText, @Nullable String servicePackageName,
-            @NonNull String packageName, @NonNull AutoFillUiCallback callback) {
+            @NonNull String packageName, @NonNull CharSequence serviceLabel,
+            @NonNull Drawable serviceIcon, @NonNull AutoFillUiCallback callback) {
         if (sDebug) {
             final int size = filterText == null ? 0 : filterText.length();
             Slog.d(TAG, "showFillUi(): id=" + focusedId + ", filter=" + size + " chars");
@@ -185,7 +188,7 @@
             }
             hideAllUiThread(callback);
             mFillUi = new FillUi(mContext, response, focusedId,
-                    filterText, mOverlayControl, new FillUi.Callback() {
+                    filterText, mOverlayControl, serviceLabel, serviceIcon, new FillUi.Callback() {
                 @Override
                 public void onResponsePicked(FillResponse response) {
                     log.setType(MetricsEvent.TYPE_DETAIL);
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index d29ca05..1aeb3b9 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -26,6 +26,8 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.view.ContextThemeWrapper;
 import android.content.Intent;
 import android.content.IntentSender;
 import android.content.pm.PackageManager;
@@ -53,9 +55,11 @@
 import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.RemoteViews;
+import android.widget.TextView;
 
 import com.android.internal.R;
 import com.android.server.UiThread;
@@ -72,30 +76,10 @@
 final class FillUi {
     private static final String TAG = "FillUi";
 
+    private static final int THEME_ID = com.android.internal.R.style.Theme_DeviceDefault_Autofill;
+
     private static final TypedValue sTempTypedValue = new TypedValue();
 
-    public static final class AutofillFrameLayout extends FrameLayout {
-
-        OnKeyListener mUnhandledListener;
-
-        public AutofillFrameLayout(Context context, AttributeSet attrs) {
-            super(context, attrs);
-        }
-
-        public AutofillFrameLayout(Context context, AttributeSet attrs, @AttrRes int defStyleAttr) {
-            super(context, attrs, defStyleAttr);
-        }
-
-        @Override
-        public boolean dispatchKeyEvent(KeyEvent event) {
-            boolean handled = super.dispatchKeyEvent(event);
-            if (!handled) {
-                handled = mUnhandledListener.onKey(this, event.getKeyCode(), event);
-            }
-            return handled;
-        }
-    }
-
     interface Callback {
         void onResponsePicked(@NonNull FillResponse response);
         void onDatasetPicked(@NonNull Dataset dataset);
@@ -146,51 +130,64 @@
 
     FillUi(@NonNull Context context, @NonNull FillResponse response,
            @NonNull AutofillId focusedViewId, @NonNull @Nullable String filterText,
-           @NonNull OverlayControl overlayControl, @NonNull Callback callback) {
-        mContext = context;
+           @NonNull OverlayControl overlayControl, @NonNull CharSequence serviceLabel,
+           @NonNull Drawable serviceIcon, @NonNull Callback callback) {
         mCallback = callback;
         mFullScreen = isFullScreen(context);
-
-        final LayoutInflater inflater = LayoutInflater.from(context);
+        mContext = new ContextThemeWrapper(context, THEME_ID);
+        final LayoutInflater inflater = LayoutInflater.from(mContext);
 
         final RemoteViews headerPresentation = response.getHeader();
         final RemoteViews footerPresentation = response.getFooter();
         final ViewGroup decor;
-        if (headerPresentation != null || footerPresentation != null) {
-            decor = (ViewGroup) inflater.inflate(
-                    mFullScreen ? R.layout.autofill_dataset_picker_header_footer_fullscreen
-                            : R.layout.autofill_dataset_picker_header_footer, null);
+        if (mFullScreen) {
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_fullscreen, null);
+        } else if (headerPresentation != null || footerPresentation != null) {
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker_header_footer,
+                    null);
         } else {
-            decor = (ViewGroup) inflater.inflate(
-                    mFullScreen ? R.layout.autofill_dataset_picker_fullscreen
-                            : R.layout.autofill_dataset_picker, null);
+            decor = (ViewGroup) inflater.inflate(R.layout.autofill_dataset_picker, null);
+        }
+        final TextView titleView = decor.findViewById(R.id.autofill_dataset_title);
+        if (titleView != null) {
+            titleView.setText(mContext.getString(R.string.autofill_window_title, serviceLabel));
+        }
+        final ImageView iconView = decor.findViewById(R.id.autofill_dataset_icon);
+        if (iconView != null) {
+            iconView.setImageDrawable(serviceIcon);
         }
 
-        // if autofill ui is not fullscreen, send unhandled keyevent to app window.
-        if (!mFullScreen) {
-            if (decor instanceof AutofillFrameLayout) {
-                ((AutofillFrameLayout) decor).mUnhandledListener =
-                        (View view, int keyCode, KeyEvent event) -> {
-                            switch (keyCode) {
-                                case KeyEvent.KEYCODE_BACK:
-                                case KeyEvent.KEYCODE_ESCAPE:
-                                case KeyEvent.KEYCODE_ENTER:
-                                case KeyEvent.KEYCODE_DPAD_CENTER:
-                                case KeyEvent.KEYCODE_DPAD_LEFT:
-                                case KeyEvent.KEYCODE_DPAD_UP:
-                                case KeyEvent.KEYCODE_DPAD_RIGHT:
-                                case KeyEvent.KEYCODE_DPAD_DOWN:
-                                    return false;
-                                default:
-                                    mCallback.dispatchUnhandledKey(event);
-                                    return true;
-                            }
-                        };
-            } else {
-                Slog.wtf(TAG, "Unable to send unhandled key");
+        // In full screen we only initialize size once assuming screen size never changes
+        if (mFullScreen) {
+            final Point outPoint = mTempPoint;
+            mContext.getDisplay().getSize(outPoint);
+            // full with of screen and half height of screen
+            mContentWidth = LayoutParams.MATCH_PARENT;
+            mContentHeight = outPoint.y / 2;
+            if (sVerbose) {
+                Slog.v(TAG, "initialized fillscreen LayoutParams "
+                        + mContentWidth + "," + mContentHeight);
             }
         }
 
+        // Send unhandled keyevent to app window.
+        decor.addOnUnhandledKeyEventListener((View view, KeyEvent event) -> {
+            switch (event.getKeyCode() ) {
+                case KeyEvent.KEYCODE_BACK:
+                case KeyEvent.KEYCODE_ESCAPE:
+                case KeyEvent.KEYCODE_ENTER:
+                case KeyEvent.KEYCODE_DPAD_CENTER:
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                case KeyEvent.KEYCODE_DPAD_UP:
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    return false;
+                default:
+                    mCallback.dispatchUnhandledKey(event);
+                    return true;
+            }
+        });
+
         if (sVisibleDatasetsMaxCount > 0) {
             mVisibleDatasetsMaxCount = sVisibleDatasetsMaxCount;
             if (sVerbose) {
@@ -218,14 +215,12 @@
             mFooter = null;
             mAdapter = null;
 
-            // insert authentication item under autofill_dataset_container or decor
-            ViewGroup container = decor.findViewById(R.id.autofill_dataset_container);
-            if (container == null) {
-                container = decor;
-            }
+            // insert authentication item under autofill_dataset_picker
+            ViewGroup container = decor.findViewById(R.id.autofill_dataset_picker);
             final View content;
             try {
-                content = response.getPresentation().apply(context, decor, interceptionHandler);
+                response.getPresentation().setApplyTheme(THEME_ID);
+                content = response.getPresentation().apply(mContext, decor, interceptionHandler);
                 container.addView(content);
             } catch (RuntimeException e) {
                 callback.onCanceled();
@@ -236,20 +231,22 @@
             decor.setFocusable(true);
             decor.setOnClickListener(v -> mCallback.onResponsePicked(response));
 
-            final Point maxSize = mTempPoint;
-            resolveMaxWindowSize(context, maxSize);
-            // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
-            content.getLayoutParams().width = mFullScreen ? maxSize.x
-                    : ViewGroup.LayoutParams.WRAP_CONTENT;
-            content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
-            final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.x,
-                    MeasureSpec.AT_MOST);
-            final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
-                    MeasureSpec.AT_MOST);
+            if (!mFullScreen) {
+                final Point maxSize = mTempPoint;
+                resolveMaxWindowSize(mContext, maxSize);
+                // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
+                content.getLayoutParams().width = mFullScreen ? maxSize.x
+                        : ViewGroup.LayoutParams.WRAP_CONTENT;
+                content.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
+                final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.x,
+                        MeasureSpec.AT_MOST);
+                final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
+                        MeasureSpec.AT_MOST);
 
-            decor.measure(widthMeasureSpec, heightMeasureSpec);
-            mContentWidth = content.getMeasuredWidth();
-            mContentHeight = content.getMeasuredHeight();
+                decor.measure(widthMeasureSpec, heightMeasureSpec);
+                mContentWidth = content.getMeasuredWidth();
+                mContentHeight = content.getMeasuredHeight();
+            }
 
             mWindow = new AnchoredWindow(decor, overlayControl);
             requestShowFillUi();
@@ -263,7 +260,8 @@
             RemoteViews.OnClickHandler clickBlocker = null;
             if (headerPresentation != null) {
                 clickBlocker = newClickBlocker();
-                mHeader = headerPresentation.apply(context, null, clickBlocker);
+                headerPresentation.setApplyTheme(THEME_ID);
+                mHeader = headerPresentation.apply(mContext, null, clickBlocker);
                 final LinearLayout headerContainer =
                         decor.findViewById(R.id.autofill_dataset_header);
                 if (sVerbose) Slog.v(TAG, "adding header");
@@ -274,15 +272,21 @@
             }
 
             if (footerPresentation != null) {
-                if (clickBlocker == null) { // already set for header
-                    clickBlocker = newClickBlocker();
-                }
-                mFooter = footerPresentation.apply(context, null, clickBlocker);
                 final LinearLayout footerContainer =
                         decor.findViewById(R.id.autofill_dataset_footer);
-                if (sVerbose) Slog.v(TAG, "adding footer");
-                footerContainer.addView(mFooter);
-                footerContainer.setVisibility(View.VISIBLE);
+                if (footerContainer != null) {
+                    if (clickBlocker == null) { // already set for header
+                        clickBlocker = newClickBlocker();
+                    }
+                    footerPresentation.setApplyTheme(THEME_ID);
+                    mFooter = footerPresentation.apply(mContext, null, clickBlocker);
+                    // Footer not supported on some platform e.g. TV
+                    if (sVerbose) Slog.v(TAG, "adding footer");
+                    footerContainer.addView(mFooter);
+                    footerContainer.setVisibility(View.VISIBLE);
+                } else {
+                    mFooter = null;
+                }
             } else {
                 mFooter = null;
             }
@@ -301,7 +305,8 @@
                     final View view;
                     try {
                         if (sVerbose) Slog.v(TAG, "setting remote view for " + focusedViewId);
-                        view = presentation.apply(context, null, interceptionHandler);
+                        presentation.setApplyTheme(THEME_ID);
+                        view = presentation.apply(mContext, null, interceptionHandler);
                     } catch (RuntimeException e) {
                         Slog.e(TAG, "Error inflating remote views", e);
                         continue;
@@ -352,12 +357,7 @@
     }
 
     void requestShowFillUi() {
-        if (mFullScreen) {
-            mCallback.requestShowFillUi(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
-                    mWindowPresenter);
-        } else {
-            mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
-        }
+        mCallback.requestShowFillUi(mContentWidth, mContentHeight, mWindowPresenter);
     }
 
     /**
@@ -388,12 +388,6 @@
                 mCallback.requestHideFillUi();
             } else {
                 if (updateContentSize()) {
-                    if (mFullScreen) {
-                        LayoutParams lp = mListView.getLayoutParams();
-                        lp.width = mContentWidth;
-                        lp.height = mContentHeight;
-                        mListView.setLayoutParams(lp);
-                    }
                     requestShowFillUi();
                 }
                 if (mAdapter.getCount() > mVisibleDatasetsMaxCount) {
@@ -452,6 +446,10 @@
         if (mAdapter == null) {
             return false;
         }
+        if (mFullScreen) {
+            // always request show fill window with fixed size for fullscreen
+            return true;
+        }
         boolean changed = false;
         if (mAdapter.getCount() <= 0) {
             if (mContentWidth != 0) {
@@ -476,11 +474,6 @@
         final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxSize.y,
                 MeasureSpec.AT_MOST);
         final int itemCount = mAdapter.getCount();
-        if (mFullScreen) {
-            // fullScreen mode occupy the full width defined by autofill_dataset_picker_max_width
-            changed = true;
-            mContentWidth = maxSize.x;
-        }
 
         if (mHeader != null) {
             mHeader.measure(widthMeasureSpec, heightMeasureSpec);
@@ -491,20 +484,9 @@
         for (int i = 0; i < itemCount; i++) {
             final View view = mAdapter.getItem(i).view;
             view.measure(widthMeasureSpec, heightMeasureSpec);
-            if (mFullScreen) {
-                // for fullscreen, add up all children height until hit max height.
-                final int newContentHeight = mContentHeight + view.getMeasuredHeight();
-                final int clampedNewHeight = Math.min(newContentHeight, maxSize.y);
-                if (clampedNewHeight != mContentHeight) {
-                    mContentHeight = clampedNewHeight;
-                } else if (view.getMeasuredHeight() > 0) {
-                    break;
-                }
-            } else {
-                changed |= updateWidth(view, maxSize);
-                if (i < mVisibleDatasetsMaxCount) {
-                    changed |= updateHeight(view, maxSize);
-                }
+            changed |= updateWidth(view, maxSize);
+            if (i < mVisibleDatasetsMaxCount) {
+                changed |= updateHeight(view, maxSize);
             }
         }
 
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index f96fa7c2..80903c1 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -42,6 +42,7 @@
 import android.util.ArraySet;
 import android.util.Pair;
 import android.util.Slog;
+import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -70,6 +71,9 @@
 
     private static final String TAG = "AutofillSaveUi";
 
+    private static final int THEME_ID =
+            com.android.internal.R.style.Theme_DeviceDefault_Autofill_Save;
+
     public interface OnSaveListener {
         void onSave();
         void onCancel(IntentSender listener);
@@ -144,6 +148,7 @@
         mServicePackageName = servicePackageName;
         mPackageName = packageName;
 
+        context = new ContextThemeWrapper(context, THEME_ID);
         final LayoutInflater inflater = LayoutInflater.from(context);
         final View view = inflater.inflate(R.layout.autofill_save, null);
 
@@ -222,7 +227,7 @@
         final View yesButton = view.findViewById(R.id.autofill_save_yes);
         yesButton.setOnClickListener((v) -> mListener.onSave());
 
-        mDialog = new Dialog(context, R.style.Theme_DeviceDefault_Light_Panel);
+        mDialog = new Dialog(context, THEME_ID);
         mDialog.setContentView(view);
 
         // Dialog can be dismissed when touched outside, but the negative listener should not be
@@ -309,6 +314,7 @@
 
         try {
             // Create the remote view peer.
+            template.setApplyTheme(THEME_ID);
             final View customSubtitleView = template.apply(context, null, handler);
 
             // And apply batch updates (if any).
diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java
index b860191..d818bd6 100644
--- a/services/core/java/com/android/server/AppOpsService.java
+++ b/services/core/java/com/android/server/AppOpsService.java
@@ -39,6 +39,7 @@
 import android.os.ServiceManager;
 import android.os.ShellCallback;
 import android.os.ShellCommand;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.os.storage.StorageManagerInternal;
@@ -77,14 +78,24 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
+import static android.app.AppOpsManager.UID_STATE_CACHED;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
+import static android.app.AppOpsManager.UID_STATE_FOREGROUND_SERVICE;
+import static android.app.AppOpsManager._NUM_UID_STATE;
+import static android.app.AppOpsManager.UID_STATE_PERSISTENT;
+import static android.app.AppOpsManager.UID_STATE_TOP;
+
 public class AppOpsService extends IAppOpsService.Stub {
     static final String TAG = "AppOps";
     static final boolean DEBUG = false;
@@ -100,6 +111,64 @@
     // Constant meaning that any UID should be matched when dispatching callbacks
     private static final int UID_ANY = -2;
 
+    // Map from process states to the uid states we track.
+    private static final int[] PROCESS_STATE_TO_UID_STATE = new int[] {
+        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT
+        UID_STATE_PERSISTENT,           // ActivityManager.PROCESS_STATE_PERSISTENT_UI
+        UID_STATE_TOP,                  // ActivityManager.PROCESS_STATE_TOP
+        UID_STATE_FOREGROUND_SERVICE,   // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
+        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE
+        UID_STATE_FOREGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_BACKUP
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_SERVICE
+        UID_STATE_BACKGROUND,           // ActivityManager.PROCESS_STATE_RECEIVER
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_TOP_SLEEPING
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_HOME
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_LAST_ACTIVITY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_RECENT
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_CACHED_EMPTY
+        UID_STATE_CACHED,               // ActivityManager.PROCESS_STATE_NONEXISTENT
+    };
+
+    static final String[] UID_STATE_NAMES = new String[] {
+            "pers ",    // UID_STATE_PERSISTENT
+            "top  ",    // UID_STATE_TOP
+            "fgsvc",    // UID_STATE_FOREGROUND_SERVICE
+            "fg   ",    // UID_STATE_FOREGROUND
+            "bg   ",    // UID_STATE_BACKGROUND
+            "cch  ",    // UID_STATE_CACHED
+    };
+
+    static final String[] UID_STATE_TIME_ATTRS = new String[] {
+            "tp",       // UID_STATE_PERSISTENT
+            "tt",       // UID_STATE_TOP
+            "tfs",      // UID_STATE_FOREGROUND_SERVICE
+            "tf",       // UID_STATE_FOREGROUND
+            "tb",       // UID_STATE_BACKGROUND
+            "tc",       // UID_STATE_CACHED
+    };
+
+    static final String[] UID_STATE_REJECT_ATTRS = new String[] {
+            "rp",       // UID_STATE_PERSISTENT
+            "rt",       // UID_STATE_TOP
+            "rfs",      // UID_STATE_FOREGROUND_SERVICE
+            "rf",       // UID_STATE_FOREGROUND
+            "rb",       // UID_STATE_BACKGROUND
+            "rc",       // UID_STATE_CACHED
+    };
+
+    static final String[] MODE_NAMES = new String[] {
+            "allow",        // MODE_ALLOWED
+            "ignore",       // MODE_IGNORED
+            "deny",         // MODE_ERRORED
+            "default",      // MODE_DEFAULT
+    };
+
     Context mContext;
     final AtomicFile mFile;
     final Handler mHandler;
@@ -133,6 +202,8 @@
     @VisibleForTesting
     static final class UidState {
         public final int uid;
+        public int state = UID_STATE_CACHED;
+        public int startNesting;
         public ArrayMap<String, Ops> pkgOps;
         public SparseIntArray opModes;
 
@@ -151,36 +222,51 @@
         }
     }
 
-    public final static class Ops extends SparseArray<Op> {
-        public final String packageName;
-        public final UidState uidState;
-        public final boolean isPrivileged;
+    final static class Ops extends SparseArray<Op> {
+        final String packageName;
+        final UidState uidState;
+        final boolean isPrivileged;
 
-        public Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
+        Ops(String _packageName, UidState _uidState, boolean _isPrivileged) {
             packageName = _packageName;
             uidState = _uidState;
             isPrivileged = _isPrivileged;
         }
     }
 
-    public final static class Op {
-        public final int uid;
-        public final String packageName;
-        public int proxyUid = -1;
-        public String proxyPackageName;
-        public final int op;
-        public int mode;
-        public int duration;
-        public long time;
-        public long rejectTime;
-        public int nesting;
+    final static class Op {
+        final UidState uidState;
+        final int uid;
+        final String packageName;
+        final int op;
+        int proxyUid = -1;
+        String proxyPackageName;
+        int mode;
+        int duration;
+        long time[] = new long[_NUM_UID_STATE];
+        long rejectTime[] = new long[_NUM_UID_STATE];
+        int startNesting;
+        long startRealtime;
 
-        public Op(int _uid, String _packageName, int _op) {
-            uid = _uid;
+        Op(UidState _uidState, String _packageName, int _op) {
+            uidState = _uidState;
+            uid = _uidState.uid;
             packageName = _packageName;
             op = _op;
             mode = AppOpsManager.opToDefaultMode(op);
         }
+
+        boolean hasAnyTime() {
+            for (int i = 0; i < AppOpsManager._NUM_UID_STATE; i++) {
+                if (time[i] != 0) {
+                    return true;
+                }
+                if (rejectTime[i] != 0) {
+                    return true;
+                }
+            }
+            return false;
+        }
     }
 
     final SparseArray<ArraySet<ModeCallback>> mOpModeWatchers = new SparseArray<>();
@@ -189,13 +275,13 @@
     final ArrayMap<IBinder, SparseArray<ActiveCallback>> mActiveWatchers = new ArrayMap<>();
     final SparseArray<SparseArray<Restriction>> mAudioRestrictions = new SparseArray<>();
 
-    public final class ModeCallback implements DeathRecipient {
+    final class ModeCallback implements DeathRecipient {
         final IAppOpsCallback mCallback;
         final int mWatchingUid;
         final int mCallingUid;
         final int mCallingPid;
 
-        public ModeCallback(IAppOpsCallback callback, int watchingUid, int callingUid,
+        ModeCallback(IAppOpsCallback callback, int watchingUid, int callingUid,
                 int callingPid) {
             mCallback = callback;
             mWatchingUid = watchingUid;
@@ -222,7 +308,7 @@
             return sb.toString();
         }
 
-        public void unlinkToDeath() {
+        void unlinkToDeath() {
             mCallback.asBinder().unlinkToDeath(this, 0);
         }
 
@@ -232,13 +318,13 @@
         }
     }
 
-    public final class ActiveCallback implements DeathRecipient {
+    final class ActiveCallback implements DeathRecipient {
         final IAppOpsActiveCallback mCallback;
         final int mWatchingUid;
         final int mCallingUid;
         final int mCallingPid;
 
-        public ActiveCallback(IAppOpsActiveCallback callback, int watchingUid, int callingUid,
+        ActiveCallback(IAppOpsActiveCallback callback, int watchingUid, int callingUid,
                 int callingPid) {
             mCallback = callback;
             mWatchingUid = watchingUid;
@@ -265,7 +351,7 @@
             return sb.toString();
         }
 
-        public void destroy() {
+        void destroy() {
             mCallback.asBinder().unlinkToDeath(this, 0);
         }
 
@@ -277,12 +363,12 @@
 
     final ArrayMap<IBinder, ClientState> mClients = new ArrayMap<>();
 
-    public final class ClientState extends Binder implements DeathRecipient {
+    final class ClientState extends Binder implements DeathRecipient {
         final ArrayList<Op> mStartedOps = new ArrayList<>();
         final IBinder mAppToken;
         final int mPid;
 
-        public ClientState(IBinder appToken) {
+        ClientState(IBinder appToken) {
             mAppToken = appToken;
             mPid = Binder.getCallingPid();
             // Watch only for remote processes dying
@@ -453,7 +539,7 @@
                     if (uid == op.uid && packageName.equals(op.packageName)) {
                         finishOperationLocked(op, /*finishNested*/ true);
                         client.mStartedOps.remove(j);
-                        if (op.nesting <= 0) {
+                        if (op.startNesting <= 0) {
                             scheduleOpActiveChangedIfNeededLocked(op.op,
                                     uid, packageName, false);
                         }
@@ -485,6 +571,31 @@
         }
     }
 
+    public void updateUidProcState(int uid, int procState) {
+        synchronized (this) {
+            final UidState uidState = getUidStateLocked(uid, true);
+            final int newState = PROCESS_STATE_TO_UID_STATE[procState];
+            if (uidState != null && uidState.state != newState) {
+                if (uidState.startNesting != 0) {
+                    // There is some actively running operation...  need to find it
+                    // and appropriately update its state.
+                    final long now = System.currentTimeMillis();
+                    for (int i = uidState.pkgOps.size() - 1; i >= 0; i--) {
+                        final Ops ops = uidState.pkgOps.valueAt(i);
+                        for (int j = ops.size() - 1; j >= 0; j--) {
+                            final Op op = ops.valueAt(j);
+                            if (op.startNesting > 0) {
+                                op.time[uidState.state] = now;
+                                op.time[newState] = now;
+                            }
+                        }
+                    }
+                }
+                uidState.state = newState;
+            }
+        }
+    }
+
     public void shutdown() {
         Slog.w(TAG, "Writing app ops before shutdown...");
         boolean doWrite = false;
@@ -501,12 +612,16 @@
 
     private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) {
         ArrayList<AppOpsManager.OpEntry> resOps = null;
+        final long elapsedNow = SystemClock.elapsedRealtime();
         if (ops == null) {
-            resOps = new ArrayList<AppOpsManager.OpEntry>();
+            resOps = new ArrayList<>();
             for (int j=0; j<pkgOps.size(); j++) {
                 Op curOp = pkgOps.valueAt(j);
+                long duration = curOp.duration == -1
+                        ? (elapsedNow - curOp.startRealtime)
+                        : curOp.duration;
                 resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                        curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                        curOp.rejectTime, (int) duration, curOp.proxyUid,
                         curOp.proxyPackageName));
             }
         } else {
@@ -514,10 +629,13 @@
                 Op curOp = pkgOps.get(ops[j]);
                 if (curOp != null) {
                     if (resOps == null) {
-                        resOps = new ArrayList<AppOpsManager.OpEntry>();
+                        resOps = new ArrayList<>();
                     }
+                    long duration = curOp.duration == -1
+                            ? (elapsedNow - curOp.startRealtime)
+                            : curOp.duration;
                     resOps.add(new AppOpsManager.OpEntry(curOp.op, curOp.mode, curOp.time,
-                            curOp.rejectTime, curOp.duration, curOp.proxyUid,
+                            curOp.rejectTime, (int) duration, curOp.proxyUid,
                             curOp.proxyPackageName));
                 }
             }
@@ -628,7 +746,7 @@
     }
 
     private void pruneOp(Op op, int uid, String packageName) {
-        if (op.time == 0 && op.rejectTime == 0) {
+        if (!op.hasAnyTime()) {
             Ops ops = getOpsRawLocked(uid, packageName, false /* edit */,
                     false /* uidMismatchExpected */);
             if (ops != null) {
@@ -946,7 +1064,7 @@
                                     mOpModeWatchers.get(curOp.op));
                             callbacks = addCallbacks(callbacks, curOp.op, curOp.uid, packageName,
                                     mPackageModeWatchers.get(packageName));
-                            if (curOp.time == 0 && curOp.rejectTime == 0) {
+                            if (!curOp.hasAnyTime()) {
                                 pkgOps.removeAt(j);
                             }
                         }
@@ -1212,24 +1330,25 @@
     private int noteOperationUnchecked(int code, int uid, String packageName,
             int proxyUid, String proxyPackageName) {
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
+            final Ops ops = getOpsRawLocked(uid, packageName, true /* edit */,
                     false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Slog.d(TAG, "noteOperation: no op for code " + code + " uid " + uid
                         + " package " + packageName);
                 return AppOpsManager.MODE_ERRORED;
             }
-            Op op = getOpLocked(ops, code, true);
+            final Op op = getOpLocked(ops, code, true);
             if (isOpRestrictedLocked(uid, code, packageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
+            final UidState uidState = ops.uidState;
             if (op.duration == -1) {
                 Slog.w(TAG, "Noting op not finished: uid " + uid + " pkg " + packageName
-                        + " code " + code + " time=" + op.time + " duration=" + op.duration);
+                        + " code " + code + " time=" + op.time[uidState.state]
+                        + " duration=" + op.duration);
             }
             op.duration = 0;
             final int switchCode = AppOpsManager.opToSwitch(code);
-            UidState uidState = ops.uidState;
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
             if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
@@ -1238,7 +1357,7 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return uidMode;
                 }
             } else {
@@ -1247,14 +1366,14 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + packageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return switchOp.mode;
                 }
             }
             if (DEBUG) Slog.d(TAG, "noteOperation: allowing code " + code + " uid " + uid
                     + " package " + packageName);
-            op.time = System.currentTimeMillis();
-            op.rejectTime = 0;
+            op.time[uidState.state] = System.currentTimeMillis();
+            op.rejectTime[uidState.state] = 0;
             op.proxyUid = proxyUid;
             op.proxyPackageName = proxyPackageName;
             return AppOpsManager.MODE_ALLOWED;
@@ -1323,19 +1442,19 @@
         }
         ClientState client = (ClientState)token;
         synchronized (this) {
-            Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
+            final Ops ops = getOpsRawLocked(uid, resolvedPackageName, true /* edit */,
                     false /* uidMismatchExpected */);
             if (ops == null) {
                 if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                         + " package " + resolvedPackageName);
                 return AppOpsManager.MODE_ERRORED;
             }
-            Op op = getOpLocked(ops, code, true);
+            final Op op = getOpLocked(ops, code, true);
             if (isOpRestrictedLocked(uid, code, resolvedPackageName)) {
                 return AppOpsManager.MODE_IGNORED;
             }
             final int switchCode = AppOpsManager.opToSwitch(code);
-            UidState uidState = ops.uidState;
+            final UidState uidState = ops.uidState;
             // If there is a non-default per UID policy (we set UID op mode only if
             // non-default) it takes over, otherwise use the per package policy.
             if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) {
@@ -1345,7 +1464,7 @@
                     if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return uidMode;
                 }
             } else {
@@ -1355,19 +1474,21 @@
                     if (DEBUG) Slog.d(TAG, "startOperation: reject #" + op.mode + " for code "
                             + switchCode + " (" + code + ") uid " + uid + " package "
                             + resolvedPackageName);
-                    op.rejectTime = System.currentTimeMillis();
+                    op.rejectTime[uidState.state] = System.currentTimeMillis();
                     return switchOp.mode;
                 }
             }
             if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                     + " package " + resolvedPackageName);
-            if (op.nesting == 0) {
-                op.time = System.currentTimeMillis();
-                op.rejectTime = 0;
+            if (op.startNesting == 0) {
+                op.startRealtime = SystemClock.elapsedRealtime();
+                op.time[uidState.state] = System.currentTimeMillis();
+                op.rejectTime[uidState.state] = 0;
                 op.duration = -1;
                 scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, true);
             }
-            op.nesting++;
+            op.startNesting++;
+            uidState.startNesting++;
             if (client.mStartedOps != null) {
                 client.mStartedOps.add(op);
             }
@@ -1415,7 +1536,7 @@
                 return;
             }
             finishOperationLocked(op, /*finishNested*/ false);
-            if (op.nesting <= 0) {
+            if (op.startNesting <= 0) {
                 scheduleOpActiveChangedIfNeededLocked(code, uid, packageName, false);
             }
         }
@@ -1476,18 +1597,22 @@
     }
 
     void finishOperationLocked(Op op, boolean finishNested) {
-        if (op.nesting <= 1 || finishNested) {
-            if (op.nesting == 1 || finishNested) {
-                op.duration = (int)(System.currentTimeMillis() - op.time);
-                op.time += op.duration;
+        if (op.startNesting <= 1 || finishNested) {
+            if (op.startNesting == 1 || finishNested) {
+                op.duration = (int)(SystemClock.elapsedRealtime() - op.startRealtime);
+                op.time[op.uidState.state] = System.currentTimeMillis();
             } else {
                 Slog.w(TAG, "Finishing op nesting under-run: uid " + op.uid + " pkg "
                         + op.packageName + " code " + op.op + " time=" + op.time
-                        + " duration=" + op.duration + " nesting=" + op.nesting);
+                        + " duration=" + op.duration + " nesting=" + op.startNesting);
             }
-            op.nesting = 0;
+            if (op.startNesting >= 1) {
+                op.uidState.startNesting -= op.startNesting;
+            }
+            op.startNesting = 0;
         } else {
-            op.nesting--;
+            op.startNesting--;
+            op.uidState.startNesting--;
         }
     }
 
@@ -1617,7 +1742,7 @@
             if (!edit) {
                 return null;
             }
-            op = new Op(ops.uidState.uid, ops.packageName, code);
+            op = new Op(ops.uidState, ops.packageName, code);
             ops.put(code, op);
         }
         if (edit) {
@@ -1750,7 +1875,7 @@
                 if (ops != null) {
                     final Op op = ops.get(AppOpsManager.OP_RUN_IN_BACKGROUND);
                     if (op != null && op.mode != AppOpsManager.opToDefaultMode(op.op)) {
-                        final Op copy = new Op(op.uid, op.packageName,
+                        final Op copy = new Op(op.uidState, op.packageName,
                                 AppOpsManager.OP_RUN_ANY_IN_BACKGROUND);
                         copy.mode = op.mode;
                         ops.put(AppOpsManager.OP_RUN_ANY_IN_BACKGROUND, copy);
@@ -1860,37 +1985,86 @@
 
             String tagName = parser.getName();
             if (tagName.equals("op")) {
-                Op op = new Op(uid, pkgName, Integer.parseInt(parser.getAttributeValue(null, "n")));
-                String mode = parser.getAttributeValue(null, "m");
-                if (mode != null) {
-                    op.mode = Integer.parseInt(mode);
-                }
-                String time = parser.getAttributeValue(null, "t");
-                if (time != null) {
-                    op.time = Long.parseLong(time);
-                }
-                time = parser.getAttributeValue(null, "r");
-                if (time != null) {
-                    op.rejectTime = Long.parseLong(time);
-                }
-                String dur = parser.getAttributeValue(null, "d");
-                if (dur != null) {
-                    op.duration = Integer.parseInt(dur);
-                }
-                String proxyUid = parser.getAttributeValue(null, "pu");
-                if (proxyUid != null) {
-                    op.proxyUid = Integer.parseInt(proxyUid);
-                }
-                String proxyPackageName = parser.getAttributeValue(null, "pp");
-                if (proxyPackageName != null) {
-                    op.proxyPackageName = proxyPackageName;
-                }
-
                 UidState uidState = getUidStateLocked(uid, true);
                 if (uidState.pkgOps == null) {
                     uidState.pkgOps = new ArrayMap<>();
                 }
 
+                Op op = new Op(uidState, pkgName,
+                        Integer.parseInt(parser.getAttributeValue(null, "n")));
+
+                for (int i = parser.getAttributeCount()-1; i >= 0; i--) {
+                    final String name = parser.getAttributeName(i);
+                    final String value = parser.getAttributeValue(i);
+                    switch (name) {
+                        case "m":
+                            op.mode = Integer.parseInt(value);
+                            break;
+                        case "d":
+                            op.duration = Integer.parseInt(value);
+                            break;
+                        case "pu":
+                            op.proxyUid = Integer.parseInt(value);
+                            break;
+                        case "pp":
+                            op.proxyPackageName = value;
+                            break;
+                        case "tp":
+                            op.time[AppOpsManager.UID_STATE_PERSISTENT] = Long.parseLong(value);
+                            break;
+                        case "tt":
+                            op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "tfs":
+                            op.time[AppOpsManager.UID_STATE_FOREGROUND_SERVICE]
+                                    = Long.parseLong(value);
+                            break;
+                        case "tf":
+                            op.time[AppOpsManager.UID_STATE_FOREGROUND] = Long.parseLong(value);
+                            break;
+                        case "tb":
+                            op.time[AppOpsManager.UID_STATE_BACKGROUND] = Long.parseLong(value);
+                            break;
+                        case "tc":
+                            op.time[AppOpsManager.UID_STATE_CACHED] = Long.parseLong(value);
+                            break;
+                        case "rp":
+                            op.rejectTime[AppOpsManager.UID_STATE_PERSISTENT]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rt":
+                            op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "rfs":
+                            op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND_SERVICE]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rf":
+                            op.rejectTime[AppOpsManager.UID_STATE_FOREGROUND]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rb":
+                            op.rejectTime[AppOpsManager.UID_STATE_BACKGROUND]
+                                    = Long.parseLong(value);
+                            break;
+                        case "rc":
+                            op.rejectTime[AppOpsManager.UID_STATE_CACHED]
+                                    = Long.parseLong(value);
+                            break;
+                        case "t":
+                            // Backwards compat.
+                            op.time[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        case "r":
+                            // Backwards compat.
+                            op.rejectTime[AppOpsManager.UID_STATE_TOP] = Long.parseLong(value);
+                            break;
+                        default:
+                            Slog.w(TAG, "Unknown attribute in 'op' tag: " + name);
+                            break;
+                    }
+                }
+
                 Ops ops = uidState.pkgOps.get(pkgName);
                 if (ops == null) {
                     ops = new Ops(pkgName, uidState, isPrivileged);
@@ -1977,13 +2151,17 @@
                             if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) {
                                 out.attribute(null, "m", Integer.toString(op.getMode()));
                             }
-                            long time = op.getTime();
-                            if (time != 0) {
-                                out.attribute(null, "t", Long.toString(time));
-                            }
-                            time = op.getRejectTime();
-                            if (time != 0) {
-                                out.attribute(null, "r", Long.toString(time));
+                            for (int k = 0; k < _NUM_UID_STATE; k++) {
+                                final long time = op.getTimeFor(k);
+                                if (time != 0) {
+                                    out.attribute(null, UID_STATE_TIME_ATTRS[k],
+                                            Long.toString(time));
+                                }
+                                final long rejectTime = op.getRejectTimeFor(k);
+                                if (rejectTime != 0) {
+                                    out.attribute(null, UID_STATE_REJECT_ATTRS[k],
+                                            Long.toString(rejectTime));
+                                }
                             }
                             int dur = op.getDuration();
                             if (dur != 0) {
@@ -2069,15 +2247,10 @@
         }
 
         int strModeToMode(String modeStr, PrintWriter err) {
-            switch (modeStr) {
-                case "allow":
-                    return AppOpsManager.MODE_ALLOWED;
-                case "deny":
-                    return AppOpsManager.MODE_ERRORED;
-                case "ignore":
-                    return AppOpsManager.MODE_IGNORED;
-                case "default":
-                    return AppOpsManager.MODE_DEFAULT;
+            for (int i = MODE_NAMES.length - 1; i >= 0; i--) {
+                if (MODE_NAMES[i].equals(modeStr)) {
+                    return i;
+                }
             }
             try {
                 return Integer.parseInt(modeStr);
@@ -2466,6 +2639,34 @@
         pw.println("  none");
     }
 
+    private void dumpTimesLocked(PrintWriter pw, String firstPrefix, String prefix, long[] times,
+            long now, SimpleDateFormat sdf, Date date) {
+        boolean hasTime = false;
+        for (int i = 0; i < _NUM_UID_STATE; i++) {
+            if (times[i] != 0) {
+                hasTime = true;
+                break;
+            }
+        }
+        if (!hasTime) {
+            return;
+        }
+        boolean first = true;
+        for (int i = 0; i < _NUM_UID_STATE; i++) {
+            if (times[i] != 0) {
+                pw.print(first ? firstPrefix : prefix);
+                first = false;
+                pw.print(UID_STATE_NAMES[i]);
+                pw.print(" = ");
+                date.setTime(times[i]);
+                pw.print(sdf.format(date));
+                pw.print(" (");
+                TimeUtils.formatDuration(times[i]-now, pw);
+                pw.println(")");
+            }
+        }
+    }
+
     @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
@@ -2491,6 +2692,9 @@
         synchronized (this) {
             pw.println("Current AppOps Service state:");
             final long now = System.currentTimeMillis();
+            final long nowElapsed = SystemClock.elapsedRealtime();
+            final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+            final Date date = new Date();
             boolean needSep = false;
             if (mOpModeWatchers.size() > 0) {
                 needSep = true;
@@ -2585,7 +2789,7 @@
                         pw.print("    "); pw.print(op);
                         pw.print(" usage="); pw.print(AudioAttributes.usageToString(usage));
                         Restriction r = restrictions.valueAt(i);
-                        pw.print(": mode="); pw.println(r.mode);
+                        pw.print(": mode="); pw.println(MODE_NAMES[r.mode]);
                         if (!r.exceptionPackages.isEmpty()) {
                             pw.println("      Exceptions:");
                             for (int j=0; j<r.exceptionPackages.size(); j++) {
@@ -2602,6 +2806,12 @@
                 UidState uidState = mUidStates.valueAt(i);
 
                 pw.print("  Uid "); UserHandle.formatUid(pw, uidState.uid); pw.println(":");
+                pw.print("    state=");
+                pw.println(UID_STATE_NAMES[uidState.state]);
+                if (uidState.startNesting != 0) {
+                    pw.print("    startNesting=");
+                    pw.println(uidState.startNesting);
+                }
                 needSep = true;
 
                 SparseIntArray opModes = uidState.opModes;
@@ -2611,7 +2821,7 @@
                         final int code = opModes.keyAt(j);
                         final int mode = opModes.valueAt(j);
                         pw.print("      "); pw.print(AppOpsManager.opToName(code));
-                        pw.print(": mode="); pw.println(mode);
+                        pw.print(": mode="); pw.println(MODE_NAMES[mode]);
                     }
                 }
 
@@ -2625,21 +2835,26 @@
                     for (int j=0; j<ops.size(); j++) {
                         Op op = ops.valueAt(j);
                         pw.print("      "); pw.print(AppOpsManager.opToName(op.op));
-                        pw.print(": mode="); pw.print(op.mode);
-                        if (op.time != 0) {
-                            pw.print("; time="); TimeUtils.formatDuration(now-op.time, pw);
-                            pw.print(" ago");
-                        }
-                        if (op.rejectTime != 0) {
-                            pw.print("; rejectTime="); TimeUtils.formatDuration(now-op.rejectTime, pw);
-                            pw.print(" ago");
-                        }
+                        pw.print(" ("); pw.print(MODE_NAMES[op.mode]); pw.println("): ");
+                        dumpTimesLocked(pw,
+                                "          Access: ",
+                                "                  ", op.time, now, sdf, date);
+                        dumpTimesLocked(pw,
+                                "          Reject: ",
+                                "                  ", op.rejectTime, now, sdf, date);
                         if (op.duration == -1) {
-                            pw.print(" (running)");
+                            pw.print("          Running start at: ");
+                            TimeUtils.formatDuration(nowElapsed-op.startRealtime, pw);
+                            pw.println();
                         } else if (op.duration != 0) {
-                            pw.print("; duration="); TimeUtils.formatDuration(op.duration, pw);
+                            pw.print("          duration=");
+                            TimeUtils.formatDuration(op.duration, pw);
+                            pw.println();
                         }
-                        pw.println();
+                        if (op.startNesting != 0) {
+                            pw.print("          startNesting=");
+                            pw.println(op.startNesting);
+                        }
                     }
                 }
             }
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index ae14dfa..1cd853f 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -56,7 +56,10 @@
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (args != null) {
             for (final String arg : args) {
-                if ("--reset".equals(arg)) {
+                if ("-a".equals(arg)) {
+                    // We currently dump all information by default
+                    continue;
+                } else if ("--reset".equals(arg)) {
                     reset();
                     pw.println("binder_calls_stats reset.");
                     return;
@@ -78,7 +81,6 @@
                     return;
                 } else {
                     pw.println("Unknown option: " + arg);
-                    return;
                 }
             }
         }
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 83d2bf7..ede870f 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -704,9 +704,11 @@
         VibrationEffect scaledEffect = null;
         if (vib.effect instanceof VibrationEffect.OneShot) {
             VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
+            oneShot = oneShot.resolve(mDefaultVibrationAmplitude);
             scaledEffect = oneShot.scale(gamma, maxAmplitude);
         } else if (vib.effect instanceof VibrationEffect.Waveform) {
             VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
+            waveform = waveform.resolve(mDefaultVibrationAmplitude);
             scaledEffect = waveform.scale(gamma, maxAmplitude);
         } else {
             Slog.w(TAG, "Unable to apply intensity scaling, unknown VibrationEffect type");
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ae26c23..7170119 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -22929,6 +22929,7 @@
 
     private void noteUidProcessState(final int uid, final int state) {
         mBatteryStatsService.noteUidProcessState(uid, state);
+        mAppOpsService.updateUidProcState(uid, state);
         if (mTrackingAssociations) {
             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index 550c37a..483fec6 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -219,6 +219,9 @@
     }
 
     public void unregisterCancelListenerLocked(IResultReceiver receiver) {
+        if (mCancelCallbacks == null) {
+            return; // Already unregistered or detached.
+        }
         mCancelCallbacks.unregister(receiver);
         if (mCancelCallbacks.getRegisteredCallbackCount() <= 0) {
             mCancelCallbacks = null;
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index f74ac47..5db20b0 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -621,7 +621,7 @@
 
     private boolean clipboardAccessAllowed(int op, String callingPackage, int callingUid) {
         // Check the AppOp.
-        if (mAppOps.checkOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
+        if (mAppOps.noteOp(op, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
             return false;
         }
         try {
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 312b21c..03046b6 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -818,37 +818,7 @@
             }
         };
 
-        mGnssMeasurementsProvider = new GnssMeasurementsProvider(mHandler) {
-            @Override
-            public boolean isAvailableInPlatform() {
-                return native_is_measurement_supported();
-            }
-
-            @Override
-            protected int registerWithService() {
-                int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
-                        Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
-                int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
-                        Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING , 0);
-                boolean result = false;
-                if (devOptions == 1 /* Developer Mode enabled */
-                        && fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */) {
-                    result =  native_start_measurement_collection(true /* enableFullTracking */);
-                } else {
-                    result =  native_start_measurement_collection(false /* enableFullTracking */);
-                }
-                if (result) {
-                    return RemoteListenerHelper.RESULT_SUCCESS;
-                } else {
-                    return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
-                }
-            }
-
-            @Override
-            protected void unregisterFromService() {
-                native_stop_measurement_collection();
-            }
-
+        mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
             @Override
             protected boolean isGpsEnabled() {
                 return isEnabled();
@@ -1032,7 +1002,7 @@
                 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
         }
     }
-    
+
     private void handleRequestLocation(boolean independentFromGnss) {
         if (isRequestLocationRateLimited()) {
             if (DEBUG) {
@@ -2790,13 +2760,6 @@
     private native void native_update_network_state(boolean connected, int type,
             boolean roaming, boolean available, String extraInfo, String defaultAPN);
 
-    // Gps Hal measurements support.
-    private static native boolean native_is_measurement_supported();
-
-    private native boolean native_start_measurement_collection(boolean enableFullTracking);
-
-    private native boolean native_stop_measurement_collection();
-
     // Gps Navigation message support.
     private static native boolean native_is_navigation_message_supported();
 
diff --git a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
index 477dae6..0add863 100644
--- a/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
+++ b/services/core/java/com/android/server/location/GnssMeasurementsProvider.java
@@ -16,12 +16,16 @@
 
 package com.android.server.location;
 
+import android.content.Context;
 import android.location.GnssMeasurementsEvent;
 import android.location.IGnssMeasurementsListener;
 import android.os.Handler;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.util.Log;
 
+import com.android.internal.annotations.VisibleForTesting;
+
 /**
  * An base implementation for GPS measurements provider.
  * It abstracts out the responsibility of handling listeners, while still allowing technology
@@ -29,22 +33,73 @@
  *
  * @hide
  */
-public abstract class GnssMeasurementsProvider
-        extends RemoteListenerHelper<IGnssMeasurementsListener> {
+public abstract class GnssMeasurementsProvider extends
+        RemoteListenerHelper<IGnssMeasurementsListener> {
     private static final String TAG = "GnssMeasurementsProvider";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
-    protected GnssMeasurementsProvider(Handler handler) {
+    private final Context mContext;
+    private final GnssMeasurementProviderNative mNative;
+
+    private boolean mIsCollectionStarted;
+    private boolean mEnableFullTracking;
+
+    protected GnssMeasurementsProvider(Context context, Handler handler) {
+        this(context, handler, new GnssMeasurementProviderNative());
+    }
+
+    @VisibleForTesting
+    GnssMeasurementsProvider(Context context, Handler handler,
+            GnssMeasurementProviderNative aNative) {
         super(handler, TAG);
+        mContext = context;
+        mNative = aNative;
+    }
+
+    // TODO(b/37460011): Use this with death recovery logic.
+    void resumeIfStarted() {
+        if (DEBUG) {
+            Log.d(TAG, "resumeIfStarted");
+        }
+        if (mIsCollectionStarted) {
+            mNative.startMeasurementCollection(mEnableFullTracking);
+        }
+    }
+
+    @Override
+    public boolean isAvailableInPlatform() {
+        return mNative.isMeasurementSupported();
+    }
+
+    @Override
+    protected int registerWithService() {
+        int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
+                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
+        int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
+                Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING, 0);
+        boolean enableFullTracking = (devOptions == 1 /* Developer Mode enabled */)
+                && (fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */);
+        boolean result = mNative.startMeasurementCollection(enableFullTracking);
+        if (result) {
+            mIsCollectionStarted = true;
+            mEnableFullTracking = enableFullTracking;
+            return RemoteListenerHelper.RESULT_SUCCESS;
+        } else {
+            return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
+        }
+    }
+
+    @Override
+    protected void unregisterFromService() {
+        boolean stopped = mNative.stopMeasurementCollection();
+        if (stopped) {
+            mIsCollectionStarted = false;
+        }
     }
 
     public void onMeasurementsAvailable(final GnssMeasurementsEvent event) {
         ListenerOperation<IGnssMeasurementsListener> operation =
-                new ListenerOperation<IGnssMeasurementsListener>() {
-                    @Override
-                    public void execute(IGnssMeasurementsListener listener) throws RemoteException {
-                        listener.onGnssMeasurementsReceived(event);
-                    }
-                };
+                listener -> listener.onGnssMeasurementsReceived(event);
         foreach(operation);
     }
 
@@ -98,4 +153,25 @@
             listener.onStatusChanged(mStatus);
         }
     }
+
+    @VisibleForTesting
+    static class GnssMeasurementProviderNative {
+        public boolean isMeasurementSupported() {
+            return native_is_measurement_supported();
+        }
+
+        public boolean startMeasurementCollection(boolean enableFullTracking) {
+            return native_start_measurement_collection(enableFullTracking);
+        }
+
+        public boolean stopMeasurementCollection() {
+            return native_stop_measurement_collection();
+        }
+    }
+
+    private static native boolean native_is_measurement_supported();
+
+    private static native boolean native_start_measurement_collection(boolean enableFullTracking);
+
+    private static native boolean native_stop_measurement_collection();
 }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 50eaa5c..bb1f5c0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4223,6 +4223,11 @@
                     || appId == Process.ROOT_UID) {
                 return false;
             }
+            // Installer gets to see all static libs.
+            if (PackageManager.PERMISSION_GRANTED
+                    == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
+                return false;
+            }
         }
 
         // No package means no static lib as it is always on internal storage
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a9cdafd..507f0a8 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -155,11 +155,10 @@
         enforceAccess(pkg, uri);
         int user = Binder.getCallingUserHandle().getIdentifier();
         uri = maybeAddUserId(uri, user);
-        getOrCreatePinnedSlice(uri, pkg).pin(pkg, specs, token);
+        String slicePkg = getProviderPkg(uri, user);
+        getOrCreatePinnedSlice(uri, slicePkg).pin(pkg, specs, token);
 
-        Uri finalUri = uri;
         mHandler.post(() -> {
-            String slicePkg = getProviderPkg(finalUri, user);
             if (slicePkg != null && !Objects.equals(pkg, slicePkg)) {
                 mAppUsageStats.reportEvent(slicePkg, user,
                         isAssistant(pkg, user) || isDefaultHomeApp(pkg, user)
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index eab391e..19c5a3d 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -922,6 +922,10 @@
      * @return Whether this WindowContainer should be magnified by the accessibility magnifier.
      */
     boolean shouldMagnify() {
+        if (mSurfaceControl == null) {
+            return false;
+        }
+
         for (int i = 0; i < mChildren.size(); i++) {
             if (!mChildren.get(i).shouldMagnify()) {
                 return false;
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 3a9bbe4..b3b37d6 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -1799,7 +1799,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_is_measurement_supported(
+static jboolean android_location_GnssMeasurementsProvider_is_measurement_supported(
     JNIEnv* env, jclass clazz) {
     if (gnssMeasurementIface != nullptr) {
         return JNI_TRUE;
@@ -1808,7 +1808,7 @@
     return JNI_FALSE;
 }
 
-static jboolean android_location_GnssLocationProvider_start_measurement_collection(
+static jboolean android_location_GnssMeasurementsProvider_start_measurement_collection(
         JNIEnv* /* env */,
         jobject /* obj */,
         jboolean enableFullTracking) {
@@ -1842,7 +1842,7 @@
     return JNI_TRUE;
 }
 
-static jboolean android_location_GnssLocationProvider_stop_measurement_collection(
+static jboolean android_location_GnssMeasurementsProvider_stop_measurement_collection(
         JNIEnv* env,
         jobject obj) {
     if (gnssMeasurementIface == nullptr) {
@@ -2178,18 +2178,6 @@
     {"native_update_network_state",
             "(ZIZZLjava/lang/String;Ljava/lang/String;)V",
             reinterpret_cast<void *>(android_location_GnssLocationProvider_update_network_state)},
-    {"native_is_measurement_supported",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_is_measurement_supported)},
-    {"native_start_measurement_collection",
-             "(Z)Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_start_measurement_collection)},
-    {"native_stop_measurement_collection",
-            "()Z",
-            reinterpret_cast<void *>(
-                    android_location_GnssLocationProvider_stop_measurement_collection)},
     {"native_is_navigation_message_supported",
             "()Z",
             reinterpret_cast<void *>(
@@ -2269,6 +2257,22 @@
             reinterpret_cast<void *>(android_location_GnssGeofenceProvider_resume_geofence)},
 };
 
+static const JNINativeMethod sMeasurementMethods[] = {
+     /* name, signature, funcPtr */
+    {"native_is_measurement_supported",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_is_measurement_supported)},
+    {"native_start_measurement_collection",
+             "(Z)Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_start_measurement_collection)},
+    {"native_stop_measurement_collection",
+            "()Z",
+            reinterpret_cast<void *>(
+                    android_location_GnssMeasurementsProvider_stop_measurement_collection)},
+};
+
 int register_android_server_location_GnssLocationProvider(JNIEnv* env) {
     jniRegisterNativeMethods(
             env,
@@ -2280,6 +2284,11 @@
             "com/android/server/location/GnssGeofenceProvider",
             sGeofenceMethods,
             NELEM(sGeofenceMethods));
+    jniRegisterNativeMethods(
+            env,
+            "com/android/server/location/GnssMeasurementsProvider",
+            sMeasurementMethods,
+            NELEM(sMeasurementMethods));
     return jniRegisterNativeMethods(
             env,
             "com/android/server/location/GnssLocationProvider",
diff --git a/services/net/java/android/net/dns/ResolvUtil.java b/services/net/java/android/net/dns/ResolvUtil.java
index 97d20f4..a2a6615 100644
--- a/services/net/java/android/net/dns/ResolvUtil.java
+++ b/services/net/java/android/net/dns/ResolvUtil.java
@@ -62,4 +62,13 @@
         final long netidForResolv = NETID_USE_LOCAL_NAMESERVERS | (long) network.netId;
         return new Network((int) netidForResolv);
     }
+
+    public static Network makeNetworkWithPrivateDnsBypass(Network network) {
+        return new Network(network) {
+            @Override
+            public InetAddress[] getAllByName(String host) throws UnknownHostException {
+                return blockingResolveAllLocally(network, host);
+            }
+        };
+    }
 }
diff --git a/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java
new file mode 100644
index 0000000..23d6cf6
--- /dev/null
+++ b/services/robotests/src/com/android/server/location/GnssMeasurementsProviderTest.java
@@ -0,0 +1,90 @@
+package com.android.server.location;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+/**
+ * Unit tests for {@link GnssMeasurementsProvider}.
+ */
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(
+        manifest = Config.NONE,
+        sdk = 27
+)
+@SystemLoaderPackages({"com.android.server.location"})
+@Presubmit
+public class GnssMeasurementsProviderTest {
+    @Mock
+    private GnssMeasurementsProvider.GnssMeasurementProviderNative mMockNative;
+    private GnssMeasurementsProvider mTestProvider;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        when(mMockNative.startMeasurementCollection(anyBoolean())).thenReturn(true);
+        when(mMockNative.stopMeasurementCollection()).thenReturn(true);
+
+        mTestProvider = new GnssMeasurementsProvider(RuntimeEnvironment.application,
+                new Handler(Looper.myLooper()), mMockNative) {
+            @Override
+            public boolean isGpsEnabled() {
+                return true;
+            }
+        };
+    }
+
+    @Test
+    public void register_nativeStarted() {
+        mTestProvider.registerWithService();
+        verify(mMockNative).startMeasurementCollection(anyBoolean());
+    }
+
+    @Test
+    public void unregister_nativeStopped() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        verify(mMockNative).stopMeasurementCollection();
+    }
+
+    @Test
+    public void isSupported_nativeIsSupported() {
+        when(mMockNative.isMeasurementSupported()).thenReturn(true);
+        assertThat(mTestProvider.isAvailableInPlatform()).isTrue();
+
+        when(mMockNative.isMeasurementSupported()).thenReturn(false);
+        assertThat(mTestProvider.isAvailableInPlatform()).isFalse();
+    }
+
+    @Test
+    public void register_resume_started() {
+        mTestProvider.registerWithService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(2)).startMeasurementCollection(anyBoolean());
+    }
+
+    @Test
+    public void unregister_resume_notStarted() {
+        mTestProvider.registerWithService();
+        mTestProvider.unregisterFromService();
+        mTestProvider.resumeIfStarted();
+        verify(mMockNative, times(1)).startMeasurementCollection(anyBoolean());
+    }
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index d49ba3e..43a4e27 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -93,7 +93,7 @@
 
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
         mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
-        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI), eq("pkg"));
+        verify(mService, times(1)).createPinnedSlice(eq(TEST_URI), anyString());
     }
 
     @Test
@@ -126,4 +126,4 @@
         verify(mContextSpy).checkPermission(eq("perm2"), eq(Process.myPid()), eq(Process.myUid()));
     }
 
-}
\ No newline at end of file
+}
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/services/usage/java/com/android/server/usage/AppStandbyController.java
index 920a605..97c5ac9 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/services/usage/java/com/android/server/usage/AppStandbyController.java
@@ -81,7 +81,7 @@
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.UserHandle;
-import android.provider.Settings;
+import android.provider.Settings.Global;
 import android.telephony.TelephonyManager;
 import android.util.ArraySet;
 import android.util.KeyValueListParser;
@@ -1439,8 +1439,10 @@
         boolean isAppIdleEnabled() {
             final boolean buildFlag = mContext.getResources().getBoolean(
                     com.android.internal.R.bool.config_enableAutoPowerModes);
-            final boolean runtimeFlag = Settings.Global.getInt(mContext.getContentResolver(),
-                    Settings.Global.APP_STANDBY_ENABLED, 1) == 1;
+            final boolean runtimeFlag = Global.getInt(mContext.getContentResolver(),
+                    Global.APP_STANDBY_ENABLED, 1) == 1
+                    && Global.getInt(mContext.getContentResolver(),
+                    Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, 1) == 1;
             return buildFlag && runtimeFlag;
         }
 
@@ -1489,8 +1491,8 @@
         }
 
         String getAppIdleSettings() {
-            return Settings.Global.getString(mContext.getContentResolver(),
-                    Settings.Global.APP_IDLE_CONSTANTS);
+            return Global.getString(mContext.getContentResolver(),
+                    Global.APP_IDLE_CONSTANTS);
         }
     }
 
@@ -1610,7 +1612,7 @@
     };
 
     /**
-     * Observe settings changes for {@link Settings.Global#APP_IDLE_CONSTANTS}.
+     * Observe settings changes for {@link Global#APP_IDLE_CONSTANTS}.
      */
     private class SettingsObserver extends ContentObserver {
         /**
@@ -1650,10 +1652,11 @@
         }
 
         void registerObserver() {
-            mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.APP_IDLE_CONSTANTS), false, this);
-            mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor(
-                    Settings.Global.APP_STANDBY_ENABLED), false, this);
+            final ContentResolver cr = mContext.getContentResolver();
+            cr.registerContentObserver(Global.getUriFor(Global.APP_IDLE_CONSTANTS), false, this);
+            cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
+            cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
+                    false, this);
         }
 
         @Override
@@ -1665,11 +1668,14 @@
         void updateSettings() {
             if (DEBUG) {
                 Slog.d(TAG,
-                        "appidle=" + Settings.Global.getString(mContext.getContentResolver(),
-                                Settings.Global.APP_STANDBY_ENABLED));
-                Slog.d(TAG, "appidleconstants=" + Settings.Global.getString(
+                        "appidle=" + Global.getString(mContext.getContentResolver(),
+                                Global.APP_STANDBY_ENABLED));
+                Slog.d(TAG,
+                        "adaptivebat=" + Global.getString(mContext.getContentResolver(),
+                                Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED));
+                Slog.d(TAG, "appidleconstants=" + Global.getString(
                         mContext.getContentResolver(),
-                        Settings.Global.APP_IDLE_CONSTANTS));
+                        Global.APP_IDLE_CONSTANTS));
             }
             // Check if app_idle_enabled has changed
             setAppIdleEnabled(mInjector.isAppIdleEnabled());