Merge "Update mobile data QS tile subtext." into pi-dev
diff --git a/api/current.txt b/api/current.txt
index 2572cd3..423e0ae 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27627,6 +27627,7 @@
   public class X509TrustManagerExtensions {
     ctor public X509TrustManagerExtensions(javax.net.ssl.X509TrustManager) throws java.lang.IllegalArgumentException;
     method public java.util.List<java.security.cert.X509Certificate> checkServerTrusted(java.security.cert.X509Certificate[], java.lang.String, java.lang.String) throws java.security.cert.CertificateException;
+    method public boolean isSameTrustConfiguration(java.lang.String, java.lang.String);
     method public boolean isUserAddedCertificate(java.security.cert.X509Certificate);
   }
 
@@ -42405,7 +42406,7 @@
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+    method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
     method public int describeContents();
     method public int getDataLimitBehavior();
     method public long getDataLimitBytes();
@@ -42427,9 +42428,7 @@
   public static class SubscriptionPlan.Builder {
     method public android.telephony.SubscriptionPlan build();
     method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+    method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
     method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/api/system-current.txt b/api/system-current.txt
index 76a71cd..6186a55 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1255,6 +1255,7 @@
     method public android.hardware.display.BrightnessConfiguration getBrightnessConfiguration();
     method public java.util.List<android.hardware.display.BrightnessChangeEvent> getBrightnessEvents();
     method public android.hardware.display.BrightnessConfiguration getDefaultBrightnessConfiguration();
+    method public android.util.Pair<float[], float[]> getMinimumBrightnessCurve();
     method public android.graphics.Point getStableDisplaySize();
     method public void setBrightnessConfiguration(android.hardware.display.BrightnessConfiguration);
     method public void setSaturationLevel(float);
@@ -5191,7 +5192,7 @@
   }
 
   public final class SubscriptionPlan implements android.os.Parcelable {
-    method public java.util.Iterator<android.util.Pair<java.time.ZonedDateTime, java.time.ZonedDateTime>> cycleIterator();
+    method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator();
     method public int describeContents();
     method public int getDataLimitBehavior();
     method public long getDataLimitBytes();
@@ -5213,9 +5214,10 @@
   public static class SubscriptionPlan.Builder {
     method public android.telephony.SubscriptionPlan build();
     method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
-    method public static android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
+    method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime);
+    method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime);
     method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
     method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
     method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence);
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index a40ea08..73d1102 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -153,6 +153,8 @@
 Landroid/app/AlarmManager;->WINDOW_EXACT:J
 Landroid/app/AlarmManager;->WINDOW_HEURISTIC:J
 Landroid/app/AlertDialog$Builder;->P:Lcom/android/internal/app/AlertController$AlertParams;
+Landroid/app/AlertDialog$Builder;->setRecycleOnMeasureEnabled(Z)Landroid/app/AlertDialog$Builder;
+Landroid/app/AlertDialog$Builder;->setView(Landroid/view/View;IIII)Landroid/app/AlertDialog$Builder;
 Landroid/app/AlertDialog;->mAlert:Lcom/android/internal/app/AlertController;
 Landroid/app/AppGlobals;->getInitialApplication()Landroid/app/Application;
 Landroid/app/AppGlobals;->getInitialPackage()Ljava/lang/String;
@@ -207,6 +209,7 @@
 Landroid/app/backup/BackupDataOutput;->mBackupWriter:J
 Landroid/app/backup/BackupHelperDispatcher$Header;->chunkSize:I
 Landroid/app/backup/BackupHelperDispatcher$Header;->keyPrefix:Ljava/lang/String;
+Landroid/app/backup/FileBackupHelperBase;->writeNewStateDescription(Landroid/os/ParcelFileDescriptor;)V
 Landroid/app/backup/FullBackup;->backupToTar(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/backup/FullBackupDataOutput;)I
 Landroid/app/backup/FullBackupDataOutput;->addSize(J)V
 Landroid/app/backup/FullBackupDataOutput;-><init>(Landroid/os/ParcelFileDescriptor;)V
@@ -260,6 +263,7 @@
 Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
 Landroid/app/IActivityManager;->requestBugReport(I)V
 Landroid/app/IActivityManager;->resumeAppSwitches()V
+Landroid/app/IActivityManager;->setActivityController(Landroid/app/IActivityController;Z)V
 Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
 Landroid/app/IActivityManager;->setTaskResizeable(II)V
 Landroid/app/IActivityManager;->stopService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;I)I
@@ -329,6 +333,7 @@
 Landroid/app/Notification$Builder;->mActions:Ljava/util/ArrayList;
 Landroid/app/Notification$Builder;->makePublicContentView()Landroid/widget/RemoteViews;
 Landroid/app/Notification$Builder;->setChannel(Ljava/lang/String;)Landroid/app/Notification$Builder;
+Landroid/app/Notification;-><init>(Landroid/content/Context;ILjava/lang/CharSequence;JLjava/lang/CharSequence;Ljava/lang/CharSequence;Landroid/content/Intent;)V
 Landroid/app/Notification;->isGroupSummary()Z
 Landroid/app/NotificationManager;->getService()Landroid/app/INotificationManager;
 Landroid/app/NotificationManager;->notifyAsUser(Ljava/lang/String;ILandroid/app/Notification;Landroid/os/UserHandle;)V
@@ -374,6 +379,7 @@
 Landroid/app/trust/ITrustManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/app/usage/UsageStatsManager;->mService:Landroid/app/usage/IUsageStatsManager;
 Landroid/app/usage/UsageStats;->mLastEvent:I
+Landroid/app/usage/UsageStats;->mLaunchCount:I
 Landroid/app/usage/UsageStats;->mTotalTimeInForeground:J
 Landroid/app/Vr2dDisplayProperties$Builder;->build()Landroid/app/Vr2dDisplayProperties;
 Landroid/app/Vr2dDisplayProperties$Builder;-><init>()V
@@ -414,6 +420,10 @@
 Landroid/bluetooth/BluetoothGatt;->mAuthRetryState:I
 Landroid/bluetooth/BluetoothGatt;->refresh()Z
 Landroid/bluetooth/BluetoothHeadset;->close()V
+Landroid/bluetooth/BluetoothHeadset;->connectAudio()Z
+Landroid/bluetooth/BluetoothHeadset;->disconnectAudio()Z
+Landroid/bluetooth/BluetoothHeadset;->startScoUsingVirtualVoiceCall(Landroid/bluetooth/BluetoothDevice;)Z
+Landroid/bluetooth/BluetoothHeadset;->stopScoUsingVirtualVoiceCall(Landroid/bluetooth/BluetoothDevice;)Z
 Landroid/bluetooth/BluetoothMapClient;->sendMessage(Landroid/bluetooth/BluetoothDevice;[Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)Z
 Landroid/bluetooth/BluetoothPan;->isTetheringOn()Z
 Landroid/bluetooth/BluetoothPan;->setBluetoothTethering(Z)V
@@ -450,6 +460,7 @@
 Landroid/content/ContentResolver;->mPackageName:Ljava/lang/String;
 Landroid/content/ContentResolver;->releaseProvider(Landroid/content/IContentProvider;)Z
 Landroid/content/ContentResolver;->releaseUnstableProvider(Landroid/content/IContentProvider;)Z
+Landroid/content/ContentResolver;->takePersistableUriPermission(Ljava/lang/String;Landroid/net/Uri;I)V
 Landroid/content/ContentResolver;->unstableProviderDied(Landroid/content/IContentProvider;)V
 Landroid/content/ContentValues;-><init>(Ljava/util/HashMap;)V
 Landroid/content/ContentValues;->mValues:Ljava/util/HashMap;
@@ -475,6 +486,7 @@
 Landroid/content/IntentFilter;->mActions:Ljava/util/ArrayList;
 Landroid/content/Intent;->mExtras:Landroid/os/Bundle;
 Landroid/content/Intent;->putExtra(Ljava/lang/String;Landroid/os/IBinder;)Landroid/content/Intent;
+Landroid/content/Intent;->toInsecureString()Ljava/lang/String;
 Landroid/content/pm/ActivityInfo;->resizeMode:I
 Landroid/content/pm/ActivityInfo;->supportsPictureInPicture()Z
 Landroid/content/pm/ApplicationInfo;->enabledSetting:I
@@ -515,6 +527,7 @@
 Landroid/content/pm/LauncherActivityInfo;->mActivityInfo:Landroid/content/pm/ActivityInfo;
 Landroid/content/pm/LauncherApps;->mPm:Landroid/content/pm/PackageManager;
 Landroid/content/pm/LauncherApps;->startShortcut(Ljava/lang/String;Ljava/lang/String;Landroid/graphics/Rect;Landroid/os/Bundle;I)V
+Landroid/content/pm/PackageInfo;->INSTALL_LOCATION_UNSPECIFIED:I
 Landroid/content/pm/PackageItemInfo;->setForceSafeLabels(Z)V
 Landroid/content/pm/PackageManager;->buildRequestPermissionsIntent([Ljava/lang/String;)Landroid/content/Intent;
 Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V
@@ -584,6 +597,7 @@
 Landroid/content/res/AssetFileDescriptor;->mStartOffset:J
 Landroid/content/res/AssetManager;->addAssetPathAsSharedLibrary(Ljava/lang/String;)I
 Landroid/content/res/AssetManager;->addAssetPath(Ljava/lang/String;)I
+Landroid/content/res/AssetManager;->applyStyle(JIILandroid/content/res/XmlBlock$Parser;[IJJ)V
 Landroid/content/res/AssetManager;->getAssignedPackageIdentifiers()Landroid/util/SparseArray;
 Landroid/content/res/AssetManager;->getResourceBagText(II)Ljava/lang/CharSequence;
 Landroid/content/res/AssetManager;->getResourceEntryName(I)Ljava/lang/String;
@@ -599,12 +613,14 @@
 Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;I)Ljava/io/InputStream;
 Landroid/content/res/AssetManager;->openNonAsset(Ljava/lang/String;)Ljava/io/InputStream;
 Landroid/content/res/AssetManager;->resolveAttrs(JII[I[I[I[I)Z
+Landroid/content/res/AssetManager;->retrieveAttributes(Landroid/content/res/XmlBlock$Parser;[I[I[I)Z
 Landroid/content/res/AssetManager;->setConfiguration(IILjava/lang/String;IIIIIIIIIIIIIII)V
 Landroid/content/res/ColorStateList$ColorStateListFactory;-><init>(Landroid/content/res/ColorStateList;)V
 Landroid/content/res/ColorStateList;->getColors()[I
 Landroid/content/res/ColorStateList;->mColors:[I
 Landroid/content/res/ColorStateList;->mDefaultColor:I
 Landroid/content/res/ColorStateList;->mFactory:Landroid/content/res/ColorStateList$ColorStateListFactory;
+Landroid/content/res/ColorStateList;->mStateSpecs:[[I
 Landroid/content/res/CompatibilityInfo;->applicationScale:F
 Landroid/content/res/CompatibilityInfo;->DEFAULT_COMPATIBILITY_INFO:Landroid/content/res/CompatibilityInfo;
 Landroid/content/res/DrawableCache;->getInstance(JLandroid/content/res/Resources;Landroid/content/res/Resources$Theme;)Landroid/graphics/drawable/Drawable;
@@ -747,6 +763,7 @@
 Landroid/graphics/drawable/Icon;->hasTint()Z
 Landroid/graphics/drawable/Icon;->mType:I
 Landroid/graphics/drawable/InsetDrawable;->mState:Landroid/graphics/drawable/InsetDrawable$InsetState;
+Landroid/graphics/drawable/LayerDrawable;->mLayerState:Landroid/graphics/drawable/LayerDrawable$LayerState;
 Landroid/graphics/drawable/NinePatchDrawable;->mNinePatchState:Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;
 Landroid/graphics/drawable/NinePatchDrawable$NinePatchState;->mNinePatch:Landroid/graphics/NinePatch;
 Landroid/graphics/drawable/StateListDrawable;->extractStateSet(Landroid/util/AttributeSet;)[I
@@ -778,6 +795,7 @@
 Landroid/graphics/PixelXorXfermode;-><init>(I)V
 Landroid/graphics/PorterDuffColorFilter;->setColor(I)V
 Landroid/graphics/PorterDuffColorFilter;->setMode(Landroid/graphics/PorterDuff$Mode;)V
+Landroid/graphics/Rect;->scale(F)V
 Landroid/graphics/Region;-><init>(JI)V
 Landroid/graphics/Region;->mNativeRegion:J
 Landroid/graphics/SurfaceTexture;->mFrameAvailableListener:J
@@ -1051,11 +1069,13 @@
 Landroid/media/MediaCodec;->getBuffers(Z)[Ljava/nio/ByteBuffer;
 Landroid/media/MediaCodec;->releaseOutputBuffer(IZZJ)V
 Landroid/media/MediaFile;->FIRST_AUDIO_FILE_TYPE:I
+Landroid/media/MediaFile;->getFileTypeForMimeType(Ljava/lang/String;)I
 Landroid/media/MediaFile;->getFileType(Ljava/lang/String;)Landroid/media/MediaFile$MediaFileType;
 Landroid/media/MediaFile;->getMimeTypeForFile(Ljava/lang/String;)Ljava/lang/String;
 Landroid/media/MediaFile;-><init>()V
 Landroid/media/MediaFile;->isAudioFileType(I)Z
 Landroid/media/MediaFile;->isImageFileType(I)Z
+Landroid/media/MediaFile;->isPlayListFileType(I)Z
 Landroid/media/MediaFile;->isVideoFileType(I)Z
 Landroid/media/MediaFile;->LAST_AUDIO_FILE_TYPE:I
 Landroid/media/MediaFile$MediaFileType;->fileType:I
@@ -1072,6 +1092,7 @@
 Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;Ljava/util/List;)V
 Landroid/media/MediaPlayer;->setDataSource(Ljava/lang/String;Ljava/util/Map;)V
 Landroid/media/MediaPlayer;->setRetransmitEndpoint(Ljava/net/InetSocketAddress;)V
+Landroid/media/MediaRecorder;->setParameter(Ljava/lang/String;)V
 Landroid/media/MediaRouter$RouteInfo;->getStatusCode()I
 Landroid/media/MediaRouter$RouteInfo;->STATUS_CONNECTING:I
 Landroid/media/MediaRouter;->selectRouteInt(ILandroid/media/MediaRouter$RouteInfo;Z)V
@@ -1142,8 +1163,10 @@
 Landroid/net/ConnectivityManager;->isNetworkSupported(I)Z
 Landroid/net/ConnectivityManager;->isNetworkTypeMobile(I)Z
 Landroid/net/ConnectivityManager;->mService:Landroid/net/IConnectivityManager;
+Landroid/net/ConnectivityManager;->registerNetworkFactory(Landroid/os/Messenger;Ljava/lang/String;)V
 Landroid/net/ConnectivityManager;->requestRouteToHostAddress(ILjava/net/InetAddress;)Z
 Landroid/net/ConnectivityManager;->requestRouteToHost(II)Z
+Landroid/net/ConnectivityManager;->setBackgroundDataSetting(Z)V
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_CBS:I
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_EMERGENCY:I
 Landroid/net/ConnectivityManager;->TYPE_MOBILE_FOTA:I
@@ -1285,6 +1308,7 @@
 Landroid/opengl/GLSurfaceView$EglHelper;->mEglContext:Ljavax/microedition/khronos/egl/EGLContext;
 Landroid/opengl/GLSurfaceView$GLThread;->mEglHelper:Landroid/opengl/GLSurfaceView$EglHelper;
 Landroid/opengl/GLSurfaceView;->mGLThread:Landroid/opengl/GLSurfaceView$GLThread;
+Landroid/opengl/GLSurfaceView;->mRenderer:Landroid/opengl/GLSurfaceView$Renderer;
 Landroid/os/AsyncTask;->mFuture:Ljava/util/concurrent/FutureTask;
 Landroid/os/AsyncTask;->mStatus:Landroid/os/AsyncTask$Status;
 Landroid/os/AsyncTask;->mTaskInvoked:Ljava/util/concurrent/atomic/AtomicBoolean;
@@ -1293,6 +1317,7 @@
 Landroid/os/AsyncTask;->setDefaultExecutor(Ljava/util/concurrent/Executor;)V
 Landroid/os/BatteryStats$Counter;->getCountLocked(I)I
 Landroid/os/BatteryStats;->getUidStats()Landroid/util/SparseArray;
+Landroid/os/BatteryStats$HistoryItem;->CMD_UPDATE:B
 Landroid/os/BatteryStats$HistoryItem;->states2:I
 Landroid/os/BatteryStats;->NUM_DATA_CONNECTION_TYPES:I
 Landroid/os/BatteryStats;->startIteratingHistoryLocked()Z
@@ -1904,6 +1929,7 @@
 Landroid/system/OsConstants;->XATTR_CREATE:I
 Landroid/system/OsConstants;->XATTR_REPLACE:I
 Landroid/system/StructTimeval;->fromMillis(J)Landroid/system/StructTimeval;
+Landroid/telecom/AudioState;->isMuted:Z
 Landroid/telecom/TelecomManager;->EXTRA_IS_HANDOVER:Ljava/lang/String;
 Landroid/telecom/TelecomManager;->getUserSelectedOutgoingPhoneAccount()Landroid/telecom/PhoneAccountHandle;
 Landroid/telecom/TelecomManager;->setUserSelectedOutgoingPhoneAccount(Landroid/telecom/PhoneAccountHandle;)V
@@ -1938,6 +1964,8 @@
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_MODERATE:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_NONE_OR_UNKNOWN:I
 Landroid/telephony/SignalStrength;->SIGNAL_STRENGTH_POOR:I
+Landroid/telephony/SmsManager;->sendMultipartTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;Ljava/util/ArrayList;Ljava/util/ArrayList;IZI)V
+Landroid/telephony/SmsManager;->sendTextMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;IZI)V
 Landroid/telephony/SmsMessage;->getSubId()I
 Landroid/telephony/SmsMessage;->mWrappedSmsMessage:Lcom/android/internal/telephony/SmsMessageBase;
 Landroid/telephony/SubscriptionManager;->getActiveSubscriptionIdList()[I
@@ -2032,6 +2060,7 @@
 Landroid/text/SpannableStringInternal;->setSpan(Ljava/lang/Object;IIIZ)V
 Landroid/text/SpannableStringInternal;->START:I
 Landroid/text/SpanSet;->spans:[Ljava/lang/Object;
+Landroid/text/StaticLayout;->getHeight(Z)I
 Landroid/text/StaticLayout;-><init>(Ljava/lang/CharSequence;IILandroid/text/TextPaint;ILandroid/text/Layout$Alignment;Landroid/text/TextDirectionHeuristic;FFZLandroid/text/TextUtils$TruncateAt;II)V
 Landroid/text/StaticLayout$LineBreaks;->ascents:[F
 Landroid/text/StaticLayout$LineBreaks;->breaks:[I
@@ -2091,18 +2120,21 @@
 Landroid/view/accessibility/AccessibilityManager;->sInstance:Landroid/view/accessibility/AccessibilityManager;
 Landroid/view/accessibility/AccessibilityManager;->sInstanceSync:Ljava/lang/Object;
 Landroid/view/accessibility/AccessibilityNodeInfo;->isSealed()Z
+Landroid/view/accessibility/AccessibilityNodeInfo;->mChildNodeIds:Landroid/util/LongArray;
 Landroid/view/accessibility/AccessibilityNodeInfo;->refresh(Landroid/os/Bundle;Z)Z
 Landroid/view/accessibility/AccessibilityNodeInfo;->setSealed(Z)V
 Landroid/view/accessibility/AccessibilityRecord;->getSourceNodeId()J
 Landroid/view/accessibility/IAccessibilityManager;->getEnabledAccessibilityServiceList(II)Ljava/util/List;
 Landroid/view/accessibility/IAccessibilityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/accessibility/IAccessibilityManager;
 Landroid/view/accessibility/IAccessibilityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/view/animation/Animation;->initializeInvalidateRegion(IIII)V
 Landroid/view/animation/Animation;->mListener:Landroid/view/animation/Animation$AnimationListener;
 Landroid/view/autofill/IAutoFillManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/Choreographer$CallbackQueue;->addCallbackLocked(JLjava/lang/Object;Ljava/lang/Object;)V
 Landroid/view/Choreographer;->doFrame(JI)V
 Landroid/view/Choreographer;->getFrameTime()J
 Landroid/view/Choreographer;->mCallbackQueues:[Landroid/view/Choreographer$CallbackQueue;
+Landroid/view/Choreographer;->mFrameIntervalNanos:J
 Landroid/view/Choreographer;->mLastFrameTimeNanos:J
 Landroid/view/Choreographer;->mLock:Ljava/lang/Object;
 Landroid/view/Choreographer;->scheduleVsyncLocked()V
@@ -2238,10 +2270,13 @@
 Landroid/view/Surface;->mLock:Ljava/lang/Object;
 Landroid/view/Surface;->mNativeObject:J
 Landroid/view/SurfaceSession;->mNativeClient:J
+Landroid/view/Surface;->transferFrom(Landroid/view/Surface;)V
+Landroid/view/SurfaceView;->isFixedSize()Z
 Landroid/view/SurfaceView;->mCallbacks:Ljava/util/ArrayList;
 Landroid/view/SurfaceView;->mFormat:I
 Landroid/view/SurfaceView;->mRequestedFormat:I
 Landroid/view/SurfaceView;->mSurfaceHolder:Landroid/view/SurfaceHolder;
+Landroid/view/SurfaceView;->setFrame(IIII)Z
 Landroid/view/SurfaceView;->surfacePositionLost_uiRtSync(J)V
 Landroid/view/SurfaceView;->updateSurfacePosition_renderWorker(JIIII)V
 Landroid/view/textclassifier/logging/SmartSelectionEventTracker;-><init>(Landroid/content/Context;I)V
@@ -2286,6 +2321,7 @@
 Landroid/view/View;->dispatchDetachedFromWindow()V
 Landroid/view/View;->fitsSystemWindows()Z
 Landroid/view/View;->getAccessibilityDelegate()Landroid/view/View$AccessibilityDelegate;
+Landroid/view/View;->getAccessibilityViewId()I
 Landroid/view/View;->getBoundsOnScreen(Landroid/graphics/Rect;)V
 Landroid/view/View;->getHorizontalScrollFactor()F
 Landroid/view/View;->getInverseMatrix()Landroid/graphics/Matrix;
@@ -2311,6 +2347,7 @@
 Landroid/view/ViewGroup;->mOnHierarchyChangeListener:Landroid/view/ViewGroup$OnHierarchyChangeListener;
 Landroid/view/ViewGroup;->mPersistentDrawingCache:I
 Landroid/view/ViewGroup;->offsetChildrenTopAndBottom(I)V
+Landroid/view/ViewGroup;->onChildVisibilityChanged(Landroid/view/View;II)V
 Landroid/view/ViewGroup;->resetResolvedDrawables()V
 Landroid/view/ViewGroup;->resetResolvedLayoutDirection()V
 Landroid/view/ViewGroup;->resetResolvedPadding()V
@@ -2321,6 +2358,7 @@
 Landroid/view/View;->initializeScrollbars(Landroid/content/res/TypedArray;)V
 Landroid/view/View;->internalSetPadding(IIII)V
 Landroid/view/View;->isPaddingResolved()Z
+Landroid/view/View;->isRootNamespace()Z
 Landroid/view/View;->isVisibleToUser(Landroid/graphics/Rect;)Z
 Landroid/view/View;->isVisibleToUser()Z
 Landroid/view/View$ListenerInfo;-><init>()V
@@ -2343,6 +2381,7 @@
 Landroid/view/View;->mPaddingRight:I
 Landroid/view/View;->mPaddingTop:I
 Landroid/view/View;->mParent:Landroid/view/ViewParent;
+Landroid/view/View;->mPrivateFlags2:I
 Landroid/view/View;->mPrivateFlags3:I
 Landroid/view/View;->mPrivateFlags:I
 Landroid/view/View;->mRecreateDisplayList:Z
@@ -2423,8 +2462,31 @@
 Landroid/view/Window;->mContext:Landroid/content/Context;
 Landroid/view/Window;->mHardwareAccelerated:Z
 Landroid/view/Window;->mWindowStyle:Landroid/content/res/TypedArray;
+Landroid/webkit/CacheManager;->cacheDisabled()Z
+Landroid/webkit/CacheManager$CacheResult;->getContentDisposition()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getContentLength()J
+Landroid/webkit/CacheManager$CacheResult;->getEncoding()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getETag()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getExpires()J
+Landroid/webkit/CacheManager$CacheResult;->getExpiresString()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getHttpStatusCode()I
+Landroid/webkit/CacheManager$CacheResult;->getInputStream()Ljava/io/InputStream;
+Landroid/webkit/CacheManager$CacheResult;->getLastModified()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getLocalPath()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getLocation()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getMimeType()Ljava/lang/String;
+Landroid/webkit/CacheManager$CacheResult;->getOutputStream()Ljava/io/OutputStream;
+Landroid/webkit/CacheManager$CacheResult;-><init>()V
+Landroid/webkit/CacheManager$CacheResult;->setEncoding(Ljava/lang/String;)V
+Landroid/webkit/CacheManager$CacheResult;->setInputStream(Ljava/io/InputStream;)V
+Landroid/webkit/CacheManager;->endCacheTransaction()Z
+Landroid/webkit/CacheManager;->getCacheFileBaseDir()Ljava/io/File;
+Landroid/webkit/CacheManager;->getCacheFile(Ljava/lang/String;Ljava/util/Map;)Landroid/webkit/CacheManager$CacheResult;
+Landroid/webkit/CacheManager;->saveCacheFile(Ljava/lang/String;Landroid/webkit/CacheManager$CacheResult;)V
+Landroid/webkit/CacheManager;->startCacheTransaction()Z
 Landroid/webkit/IWebViewUpdateService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/webkit/WebResourceResponse;->mImmutable:Z
+Landroid/webkit/WebSettings$TextSize;->value:I
 Landroid/webkit/WebSyncManager;->mHandler:Landroid/os/Handler;
 Landroid/webkit/WebViewClient;->onUnhandledInputEvent(Landroid/webkit/WebView;Landroid/view/InputEvent;)V
 Landroid/webkit/WebView;->debugDump()V
@@ -2435,11 +2497,13 @@
 Landroid/webkit/WebViewFactory;->getWebViewContextAndSetProvider()Landroid/content/Context;
 Landroid/webkit/WebViewFactory;->sPackageInfo:Landroid/content/pm/PackageInfo;
 Landroid/webkit/WebViewFactory;->sProviderInstance:Landroid/webkit/WebViewFactoryProvider;
+Landroid/webkit/WebView;->getContentWidth()I
 Landroid/webkit/WebView;->getTouchIconUrl()Ljava/lang/String;
 Landroid/webkit/WebView;->getVisibleTitleHeight()I
 Landroid/webkit/WebView;->isPaused()Z
 Landroid/webkit/WebView;->mProvider:Landroid/webkit/WebViewProvider;
 Landroid/webkit/WebView;->notifyFindDialogDismissed()V
+Landroid/webkit/WebView;->onDrawVerticalScrollBar(Landroid/graphics/Canvas;Landroid/graphics/drawable/Drawable;IIII)V
 Landroid/webkit/WebView;->restorePicture(Landroid/os/Bundle;Ljava/io/File;)Z
 Landroid/webkit/WebView;->savePicture(Landroid/os/Bundle;Ljava/io/File;)Z
 Landroid/webkit/WebView;->sEnforceThreadChecking:Z
@@ -2454,6 +2518,7 @@
 Landroid/widget/AbsListView;->mFastScroll:Landroid/widget/FastScroller;
 Landroid/widget/AbsListView;->mFlingRunnable:Landroid/widget/AbsListView$FlingRunnable;
 Landroid/widget/AbsListView;->mIsChildViewEnabled:Z
+Landroid/widget/AbsListView;->mLayoutMode:I
 Landroid/widget/AbsListView;->mMaximumVelocity:I
 Landroid/widget/AbsListView;->mMotionPosition:I
 Landroid/widget/AbsListView;->mOnScrollListener:Landroid/widget/AbsListView$OnScrollListener;
@@ -2483,6 +2548,8 @@
 Landroid/widget/ActivityChooserView;->setExpandActivityOverflowButtonDrawable(Landroid/graphics/drawable/Drawable;)V
 Landroid/widget/AdapterView;->mDataChanged:Z
 Landroid/widget/AdapterView;->mFirstPosition:I
+Landroid/widget/AdapterView;->mNextSelectedPosition:I
+Landroid/widget/AdapterView;->mNextSelectedRowId:J
 Landroid/widget/AdapterView;->mOldSelectedPosition:I
 Landroid/widget/AdapterView;->setNextSelectedPositionInt(I)V
 Landroid/widget/AdapterView;->setSelectedPositionInt(I)V
@@ -2492,6 +2559,7 @@
 Landroid/widget/AutoCompleteTextView;->mPopup:Landroid/widget/ListPopupWindow;
 Landroid/widget/AutoCompleteTextView;->setDropDownAlwaysVisible(Z)V
 Landroid/widget/AutoCompleteTextView;->setForceIgnoreOutsideTouch(Z)V
+Landroid/widget/BaseAdapter;->mDataSetObservable:Landroid/database/DataSetObservable;
 Landroid/widget/CompoundButton;->mButtonDrawable:Landroid/graphics/drawable/Drawable;
 Landroid/widget/CompoundButton;->mOnCheckedChangeListener:Landroid/widget/CompoundButton$OnCheckedChangeListener;
 Landroid/widget/CursorAdapter;->mChangeObserver:Landroid/widget/CursorAdapter$ChangeObserver;
@@ -2741,6 +2809,10 @@
 Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setFeatureTag(Ljava/lang/String;)V
 Lcom/android/ims/internal/uce/presence/PresTupleInfo;->setTimestamp(Ljava/lang/String;)V
 Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/internal/app/AlertController;->mCustomTitleView:Landroid/view/View;
+Lcom/android/internal/app/AlertController;->mForceInverseBackground:Z
+Lcom/android/internal/app/AlertController;->mTitle:Ljava/lang/CharSequence;
+Lcom/android/internal/app/AlertController;->mView:Landroid/view/View;
 Lcom/android/internal/app/AlertController$RecycleListView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 Lcom/android/internal/app/IAppOpsService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IAppOpsService;
 Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
@@ -3211,6 +3283,7 @@
 Ljava/lang/ref/Reference;->referent:Ljava/lang/Object;
 Ljava/lang/Runtime;->loadLibrary(Ljava/lang/String;Ljava/lang/ClassLoader;)V
 Ljava/lang/Runtime;->load(Ljava/lang/String;Ljava/lang/ClassLoader;)V
+Ljava/lang/Runtime;->mLibPaths:[Ljava/lang/String;
 Ljava/lang/Runtime;->nativeLoad(Ljava/lang/String;Ljava/lang/ClassLoader;)Ljava/lang/String;
 Ljava/lang/Short;->value:S
 Ljava/lang/String;-><init>(II[C)V
@@ -3232,7 +3305,9 @@
 Ljava/lang/Thread;->lock:Ljava/lang/Object;
 Ljava/lang/Thread;->name:Ljava/lang/String;
 Ljava/lang/Thread;->nativePeer:J
+Ljava/lang/Thread;->parkBlocker:Ljava/lang/Object;
 Ljava/lang/Thread;->priority:I
+Ljava/lang/Thread;->threadLocals:Ljava/lang/ThreadLocal$ThreadLocalMap;
 Ljava/lang/Throwable;->backtrace:Ljava/lang/Object;
 Ljava/lang/Throwable;->cause:Ljava/lang/Throwable;
 Ljava/lang/Throwable;->detailMessage:Ljava/lang/String;
@@ -3264,7 +3339,10 @@
 Ljava/net/Socket;->impl:Ljava/net/SocketImpl;
 Ljava/net/SocketImpl;->serverSocket:Ljava/net/ServerSocket;
 Ljava/net/SocketImpl;->socket:Ljava/net/Socket;
+Ljava/net/URI;->fragment:Ljava/lang/String;
 Ljava/net/URI;->host:Ljava/lang/String;
+Ljava/net/URI;->port:I
+Ljava/net/URI;->string:Ljava/lang/String;
 Ljava/net/URL;->handler:Ljava/net/URLStreamHandler;
 Ljava/net/URL;->handlers:Ljava/util/Hashtable;
 Ljava/nio/Buffer;->address:J
@@ -3285,6 +3363,9 @@
 Ljava/text/DateFormat;->is24Hour:Ljava/lang/Boolean;
 Ljava/time/Duration;->toSeconds()Ljava/math/BigDecimal;
 Ljava/time/OffsetDateTime;-><init>(Ljava/time/LocalDateTime;Ljava/time/ZoneOffset;)V
+Ljava/util/ArrayDeque;->elements:[Ljava/lang/Object;
+Ljava/util/ArrayDeque;->head:I
+Ljava/util/ArrayDeque;->tail:I
 Ljava/util/ArrayList;->elementData:[Ljava/lang/Object;
 Ljava/util/ArrayList;->size:I
 Ljava/util/ArrayList$SubList;->parent:Ljava/util/AbstractList;
@@ -3297,22 +3378,37 @@
 Ljava/util/Collections$SynchronizedMap;->m:Ljava/util/Map;
 Ljava/util/Collections$UnmodifiableCollection;->c:Ljava/util/Collection;
 Ljava/util/Collections$UnmodifiableMap;->m:Ljava/util/Map;
+Ljava/util/concurrent/atomic/AtomicInteger;->value:I
 Ljava/util/concurrent/ConcurrentHashMap$BaseIterator;->hasMoreElements()Z
+Ljava/util/concurrent/CopyOnWriteArraySet;->al:Ljava/util/concurrent/CopyOnWriteArrayList;
 Ljava/util/concurrent/Executors$RunnableAdapter;->task:Ljava/lang/Runnable;
 Ljava/util/concurrent/FutureTask;->callable:Ljava/util/concurrent/Callable;
 Ljava/util/concurrent/FutureTask;->EXCEPTIONAL:I
 Ljava/util/concurrent/FutureTask;->outcome:Ljava/lang/Object;
 Ljava/util/concurrent/FutureTask;->state:I
+Ljava/util/concurrent/LinkedBlockingDeque;->first:Ljava/util/concurrent/LinkedBlockingDeque$Node;
+Ljava/util/concurrent/LinkedBlockingDeque;->lock:Ljava/util/concurrent/locks/ReentrantLock;
 Ljava/util/concurrent/LinkedBlockingQueue;->capacity:I
+Ljava/util/concurrent/LinkedBlockingQueue;->head:Ljava/util/concurrent/LinkedBlockingQueue$Node;
+Ljava/util/concurrent/LinkedBlockingQueue;->putLock:Ljava/util/concurrent/locks/ReentrantLock;
+Ljava/util/concurrent/LinkedBlockingQueue;->takeLock:Ljava/util/concurrent/locks/ReentrantLock;
+Ljava/util/concurrent/ThreadPoolExecutor;->allowCoreThreadTimeOut:Z
 Ljava/util/EnumMap;->keyType:Ljava/lang/Class;
 Ljava/util/EnumSet;->elementType:Ljava/lang/Class;
 Ljava/util/HashMap$HashIterator;->hasNext()Z
+Ljava/util/HashMap;->modCount:I
+Ljava/util/HashMap;->table:[Ljava/util/HashMap$Node;
+Ljava/util/HashSet;->map:Ljava/util/HashMap;
 Ljava/util/jar/JarFile;->manifest:Ljava/util/jar/Manifest;
 Ljava/util/LinkedHashMap;->eldest()Ljava/util/Map$Entry;
 Ljava/util/LinkedHashMap$LinkedHashIterator;->hasNext()Z
+Ljava/util/LinkedList;->size:I
 Ljava/util/Locale;->createConstant(Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
+Ljava/util/PriorityQueue;->modCount:I
+Ljava/util/PriorityQueue;->size:I
 Ljava/util/Random;->seedUniquifier()J
 Ljava/util/regex/Matcher;->appendPos:I
+Ljava/util/Vector;->elementData(I)Ljava/lang/Object;
 Ljava/util/zip/Deflater;->buf:[B
 Ljava/util/zip/Deflater;->finished:Z
 Ljava/util/zip/Deflater;->finish:Z
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 5113fd0..757fc64 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1338,6 +1338,32 @@
             return false;
         }
 
+        /**
+         * @hide
+         */
+        public static int toggleScreenOffEffectsSuppressed(int currentEffects, boolean suppress) {
+            return toggleEffects(currentEffects, SCREEN_OFF_SUPPRESSED_EFFECTS, suppress);
+        }
+
+        /**
+         * @hide
+         */
+        public static int toggleScreenOnEffectsSuppressed(int currentEffects, boolean suppress) {
+            return toggleEffects(currentEffects, SCREEN_ON_SUPPRESSED_EFFECTS, suppress);
+        }
+
+        private static int toggleEffects(int currentEffects, int[] effects, boolean suppress) {
+            for (int i = 0; i < effects.length; i++) {
+                final int effect = effects[i];
+                if (suppress) {
+                    currentEffects |= effect;
+                } else {
+                    currentEffects &= ~effect;
+                }
+            }
+            return currentEffects;
+        }
+
         public static String suppressedEffectsToString(int effects) {
             if (effects <= 0) return "";
             final StringBuilder sb = new StringBuilder();
diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
index 37360ba..49cc498 100644
--- a/core/java/android/appwidget/AppWidgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -37,6 +37,7 @@
 import android.widget.RemoteViews;
 import android.widget.RemoteViews.OnClickHandler;
 
+import com.android.internal.R;
 import com.android.internal.appwidget.IAppWidgetHost;
 import com.android.internal.appwidget.IAppWidgetService;
 
@@ -171,8 +172,9 @@
                 return;
             }
             sServiceInitialized = true;
-            if (!context.getPackageManager().hasSystemFeature(
-                    PackageManager.FEATURE_APP_WIDGETS)) {
+            PackageManager packageManager = context.getPackageManager();
+            if (!packageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)
+                    && !context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) {
                 return;
             }
             IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
diff --git a/core/java/android/content/QuickViewConstants.java b/core/java/android/content/QuickViewConstants.java
index a25513d..132d43f 100644
--- a/core/java/android/content/QuickViewConstants.java
+++ b/core/java/android/content/QuickViewConstants.java
@@ -45,8 +45,8 @@
      * Feature to delete an individual document. Quick viewer implementations must use
      * Storage Access Framework to both verify delete permission and to delete content.
      *
-     * @see DocumentsContract#Document#FLAG_SUPPORTS_DELETE
-     * @see DocumentsContract#deleteDocument(ContentResolver resolver, Uri documentUri)
+     * @see DocumentsContract.Document#FLAG_SUPPORTS_DELETE
+     * @see DocumentsContract#deleteDocument(ContentResolver, Uri)
      */
     public static final String FEATURE_DELETE = "android:delete";
 
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 49b1efd..c5a39f4 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -26,6 +26,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
+import android.os.Build;
 import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -1166,7 +1167,8 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface HiddenApiEnforcementPolicy {}
 
-    private boolean isValidHiddenApiEnforcementPolicy(int policy) {
+    /** @hide */
+    public static boolean isValidHiddenApiEnforcementPolicy(int policy) {
         return policy >= HIDDEN_API_ENFORCEMENT_DEFAULT && policy <= HIDDEN_API_ENFORCEMENT_MAX;
     }
 
@@ -1686,13 +1688,17 @@
      * @hide
      */
     public @HiddenApiEnforcementPolicy int getHiddenApiEnforcementPolicy() {
-        if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
-            return mHiddenApiPolicy;
-        }
         if (isAllowedToUseHiddenApis()) {
             return HIDDEN_API_ENFORCEMENT_NONE;
         }
-        return HIDDEN_API_ENFORCEMENT_BLACK;
+        if (mHiddenApiPolicy != HIDDEN_API_ENFORCEMENT_DEFAULT) {
+            return mHiddenApiPolicy;
+        }
+        if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) {
+            return HIDDEN_API_ENFORCEMENT_BLACK;
+        } else {
+            return HIDDEN_API_ENFORCEMENT_DARK_GREY_AND_BLACK;
+        }
     }
 
     /**
@@ -1706,6 +1712,31 @@
     }
 
     /**
+     * Updates the hidden API enforcement policy for this app from the given values, if appropriate.
+     *
+     * This will have no effect if this app is not subject to hidden API enforcement, i.e. if it
+     * is on the package whitelist.
+     *
+     * @param policyPreP configured policy for pre-P apps, or {@link
+     *        #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured.
+     * @param policyP configured policy for apps targeting P or later, or {@link
+     *        #HIDDEN_API_ENFORCEMENT_DEFAULT} if nothing configured.
+     * @hide
+     */
+    public void maybeUpdateHiddenApiEnforcementPolicy(
+            @HiddenApiEnforcementPolicy int policyPreP, @HiddenApiEnforcementPolicy int policyP) {
+        if (isPackageWhitelistedForHiddenApis()) {
+            return;
+        }
+        if (targetSdkVersion <= Build.VERSION_CODES.O_MR1) {
+            setHiddenApiEnforcementPolicy(policyPreP);
+        } else if (targetSdkVersion > Build.VERSION_CODES.O_MR1) {
+            setHiddenApiEnforcementPolicy(policyP);
+        }
+
+    }
+
+    /**
      * @hide
      */
     public void setVersionCode(long newVersionCode) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 33e77d2..34e3d8b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -6131,7 +6131,9 @@
      * signed.  This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
      * since it takes into account the possibility of signing certificate rotation, except in the
      * case of packages that are signed by multiple certificates, for which signing certificate
-     * rotation is not supported.
+     * rotation is not supported.  This method is analogous to using {@code getPackageInfo} with
+     * {@code GET_SIGNING_CERTIFICATES} and then searching through the resulting {@code
+     * signingCertificateHistory} field to see if the desired certificate is present.
      *
      * @param packageName package whose signing certificates to check
      * @param certificate signing certificate for which to search
@@ -6145,13 +6147,19 @@
     }
 
     /**
-     * Searches the set of signing certificates by which the given uid has proven to have been
-     * signed.  This should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
+     * Searches the set of signing certificates by which the package(s) for the given uid has proven
+     * to have been signed.  For multiple packages sharing the same uid, this will return the
+     * signing certificates found in the signing history of the "newest" package, where "newest"
+     * indicates the package with the newest signing certificate in the shared uid group.  This
+     * method should be used instead of {@code getPackageInfo} with {@code GET_SIGNATURES}
      * since it takes into account the possibility of signing certificate rotation, except in the
      * case of packages that are signed by multiple certificates, for which signing certificate
-     * rotation is not supported.
+     * rotation is not supported. This method is analogous to using {@code getPackagesForUid}
+     * followed by {@code getPackageInfo} with {@code GET_SIGNING_CERTIFICATES}, selecting the
+     * {@code PackageInfo} of the newest-signed bpackage , and finally searching through the
+     * resulting {@code signingCertificateHistory} field to see if the desired certificate is there.
      *
-     * @param uid package whose signing certificates to check
+     * @param uid uid whose signing certificates to check
      * @param certificate signing certificate for which to search
      * @param type representation of the {@code certificate}
      * @return true if this package was or is signed by exactly the certificate {@code certificate}
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index a9d0911..699e81b 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -521,6 +521,11 @@
     public abstract @Nullable PackageParser.Package getPackage(@NonNull String packageName);
 
     /**
+     * Returns a {@link com.android.server.pm.PackageSetting} for a given package name.
+     */
+    public abstract @Nullable Object getPackageSetting(String packageName);
+
+    /**
      * Returns a list without a change observer.
      *
      * {@see #getPackageList(PackageListObserver)}
diff --git a/core/java/android/hardware/display/BrightnessConfiguration.java b/core/java/android/hardware/display/BrightnessConfiguration.java
index 67e97bf..6d9ba77 100644
--- a/core/java/android/hardware/display/BrightnessConfiguration.java
+++ b/core/java/android/hardware/display/BrightnessConfiguration.java
@@ -86,7 +86,9 @@
             sb.append("(").append(mLux[i]).append(", ").append(mNits[i]).append(")");
         }
         sb.append("], '");
-        sb.append(mDescription);
+        if (mDescription != null) {
+            sb.append(mDescription);
+        }
         sb.append("'}");
         return sb.toString();
     }
@@ -96,7 +98,9 @@
         int result = 1;
         result = result * 31 + Arrays.hashCode(mLux);
         result = result * 31 + Arrays.hashCode(mNits);
-        result = result * 31 + mDescription.hashCode();
+        if (mDescription != null) {
+            result = result * 31 + mDescription.hashCode();
+        }
         return result;
     }
 
diff --git a/core/java/android/hardware/display/Curve.aidl b/core/java/android/hardware/display/Curve.aidl
new file mode 100644
index 0000000..796493e
--- /dev/null
+++ b/core/java/android/hardware/display/Curve.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+parcelable Curve;
diff --git a/core/java/android/hardware/display/Curve.java b/core/java/android/hardware/display/Curve.java
new file mode 100644
index 0000000..ac28fdd
--- /dev/null
+++ b/core/java/android/hardware/display/Curve.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/** @hide */
+public final class Curve implements Parcelable {
+    private final float[] mX;
+    private final float[] mY;
+
+    public Curve(float[] x, float[] y) {
+        mX = x;
+        mY = y;
+    }
+
+    public float[] getX() {
+        return mX;
+    }
+
+    public float[] getY() {
+        return mY;
+    }
+
+    public static final Creator<Curve> CREATOR = new Creator<Curve>() {
+        public Curve createFromParcel(Parcel in) {
+            float[] x = in.createFloatArray();
+            float[] y = in.createFloatArray();
+            return new Curve(x, y);
+        }
+
+        public Curve[] newArray(int size) {
+            return new Curve[size];
+        }
+    };
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeFloatArray(mX);
+        out.writeFloatArray(mY);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index efb9517..b182fa2 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -28,6 +28,7 @@
 import android.graphics.Point;
 import android.media.projection.MediaProjection;
 import android.os.Handler;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.Surface;
@@ -748,6 +749,22 @@
     }
 
     /**
+     * Returns the minimum brightness curve, which guarantess that any brightness curve that dips
+     * below it is rejected by the system.
+     * This prevent auto-brightness from setting the screen so dark as to prevent the user from
+     * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable
+     * in that ambient brightness.
+     *
+     * @return The minimum brightness curve (as lux values and their corresponding nits values).
+     *
+     * @hide
+     */
+    @SystemApi
+    public Pair<float[], float[]> getMinimumBrightnessCurve() {
+        return mGlobal.getMinimumBrightnessCurve();
+    }
+
+    /**
      * Listens for changes in available display devices.
      */
     public interface DisplayListener {
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index 2d0ef2f..d968a3e 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -31,6 +31,7 @@
 import android.os.ServiceManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.view.Display;
 import android.view.DisplayAdjustments;
@@ -563,6 +564,24 @@
     }
 
     /**
+     * Returns the minimum brightness curve, which guarantess that any brightness curve that dips
+     * below it is rejected by the system.
+     * This prevent auto-brightness from setting the screen so dark as to prevent the user from
+     * resetting or disabling it, and maps lux to the absolute minimum nits that are still readable
+     * in that ambient brightness.
+     *
+     * @return The minimum brightness curve (as lux values and their corresponding nits values).
+     */
+    public Pair<float[], float[]> getMinimumBrightnessCurve() {
+        try {
+            Curve curve = mDm.getMinimumBrightnessCurve();
+            return Pair.create(curve.getX(), curve.getY());
+        } catch (RemoteException ex) {
+            throw ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Retrieves ambient brightness stats.
      */
     public List<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index b77de748..b575997 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -19,6 +19,7 @@
 import android.content.pm.ParceledListSlice;
 import android.graphics.Point;
 import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.Curve;
 import android.hardware.display.IDisplayManagerCallback;
 import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.display.WifiDisplay;
@@ -112,4 +113,7 @@
 
     // Temporarily sets the auto brightness adjustment factor.
     void setTemporaryAutoBrightnessAdjustment(float adjustment);
+
+    // Get the minimum brightness curve.
+    Curve getMinimumBrightnessCurve();
 }
diff --git a/core/java/android/net/NetworkPolicy.java b/core/java/android/net/NetworkPolicy.java
index 1a28732..e84c85e 100644
--- a/core/java/android/net/NetworkPolicy.java
+++ b/core/java/android/net/NetworkPolicy.java
@@ -19,7 +19,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.BackupUtils;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.util.Preconditions;
@@ -136,7 +136,7 @@
         return 0;
     }
 
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         return cycleRule.cycleIterator();
     }
 
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index bf6b7e0..6546c39 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -31,6 +31,7 @@
 import android.os.UserHandle;
 import android.util.DebugUtils;
 import android.util.Pair;
+import android.util.Range;
 
 import com.google.android.collect.Sets;
 
@@ -258,8 +259,21 @@
     }
 
     /** {@hide} */
+    @Deprecated
     public static Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator(NetworkPolicy policy) {
-        return policy.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
+        return new Iterator<Pair<ZonedDateTime, ZonedDateTime>>() {
+            @Override
+            public boolean hasNext() {
+                return it.hasNext();
+            }
+
+            @Override
+            public Pair<ZonedDateTime, ZonedDateTime> next() {
+                final Range<ZonedDateTime> r = it.next();
+                return Pair.create(r.getLower(), r.getUpper());
+            }
+        };
     }
 
     /**
diff --git a/core/java/android/net/NetworkState.java b/core/java/android/net/NetworkState.java
index b00cb48..321f971 100644
--- a/core/java/android/net/NetworkState.java
+++ b/core/java/android/net/NetworkState.java
@@ -26,6 +26,8 @@
  * @hide
  */
 public class NetworkState implements Parcelable {
+    private static final boolean SANITY_CHECK_ROAMING = false;
+
     public static final NetworkState EMPTY = new NetworkState(null, null, null, null, null, null);
 
     public final NetworkInfo networkInfo;
@@ -47,7 +49,7 @@
 
         // This object is an atomic view of a network, so the various components
         // should always agree on roaming state.
-        if (networkInfo != null && networkCapabilities != null) {
+        if (SANITY_CHECK_ROAMING && networkInfo != null && networkCapabilities != null) {
             if (networkInfo.isRoaming() == networkCapabilities
                     .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING)) {
                 Slog.wtf("NetworkState", "Roaming state disagreement between " + networkInfo
diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java
index e0fa63a..f9b6dfc 100644
--- a/core/java/android/net/http/X509TrustManagerExtensions.java
+++ b/core/java/android/net/http/X509TrustManagerExtensions.java
@@ -21,7 +21,6 @@
 
 import com.android.org.conscrypt.TrustManagerImpl;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.security.cert.CertificateException;
@@ -133,8 +132,6 @@
     /**
      * Returns {@code true} if the TrustManager uses the same trust configuration for the provided
      * hostnames.
-     *
-     * @hide
      */
     @SystemApi
     public boolean isSameTrustConfiguration(String hostname1, String hostname2) {
diff --git a/core/java/android/os/storage/DiskInfo.java b/core/java/android/os/storage/DiskInfo.java
index 9114107..d493cce 100644
--- a/core/java/android/os/storage/DiskInfo.java
+++ b/core/java/android/os/storage/DiskInfo.java
@@ -17,6 +17,7 @@
 package android.os.storage;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.res.Resources;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -93,7 +94,7 @@
         return true;
     }
 
-    public String getDescription() {
+    public @Nullable String getDescription() {
         final Resources res = Resources.getSystem();
         if ((flags & FLAG_SD) != 0) {
             if (isInteresting(label)) {
@@ -112,6 +113,17 @@
         }
     }
 
+    public @Nullable String getShortDescription() {
+        final Resources res = Resources.getSystem();
+        if (isSd()) {
+            return res.getString(com.android.internal.R.string.storage_sd_card);
+        } else if (isUsb()) {
+            return res.getString(com.android.internal.R.string.storage_usb_drive);
+        } else {
+            return null;
+        }
+    }
+
     public boolean isAdoptable() {
         return (flags & FLAG_ADOPTABLE) != 0;
     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 50d73ce..c7c2c15 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1179,6 +1179,23 @@
     public static final String ACTION_ZEN_MODE_SETTINGS = "android.settings.ZEN_MODE_SETTINGS";
 
     /**
+     * Activity Action: Show Zen Mode visual effects configuration settings.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ZEN_MODE_BLOCKED_EFFECTS_SETTINGS =
+            "android.settings.ZEN_MODE_BLOCKED_EFFECTS_SETTINGS";
+
+    /**
+     * Activity Action: Show Zen Mode onboarding activity.
+     *
+     * @hide
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ZEN_MODE_ONBOARDING = "android.settings.ZEN_MODE_ONBOARDING";
+
+    /**
      * Activity Action: Show Zen Mode (aka Do Not Disturb) priority configuration settings.
      */
     @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
@@ -3113,6 +3130,9 @@
          */
         public static final String DISPLAY_COLOR_MODE = "display_color_mode";
 
+        private static final Validator DISPLAY_COLOR_MODE_VALIDATOR =
+                new SettingsValidators.InclusiveIntegerRangeValidator(0, 2);
+
         /**
          * The amount of time in milliseconds before the device goes to sleep or begins
          * to dream after a period of inactivity.  This value is also known as the
@@ -4092,6 +4112,7 @@
             SHOW_BATTERY_PERCENT,
             NOTIFICATION_VIBRATION_INTENSITY,
             HAPTIC_FEEDBACK_INTENSITY,
+            DISPLAY_COLOR_MODE
         };
 
         /**
@@ -4204,6 +4225,7 @@
             PRIVATE_SETTINGS.add(LOCK_TO_APP_ENABLED);
             PRIVATE_SETTINGS.add(EGG_MODE);
             PRIVATE_SETTINGS.add(SHOW_BATTERY_PERCENT);
+            PRIVATE_SETTINGS.add(DISPLAY_COLOR_MODE);
         }
 
         /**
@@ -4225,6 +4247,7 @@
             VALIDATORS.put(NEXT_ALARM_FORMATTED, NEXT_ALARM_FORMATTED_VALIDATOR);
             VALIDATORS.put(FONT_SCALE, FONT_SCALE_VALIDATOR);
             VALIDATORS.put(DIM_SCREEN, DIM_SCREEN_VALIDATOR);
+            VALIDATORS.put(DISPLAY_COLOR_MODE, DISPLAY_COLOR_MODE_VALIDATOR);
             VALIDATORS.put(SCREEN_OFF_TIMEOUT, SCREEN_OFF_TIMEOUT_VALIDATOR);
             VALIDATORS.put(SCREEN_BRIGHTNESS_FOR_VR, SCREEN_BRIGHTNESS_FOR_VR_VALIDATOR);
             VALIDATORS.put(SCREEN_BRIGHTNESS_MODE, SCREEN_BRIGHTNESS_MODE_VALIDATOR);
@@ -11117,6 +11140,14 @@
         public static final String ALWAYS_FINISH_ACTIVITIES = "always_finish_activities";
 
         /**
+         * If nonzero, all system error dialogs will be hidden.  For example, the
+         * crash and ANR dialogs will not be shown, and the system will just proceed
+         * as if they had been accepted by the user.
+         * @hide
+         */
+        public static final String HIDE_ERROR_DIALOGS = "hide_error_dialogs";
+
+        /**
          * Use Dock audio output for media:
          *      0 = disabled
          *      1 = enabled
@@ -11735,6 +11766,29 @@
                 "hidden_api_blacklist_exemptions";
 
         /**
+         * Hidden API enforcement policy for apps targeting SDK versions prior to the latest
+         * version.
+         *
+         * Values correspond to @{@link
+         * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy}
+         *
+         * @hide
+         */
+        public static final String HIDDEN_API_POLICY_PRE_P_APPS =
+                "hidden_api_policy_pre_p_apps";
+
+        /**
+         * Hidden API enforcement policy for apps targeting the current SDK version.
+         *
+         * Values correspond to @{@link
+         * android.content.pm.ApplicationInfo.HiddenApiEnforcementPolicy}
+         *
+         * @hide
+         */
+        public static final String HIDDEN_API_POLICY_P_APPS =
+                "hidden_api_policy_p_apps";
+
+        /**
          * Timeout for a single {@link android.media.soundtrigger.SoundTriggerDetectionService}
          * operation (in ms).
          *
diff --git a/core/java/android/text/format/Formatter.java b/core/java/android/text/format/Formatter.java
index ad3b4b6..de86a66 100644
--- a/core/java/android/text/format/Formatter.java
+++ b/core/java/android/text/format/Formatter.java
@@ -40,6 +40,10 @@
     public static final int FLAG_SHORTER = 1 << 0;
     /** {@hide} */
     public static final int FLAG_CALCULATE_ROUNDED = 1 << 1;
+    /** {@hide} */
+    public static final int FLAG_SI_UNITS = 1 << 2;
+    /** {@hide} */
+    public static final int FLAG_IEC_UNITS = 1 << 3;
 
     /** {@hide} */
     public static class BytesResult {
@@ -90,7 +94,7 @@
         if (context == null) {
             return "";
         }
-        final BytesResult res = formatBytes(context.getResources(), sizeBytes, 0);
+        final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SI_UNITS);
         return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix,
                 res.value, res.units));
     }
@@ -103,41 +107,43 @@
         if (context == null) {
             return "";
         }
-        final BytesResult res = formatBytes(context.getResources(), sizeBytes, FLAG_SHORTER);
+        final BytesResult res = formatBytes(context.getResources(), sizeBytes,
+                FLAG_SI_UNITS | FLAG_SHORTER);
         return bidiWrap(context, context.getString(com.android.internal.R.string.fileSizeSuffix,
                 res.value, res.units));
     }
 
     /** {@hide} */
     public static BytesResult formatBytes(Resources res, long sizeBytes, int flags) {
+        final int unit = ((flags & FLAG_IEC_UNITS) != 0) ? 1024 : 1000;
         final boolean isNegative = (sizeBytes < 0);
         float result = isNegative ? -sizeBytes : sizeBytes;
         int suffix = com.android.internal.R.string.byteShort;
         long mult = 1;
         if (result > 900) {
             suffix = com.android.internal.R.string.kilobyteShort;
-            mult = 1000;
-            result = result / 1000;
+            mult = unit;
+            result = result / unit;
         }
         if (result > 900) {
             suffix = com.android.internal.R.string.megabyteShort;
-            mult *= 1000;
-            result = result / 1000;
+            mult *= unit;
+            result = result / unit;
         }
         if (result > 900) {
             suffix = com.android.internal.R.string.gigabyteShort;
-            mult *= 1000;
-            result = result / 1000;
+            mult *= unit;
+            result = result / unit;
         }
         if (result > 900) {
             suffix = com.android.internal.R.string.terabyteShort;
-            mult *= 1000;
-            result = result / 1000;
+            mult *= unit;
+            result = result / unit;
         }
         if (result > 900) {
             suffix = com.android.internal.R.string.petabyteShort;
-            mult *= 1000;
-            result = result / 1000;
+            mult *= unit;
+            result = result / unit;
         }
         // Note we calculate the rounded long by ourselves, but still let String.format()
         // compute the rounded value. String.format("%f", 0.1) might not return "0.1" due to
diff --git a/core/java/android/util/RecurrenceRule.java b/core/java/android/util/RecurrenceRule.java
index 9f115eb..975ad48 100644
--- a/core/java/android/util/RecurrenceRule.java
+++ b/core/java/android/util/RecurrenceRule.java
@@ -158,7 +158,7 @@
                 && period.getDays() == 0;
     }
 
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         if (period != null) {
             return new RecurringIterator();
         } else {
@@ -166,7 +166,7 @@
         }
     }
 
-    private class NonrecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+    private class NonrecurringIterator implements Iterator<Range<ZonedDateTime>> {
         boolean hasNext;
 
         public NonrecurringIterator() {
@@ -179,13 +179,13 @@
         }
 
         @Override
-        public Pair<ZonedDateTime, ZonedDateTime> next() {
+        public Range<ZonedDateTime> next() {
             hasNext = false;
-            return new Pair<>(start, end);
+            return new Range<>(start, end);
         }
     }
 
-    private class RecurringIterator implements Iterator<Pair<ZonedDateTime, ZonedDateTime>> {
+    private class RecurringIterator implements Iterator<Range<ZonedDateTime>> {
         int i;
         ZonedDateTime cycleStart;
         ZonedDateTime cycleEnd;
@@ -231,12 +231,12 @@
         }
 
         @Override
-        public Pair<ZonedDateTime, ZonedDateTime> next() {
+        public Range<ZonedDateTime> next() {
             if (LOGD) Log.d(TAG, "Cycle " + i + " from " + cycleStart + " to " + cycleEnd);
-            Pair<ZonedDateTime, ZonedDateTime> p = new Pair<>(cycleStart, cycleEnd);
+            Range<ZonedDateTime> r = new Range<>(cycleStart, cycleEnd);
             i--;
             updateCycle();
-            return p;
+            return r;
         }
     }
 
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index da15506..c5ab2e6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -487,6 +487,7 @@
     <protected-broadcast android:name="android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED" />
     <protected-broadcast android:name="android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED" />
     <protected-broadcast android:name="android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION" />
+    <protected-broadcast android:name="android.telephony.action.SUBSCRIPTION_PLANS_CHANGED" />
 
     <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" />
     <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" />
diff --git a/core/res/res/drawable/ic_zen_24dp.xml b/core/res/res/drawable/ic_zen_24dp.xml
new file mode 100644
index 0000000..790bfb9
--- /dev/null
+++ b/core/res/res/drawable/ic_zen_24dp.xml
@@ -0,0 +1,26 @@
+<!--
+     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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:viewportHeight="24.0"
+        android:viewportWidth="24.0"
+        android:height="24dp"
+        android:width="24dp" >
+
+    <path
+        android:fillColor="?android:attr/colorControlActivated"
+        android:pathData="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm4 11H8c-.55 0-1-.45-1-1s.45-1 1-1h8c.55 0 1 .45 1 1s-.45 1-1 1z" />
+
+</vector>
\ No newline at end of file
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index aceba08..fe34d98 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2154,9 +2154,6 @@
             Corresponds to <code>LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES</code>.
             -->
             <enum name="shortEdges" value="1" />
-            <!-- Use <code>shortEdges</code> instead. This is temporarily here to unblock pushing
-                 the SDK until all usages have been migrated to <code>shortEdges</code> -->
-            <enum name="always" value="1" />
             <!-- <p>
             The window is never allowed to overlap with the <code>DisplayCutout</code> area.
             <p>
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 7048511..0fe80a1 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -38,4 +38,8 @@
     <color name="background_device_default_light">@color/background_material_light</color>
     <color name="background_floating_device_default_dark">@color/background_floating_material_dark</color>
     <color name="background_floating_device_default_light">@color/background_floating_material_light</color>
+
+    <!-- Error color -->
+    <color name="error_color_device_default_dark">@color/error_color_material_dark</color>
+    <color name="error_color_device_default_light">@color/error_color_material_light</color>
 </resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 4ce89c9..fc030ca 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1289,6 +1289,32 @@
          in darkness (although they may not be visible in a bright room). -->
     <integer name="config_screenBrightnessDark">1</integer>
 
+    <!-- Array of lux values to define the minimum brightness curve, which guarantees that any
+         brightness curve that dips below it is rejected by the system.
+         This prevents auto-brightness from setting the screen so dark as to prevent the user from
+         resetting or disabling it.
+
+         The values must be non-negative and strictly increasing, and correspond to the values in
+         the config_minimumBrightnessCurveNits array. -->
+    <array name="config_minimumBrightnessCurveLux">
+        <item>0.0</item>
+        <item>2000.0</item>
+        <item>4000.0</item>
+    </array>
+
+    <!-- Array of nits values to define the minimum brightness curve, which guarantees that any
+         brightness curve that dips below it is rejected by the system.
+         This should map lux to the absolute minimum nits that are still readable in that ambient
+         brightness.
+
+         The values must be non-negative and non-decreasing, and correspond to the values in the
+         config_minimumBrightnessCurveLux array. -->
+    <array name="config_minimumBrightnessCurveNits">
+        <item>0.0</item>
+        <item>50.0</item>
+        <item>90.0</item>
+    </array>
+
     <!-- Array of light sensor lux values to define our levels for auto backlight brightness support.
          The N entries of this array define N + 1 control points as follows:
          (1-based arrays)
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 715be5b..1798d45 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4943,9 +4943,9 @@
     <!-- Title for the notification channel notifying user of do not disturb system changes (i.e. Do Not Disturb has changed). [CHAR LIMIT=NONE] -->
     <string name="notification_channel_do_not_disturb">Do Not Disturb</string>
     <!-- Title of notification indicating do not disturb visual interruption settings have changed when upgrading to P -->
-    <string name="zen_upgrade_notification_visd_title">Do Not Disturb is hiding notifications to help you focus</string>
+    <string name="zen_upgrade_notification_visd_title">New: Do Not Disturb is hiding notifications</string>
     <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings -->
-    <string name="zen_upgrade_notification_visd_content">This is new behavior. Tap to change.</string>
+    <string name="zen_upgrade_notification_visd_content">Tap to learn more and change.</string>
     <!-- Title of notification indicating do not disturb settings have changed when upgrading to P -->
     <string name="zen_upgrade_notification_title">Do Not Disturb has changed</string>
     <!-- Content of notification indicating users can tap on the notification to go to dnd behavior settings -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index ce7f1ff..b6f0b70 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1810,6 +1810,8 @@
   <java-symbol type="array" name="config_dynamicHysteresisBrightLevels" />
   <java-symbol type="array" name="config_dynamicHysteresisDarkLevels" />
   <java-symbol type="array" name="config_dynamicHysteresisLuxLevels" />
+  <java-symbol type="array" name="config_minimumBrightnessCurveLux" />
+  <java-symbol type="array" name="config_minimumBrightnessCurveNits" />
   <java-symbol type="array" name="config_protectedNetworks" />
   <java-symbol type="array" name="config_statusBarIcons" />
   <java-symbol type="array" name="config_tether_bluetooth_regexs" />
@@ -2547,6 +2549,7 @@
   <java-symbol type="drawable" name="ic_settings_24dp" />
   <java-symbol type="drawable" name="ic_storage_48dp" />
   <java-symbol type="drawable" name="ic_usb_48dp" />
+  <java-symbol type="drawable" name="ic_zen_24dp" />
 
   <!-- Floating toolbar -->
   <java-symbol type="id" name="floating_toolbar_menu_item_image" />
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index fd6cc95..92b2f33 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -210,6 +210,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
     </style>
 
@@ -221,6 +222,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -248,6 +250,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -277,6 +280,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -305,6 +309,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -348,6 +353,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -368,6 +374,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -394,6 +401,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -421,6 +429,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -464,6 +473,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -492,6 +502,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -518,6 +529,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -546,6 +558,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -573,6 +586,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -600,6 +614,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -627,6 +642,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -654,6 +670,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -685,6 +702,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Text styles -->
         <item name="textAppearanceButton">@style/TextAppearance.DeviceDefault.Widget.Button</item>
@@ -706,6 +724,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -731,6 +750,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -908,6 +928,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
     </style>
 
     <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
@@ -917,6 +938,7 @@
         <item name="colorPrimary">@color/primary_device_default_dark</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_dark</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -943,6 +965,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -970,6 +993,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -999,6 +1023,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1027,6 +1052,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1072,6 +1098,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
@@ -1091,6 +1118,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1120,6 +1148,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1150,6 +1179,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1181,6 +1211,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -1194,6 +1225,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -1206,6 +1238,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1237,6 +1270,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1266,6 +1300,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1294,6 +1329,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1321,6 +1357,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1346,6 +1383,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1371,6 +1409,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1404,6 +1443,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorEdgeEffect">@android:color/black</item>
 
         <!-- Add white nav bar with divider that matches material -->
@@ -1438,6 +1478,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
         <item name="colorControlNormal">?attr/textColorPrimary</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
 
@@ -1465,6 +1506,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings_light</item>
         <item name="colorSecondary">@color/secondary_device_default_settings_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
 
         <!-- Progress bar attributes -->
@@ -1482,6 +1524,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
+        <item name="colorError">@color/error_color_device_default_dark</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1511,6 +1554,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1540,6 +1584,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1569,6 +1614,7 @@
         <item name="colorPrimaryDark">@color/primary_dark_device_default_settings</item>
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Dialog attributes -->
         <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
@@ -1617,6 +1663,7 @@
         <item name="colorPrimary">@color/primary_device_default_light</item>
         <item name="colorPrimaryDark">@color/primary_dark_device_default_light</item>
         <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
 
         <!-- Progress bar attributes -->
         <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
diff --git a/core/tests/coretests/AndroidTest.xml b/core/tests/coretests/AndroidTest.xml
index 7b5ad9a..68ef34b 100644
--- a/core/tests/coretests/AndroidTest.xml
+++ b/core/tests/coretests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <option name="test-tag" value="FrameworksCoreTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.coretests" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
index bad0d25..5ef30a8 100644
--- a/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
+++ b/core/tests/coretests/src/android/hardware/display/BrightnessConfigurationTest.java
@@ -41,7 +41,7 @@
     };
 
     private static final float[] NITS_LEVELS = {
-        0.5f,
+        1f,
         90f,
         100f,
     };
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index cb3509c..a5941b2 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -60,7 +60,6 @@
                     Settings.System.ALARM_ALERT, // backup candidate?
                     Settings.System.ALARM_ALERT_CACHE, // internal cache
                     Settings.System.APPEND_FOR_LAST_AUDIBLE, // suffix deprecated since API 2
-                    Settings.System.DISPLAY_COLOR_MODE, // bug?
                     Settings.System.EGG_MODE, // I am the lolrus
                     Settings.System.END_BUTTON_BEHAVIOR, // bug?
                     Settings.System
@@ -247,6 +246,9 @@
                     Settings.Global.HDMI_CONTROL_ENABLED,
                     Settings.Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED,
                     Settings.Global.HEADS_UP_NOTIFICATIONS_ENABLED,
+                    Settings.Global.HIDDEN_API_POLICY_P_APPS,
+                    Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS,
+                    Settings.Global.HIDE_ERROR_DIALOGS,
                     Settings.Global.HTTP_PROXY,
                     HYBRID_SYSUI_BATTERY_WARNING_FLAGS,
                     Settings.Global.INET_CONDITION_DEBOUNCE_DOWN_DELAY,
diff --git a/core/tests/coretests/src/android/text/format/FormatterTest.java b/core/tests/coretests/src/android/text/format/FormatterTest.java
index 04d2dad..c02d97c 100644
--- a/core/tests/coretests/src/android/text/format/FormatterTest.java
+++ b/core/tests/coretests/src/android/text/format/FormatterTest.java
@@ -16,12 +16,14 @@
 
 package android.text.format;
 
+import static android.text.format.Formatter.FLAG_IEC_UNITS;
+import static android.text.format.Formatter.FLAG_SI_UNITS;
+
 import static org.junit.Assert.assertEquals;
 
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
-import android.icu.util.MeasureUnit;
 import android.platform.test.annotations.Presubmit;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.SmallTest;
@@ -34,7 +36,6 @@
 import org.junit.runner.RunWith;
 
 import java.util.Locale;
-import java.util.Set;
 
 @Presubmit
 @SmallTest
@@ -104,6 +105,27 @@
         checkFormatBytes(9123000, false, "9,12", 9120000);
     }
 
+    @Test
+    public void testFormatBytesSi() {
+        setLocale(Locale.US);
+
+        checkFormatBytes(1_000, FLAG_SI_UNITS, "1.00", 1_000);
+        checkFormatBytes(1_024, FLAG_SI_UNITS, "1.02", 1_020);
+        checkFormatBytes(1_500, FLAG_SI_UNITS, "1.50", 1_500);
+        checkFormatBytes(12_582_912L, FLAG_SI_UNITS, "12.58", 12_580_000L);
+    }
+
+    @Test
+    public void testFormatBytesIec() {
+        setLocale(Locale.US);
+
+        checkFormatBytes(1_000, FLAG_IEC_UNITS, "0.98", 1_003);
+        checkFormatBytes(1_024, FLAG_IEC_UNITS, "1.00", 1_024);
+        checkFormatBytes(1_500, FLAG_IEC_UNITS, "1.46", 1_495);
+        checkFormatBytes(12_500_000L, FLAG_IEC_UNITS, "11.92", 12_499_025L);
+        checkFormatBytes(12_582_912L, FLAG_IEC_UNITS, "12.00", 12_582_912L);
+    }
+
     private static final long SECOND = 1000;
     private static final long MINUTE = 60 * SECOND;
     private static final long HOUR = 60 * MINUTE;
@@ -195,8 +217,14 @@
 
     private void checkFormatBytes(long bytes, boolean useShort,
             String expectedString, long expectedRounded) {
+        checkFormatBytes(bytes, (useShort ? Formatter.FLAG_SHORTER : 0),
+                expectedString, expectedRounded);
+    }
+
+    private void checkFormatBytes(long bytes, int flags,
+            String expectedString, long expectedRounded) {
         BytesResult r = Formatter.formatBytes(mContext.getResources(), bytes,
-                Formatter.FLAG_CALCULATE_ROUNDED | (useShort ? Formatter.FLAG_SHORTER : 0));
+                Formatter.FLAG_CALCULATE_ROUNDED | flags);
         assertEquals(expectedString, r.value);
         assertEquals(expectedRounded, r.roundedBytes);
     }
diff --git a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
index 42b6048..39d492d 100644
--- a/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
+++ b/core/tests/coretests/src/android/util/RecurrenceRuleTest.java
@@ -57,13 +57,13 @@
 
         assertTrue(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2015-11-14T00:00:00.00Z"),
                 ZonedDateTime.parse("2015-12-14T00:00:00.00Z")), it.next());
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2015-10-14T00:00:00.00Z"),
                 ZonedDateTime.parse("2015-11-14T00:00:00.00Z")), it.next());
     }
@@ -77,13 +77,13 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-17T00:11:00.00Z"),
                 ZonedDateTime.parse("2010-11-20T00:11:00.00Z")), it.next());
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-14T00:11:00.00Z"),
                 ZonedDateTime.parse("2010-11-17T00:11:00.00Z")), it.next());
         assertFalse(it.hasNext());
@@ -98,9 +98,9 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertTrue(it.hasNext());
-        assertEquals(Pair.create(
+        assertEquals(new Range<>(
                 ZonedDateTime.parse("2010-11-14T00:11:00.000Z"),
                 ZonedDateTime.parse("2010-11-20T00:11:00.000Z")), it.next());
         assertFalse(it.hasNext());
@@ -112,7 +112,7 @@
 
         assertFalse(r.isMonthly());
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         assertFalse(it.hasNext());
     }
 
@@ -122,22 +122,22 @@
                 ZonedDateTime.parse("2030-01-31T00:00:00.000Z"),
                 Period.ofMonths(1));
 
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = r.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = r.cycleIterator();
         ZonedDateTime lastStart = null;
         int months = 0;
         while (it.hasNext()) {
-            final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
+            final Range<ZonedDateTime> cycle = it.next();
 
             // Make sure cycle has reasonable length
-            final long length = cycle.second.toEpochSecond() - cycle.first.toEpochSecond();
+            final long length = cycle.getUpper().toEpochSecond() - cycle.getLower().toEpochSecond();
             assertTrue(cycle + " must be more than 4 weeks", length >= 2419200);
             assertTrue(cycle + " must be less than 5 weeks", length <= 3024000);
 
             // Make sure we have no gaps
             if (lastStart != null) {
-                assertEquals(lastStart, cycle.second);
+                assertEquals(lastStart, cycle.getUpper());
             }
-            lastStart = cycle.first;
+            lastStart = cycle.getLower();
             months++;
         }
 
diff --git a/core/tests/privacytests/AndroidTest.xml b/core/tests/privacytests/AndroidTest.xml
index 8098c14..a3e785c 100644
--- a/core/tests/privacytests/AndroidTest.xml
+++ b/core/tests/privacytests/AndroidTest.xml
@@ -23,5 +23,6 @@
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.coretests.privacy" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/core/tests/utiltests/AndroidTest.xml b/core/tests/utiltests/AndroidTest.xml
index 270d773..f32acb4 100644
--- a/core/tests/utiltests/AndroidTest.xml
+++ b/core/tests/utiltests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <option name="test-tag" value="FrameworksUtilTests" />
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.utiltests" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 985a756..7d4e6f8 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -456,6 +456,22 @@
 
     uninit();
 
+    // The chunk must be at least the size of the string pool header.
+    if (size < sizeof(ResStringPool_header)) {
+        LOG_ALWAYS_FATAL("Bad string block: data size %zu is too small to be a string block", size);
+        return (mError=BAD_TYPE);
+    }
+
+    // The data is at least as big as a ResChunk_header, so we can safely validate the other
+    // header fields.
+    // `data + size` is safe because the source of `size` comes from the kernel/filesystem.
+    if (validate_chunk(reinterpret_cast<const ResChunk_header*>(data), sizeof(ResStringPool_header),
+                       reinterpret_cast<const uint8_t*>(data) + size,
+                       "ResStringPool_header") != NO_ERROR) {
+        LOG_ALWAYS_FATAL("Bad string block: malformed block dimensions");
+        return (mError=BAD_TYPE);
+    }
+
     const bool notDeviceEndian = htods(0xf0) != 0xf0;
 
     if (copyData || notDeviceEndian) {
@@ -467,6 +483,8 @@
         data = mOwnedData;
     }
 
+    // The size has been checked, so it is safe to read the data in the ResStringPool_header
+    // data structure.
     mHeader = (const ResStringPool_header*)data;
 
     if (notDeviceEndian) {
diff --git a/location/tests/locationtests/AndroidTest.xml b/location/tests/locationtests/AndroidTest.xml
index 0c5b7cc..bb6547b 100644
--- a/location/tests/locationtests/AndroidTest.xml
+++ b/location/tests/locationtests/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.locationtests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 0458931..9152ff2 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -250,9 +250,10 @@
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,    SUPPRESSIBLE_MEDIA);
         SUPPRESSIBLE_USAGES.put(USAGE_GAME,                              SUPPRESSIBLE_MEDIA);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT,                         SUPPRESSIBLE_MEDIA);
+        /** default volume assignment is STREAM_MUSIC, handle unknown usage as media */
+        SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN,                           SUPPRESSIBLE_MEDIA);
         SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING,    SUPPRESSIBLE_SYSTEM);
         SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION,           SUPPRESSIBLE_SYSTEM);
-        SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN,                           SUPPRESSIBLE_SYSTEM);
     }
 
     /**
@@ -1057,8 +1058,7 @@
             case USAGE_ASSISTANCE_ACCESSIBILITY:
                 return AudioSystem.STREAM_ACCESSIBILITY;
             case USAGE_UNKNOWN:
-                return fromGetVolumeControlStream ?
-                        AudioManager.USE_DEFAULT_STREAM_TYPE : AudioSystem.STREAM_MUSIC;
+                return AudioSystem.STREAM_MUSIC;
             default:
                 if (fromGetVolumeControlStream) {
                     throw new IllegalArgumentException("Unknown usage value " + aa.getUsage() +
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index b4ca88c..ed2afdd 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -809,7 +809,11 @@
             mAudioTrack = newTrack;
             ALOGV("using new track %p for sample %d", newTrack.get(), sample->sampleID());
         }
-        newTrack->setVolume(leftVolume, rightVolume);
+        if (mMuted) {
+            newTrack->setVolume(0.0f, 0.0f);
+        } else {
+            newTrack->setVolume(leftVolume, rightVolume);
+        }
         newTrack->setLoop(0, frameCount, loop);
         mPos = 0;
         mSample = sample;
diff --git a/packages/MtpDocumentsProvider/tests/AndroidTest.xml b/packages/MtpDocumentsProvider/tests/AndroidTest.xml
index 940d364..f84131c 100644
--- a/packages/MtpDocumentsProvider/tests/AndroidTest.xml
+++ b/packages/MtpDocumentsProvider/tests/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.InstrumentationTest" >
         <option name="package" value="com.android.mtp.tests" />
         <option name="runner" value="com.android.mtp.TestResultInstrumentation" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
index 15dd64b..d21a2e4 100644
--- a/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
+++ b/packages/PrintSpooler/tests/outofprocess/AndroidTest.xml
@@ -25,5 +25,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.printspooler.outofprocess.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/SettingsLib/tests/integ/AndroidTest.xml b/packages/SettingsLib/tests/integ/AndroidTest.xml
index 96621eb..d7ee618 100644
--- a/packages/SettingsLib/tests/integ/AndroidTest.xml
+++ b/packages/SettingsLib/tests/integ/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.settingslib" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml
index 3a156895..46b8f94 100644
--- a/packages/SettingsProvider/test/AndroidTest.xml
+++ b/packages/SettingsProvider/test/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.providers.setting.test" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/Shell/tests/AndroidTest.xml b/packages/Shell/tests/AndroidTest.xml
index bd37712c..e592d82 100644
--- a/packages/Shell/tests/AndroidTest.xml
+++ b/packages/Shell/tests/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.shell.tests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar.xml b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
index 18301a8..02be457 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_left_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar.xml b/packages/SystemUI/res/layout/car_navigation_bar.xml
index 9ff16a2..d568d0d 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar.xml
@@ -38,7 +38,7 @@
             android:id="@+id/home"
             android:layout_height="match_parent"
             android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
index b0488ae..4ba6c06 100644
--- a/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_navigation_bar_unprovisioned.xml
@@ -38,7 +38,7 @@
             android:id="@+id/home"
             android:layout_height="match_parent"
             android:layout_width="wrap_content"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingLeft="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar.xml b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
index 99bd23c..91ba026 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
index a65ff16..708f595 100644
--- a/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
+++ b/packages/SystemUI/res/layout/car_right_navigation_bar_unprovisioned.xml
@@ -40,7 +40,7 @@
             android:id="@+id/home"
             android:layout_height="wrap_content"
             android:layout_width="match_parent"
-            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;end"
+            systemui:intent="intent:#Intent;action=android.intent.action.MAIN;category=android.intent.category.HOME;launchFlags=0x14000000;end"
             android:src="@drawable/car_ic_overview"
             android:background="?android:attr/selectableItemBackground"
             android:paddingTop="30dp"
diff --git a/packages/SystemUI/res/layout/remote_input.xml b/packages/SystemUI/res/layout/remote_input.xml
index e4ea08e..b5d48b4 100644
--- a/packages/SystemUI/res/layout/remote_input.xml
+++ b/packages/SystemUI/res/layout/remote_input.xml
@@ -51,12 +51,10 @@
 
         <ImageButton
                 android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
+                android:layout_height="match_parent"
                 android:layout_gravity="center"
                 android:paddingStart="12dp"
                 android:paddingEnd="24dp"
-                android:paddingTop="16dp"
-                android:paddingBottom="16dp"
                 android:id="@+id/remote_input_send"
                 android:src="@drawable/ic_send"
                 android:contentDescription="@*android:string/ime_action_send"
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 0e92c60..d45c427 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -98,5 +98,8 @@
     <item type="id" name="status_bar_view_state_tag" />
 
     <item type="id" name="display_cutout" />
+
+    <!-- Optional cancel button on Keyguard -->
+    <item type="id" name="cancel_button"/>
 </resources>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
index 20d1418..78b1b2614 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/recents/model/IconLoader.java
@@ -15,10 +15,13 @@
  */
 package com.android.systemui.shared.recents.model;
 
+import static android.content.pm.PackageManager.MATCH_ANY_USER;
+
 import android.app.ActivityManager;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
@@ -108,10 +111,12 @@
         }
         if (desc.getIconResource() != 0) {
             try {
-                Context packageContext = mContext.createPackageContextAsUser(
-                        taskKey.getPackageName(), 0, UserHandle.of(userId));
-                return createBadgedDrawable(packageContext.getDrawable(desc.getIconResource()),
-                        userId, desc);
+                PackageManager pm = mContext.getPackageManager();
+                ApplicationInfo appInfo = pm.getApplicationInfo(taskKey.getPackageName(),
+                        MATCH_ANY_USER);
+                Resources res = pm.getResourcesForApplication(appInfo);
+                return createBadgedDrawable(res.getDrawable(desc.getIconResource(), null), userId,
+                        desc);
             } catch (Resources.NotFoundException|PackageManager.NameNotFoundException e) {
                 Log.e(TAG, "Could not find icon drawable from resource", e);
             }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
index 6fa7db3..32e4bbf 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/PackageManagerWrapper.java
@@ -18,23 +18,24 @@
 
 import android.app.AppGlobals;
 import android.content.ComponentName;
+import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.os.RemoteException;
 
-import java.util.ArrayList;
 import java.util.List;
 
 public class PackageManagerWrapper {
 
-    private static final String TAG = "PackageManagerWrapper";
-
     private static final PackageManagerWrapper sInstance = new PackageManagerWrapper();
 
     private static final IPackageManager mIPackageManager = AppGlobals.getPackageManager();
 
+    public static final String ACTION_PREFERRED_ACTIVITY_CHANGED =
+            Intent.ACTION_PREFERRED_ACTIVITY_CHANGED;
+
     public static PackageManagerWrapper getInstance() {
         return sInstance;
     }
@@ -53,40 +54,15 @@
     }
 
     /**
-     * @return true if the packageName belongs to the current preferred home app on the device.
-     *
-     * If will also return false if there are multiple home apps and the user has not picked any
-     * preferred home, in which case the user would see a disambiguation screen on going to home.
+     * Report the set of 'Home' activity candidates, plus (if any) which of them
+     * is the current "always use this one" setting.
      */
-    public boolean isDefaultHomeActivity(String packageName) {
-        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
-        ComponentName home;
+    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
         try {
-            home = mIPackageManager.getHomeActivities(allHomeCandidates);
+            return mIPackageManager.getHomeActivities(allHomeCandidates);
         } catch (RemoteException e) {
             e.printStackTrace();
-            return false;
+            return null;
         }
-
-        if (home != null && packageName.equals(home.getPackageName())) {
-            return true;
-        }
-
-        // Find the launcher with the highest priority and return that component if there are no
-        // other home activity with the same priority.
-        int lastPriority = Integer.MIN_VALUE;
-        ComponentName lastComponent = null;
-        final int size = allHomeCandidates.size();
-        for (int i = 0; i < size; i++) {
-            final ResolveInfo ri = allHomeCandidates.get(i);
-            if (ri.priority > lastPriority) {
-                lastComponent = ri.activityInfo.getComponentName();
-                lastPriority = ri.priority;
-            } else if (ri.priority == lastPriority) {
-                // Two components found with same priority.
-                lastComponent = null;
-            }
-        }
-        return lastComponent != null && packageName.equals(lastComponent.getPackageName());
     }
 }
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index c1cff9e..adb2460 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -107,6 +107,13 @@
                 new View[]{
                         null, mEcaView, null
                 }};
+
+        View cancelBtn = findViewById(R.id.cancel_button);
+        if (cancelBtn != null) {
+            cancelBtn.setOnClickListener(view -> {
+                mCallback.reset();
+            });
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
index 75c52d8..7cc37c4 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java
@@ -205,6 +205,13 @@
             }
         });
 
+        View cancelBtn = findViewById(R.id.cancel_button);
+        if (cancelBtn != null) {
+            cancelBtn.setOnClickListener(view -> {
+                mCallback.reset();
+            });
+        }
+
         // If there's more than one IME, enable the IME switcher button
         updateSwitchImeButton();
 
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index 651831e..174dcab 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -157,6 +157,13 @@
         if (button != null) {
             button.setCallback(this);
         }
+
+        View cancelBtn = findViewById(R.id.cancel_button);
+        if (cancelBtn != null) {
+            cancelBtn.setOnClickListener(view -> {
+                mCallback.reset();
+            });
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 0ba26e9..c01cafa 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -25,6 +25,7 @@
 
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.Dependency.DependencyProvider;
 import com.android.systemui.classifier.FalsingManager;
@@ -101,12 +102,13 @@
                 dismissCallbackRegistry, FalsingManager.getInstance(context));
     }
 
-    public ScrimController createScrimController(LightBarController lightBarController,
-            ScrimView scrimBehind, ScrimView scrimInFront, LockscreenWallpaper lockscreenWallpaper,
+    public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+            LockscreenWallpaper lockscreenWallpaper, Consumer<Float> scrimBehindAlphaListener,
+            Consumer<GradientColors> scrimInFrontColorListener,
             Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
             AlarmManager alarmManager) {
-        return new ScrimController(lightBarController, scrimBehind, scrimInFront,
-                scrimVisibleListener, dozeParameters, alarmManager);
+        return new ScrimController(scrimBehind, scrimInFront, scrimBehindAlphaListener,
+                scrimInFrontColorListener, scrimVisibleListener, dozeParameters, alarmManager);
     }
 
     public NotificationIconAreaController createNotificationIconAreaController(Context context,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index 7161463..101c790 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -16,17 +16,19 @@
 
 package com.android.systemui.qs;
 
+import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Point;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.widget.FrameLayout;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.R;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.statusbar.CommandQueue;
 
 /**
  * Wrapper view with background which contains {@link QSPanel} and {@link BaseStatusBarHeader}
@@ -48,6 +50,7 @@
     private View mStatusBarBackground;
 
     private int mSideMargins;
+    private boolean mQsDisabled;
 
     public QSContainerImpl(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -96,6 +99,16 @@
 
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (mQsDisabled) {
+            // Only show the status bar contents in QQS header when QS is disabled.
+            mHeader.measure(widthMeasureSpec, heightMeasureSpec);
+            LayoutParams layoutParams = (LayoutParams) mHeader.getLayoutParams();
+            int height = layoutParams.topMargin + layoutParams.bottomMargin
+                    + mHeader.getMeasuredHeight();
+            super.onMeasure(
+                    widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+            return;
+        }
         // Since we control our own bottom, be whatever size we want.
         // Otherwise the QSPanel ends up with 0 height when the window is only the
         // size of the status bar.
@@ -121,6 +134,15 @@
         updateExpansion();
     }
 
+    public void disable(int state1, int state2, boolean animate) {
+        final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
+        if (disabled == mQsDisabled) return;
+        mQsDisabled = disabled;
+        mBackgroundGradient.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        mQSPanel.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        mQSFooter.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+    }
+
     private void updateResources() {
         LayoutParams layoutParams = (LayoutParams) mQSPanel.getLayoutParams();
         layoutParams.topMargin = mContext.getResources().getDimensionPixelSize(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 3f3cea2..6c7eda7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -69,4 +69,6 @@
      */
     @Nullable
     View getExpandView();
+
+    default void disable(int state1, int state2, boolean animate) {}
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
index 0fa6597..cf549fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterImpl.java
@@ -47,10 +47,8 @@
 import com.android.systemui.Dependency;
 import com.android.systemui.R;
 import com.android.systemui.R.dimen;
-import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.ActivityStarter;
 import com.android.systemui.qs.TouchAnimator.Builder;
-import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.MultiUserSwitch;
 import com.android.systemui.statusbar.phone.SettingsButton;
 import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -62,8 +60,7 @@
 import com.android.systemui.tuner.TunerService;
 
 public class QSFooterImpl extends FrameLayout implements QSFooter,
-        OnClickListener, OnUserInfoChangedListener, EmergencyListener,
-        SignalCallback, CommandQueue.Callbacks {
+        OnClickListener, OnUserInfoChangedListener, EmergencyListener, SignalCallback {
 
     private ActivityStarter mActivityStarter;
     private UserInfoController mUserInfoController;
@@ -211,16 +208,9 @@
     }
 
     @Override
-    public void onAttachedToWindow() {
-        super.onAttachedToWindow();
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
-    }
-
-    @Override
     @VisibleForTesting
     public void onDetachedFromWindow() {
         setListening(false);
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
         super.onDetachedFromWindow();
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 018a635..cb068e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -14,9 +14,12 @@
 
 package com.android.systemui.qs;
 
+import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.app.Fragment;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -35,12 +38,14 @@
 import com.android.systemui.Interpolators;
 import com.android.systemui.R;
 import com.android.systemui.R.id;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.qs.customize.QSCustomizer;
+import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
 import com.android.systemui.statusbar.stack.StackStateAnimator;
 
-public class QSFragment extends Fragment implements QS {
+public class QSFragment extends Fragment implements QS, CommandQueue.Callbacks {
     private static final String TAG = "QS";
     private static final boolean DEBUG = false;
     private static final String EXTRA_EXPANDED = "expanded";
@@ -65,6 +70,7 @@
     private int mLayoutDirection;
     private QSFooter mFooter;
     private float mLastQSExpansion = -1;
+    private boolean mQsDisabled;
 
     @Override
     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -176,6 +182,17 @@
         }
     }
 
+    @Override
+    public void disable(int state1, int state2, boolean animate) {
+        final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
+        if (disabled == mQsDisabled) return;
+        mQsDisabled = disabled;
+        mContainer.disable(state1, state2, animate);
+        mHeader.disable(state1, state2, animate);
+        mFooter.disable(state1, state2, animate);
+        updateQsState();
+    }
+
     private void updateQsState() {
         final boolean expandVisually = mQsExpanded || mStackScrollerOverscrolling
                 || mHeaderAnimating;
@@ -189,6 +206,9 @@
         mFooter.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
                 ? View.VISIBLE
                 : View.INVISIBLE);
+        if (mQsDisabled) {
+            mFooter.setVisibility(View.GONE);
+        }
         mFooter.setExpanded((mKeyguardShowing && !mHeaderAnimating)
                 || (mQsExpanded && !mStackScrollerOverscrolling));
         mQSPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
@@ -258,6 +278,12 @@
         mHeader.setListening(listening);
         mFooter.setListening(listening);
         mQSPanel.setListening(mListening && mQsExpanded);
+        if (listening) {
+            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
+        } else {
+            SysUiServiceProvider.getComponent(getContext(), CommandQueue.class)
+                    .removeCallbacks(this);
+        }
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index 70bfad1..e2af90d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -68,7 +68,7 @@
  * battery) and also contains the {@link QuickQSPanel} along with some of the panel's inner
  * contents.
  */
-public class QuickStatusBarHeader extends RelativeLayout implements CommandQueue.Callbacks,
+public class QuickStatusBarHeader extends RelativeLayout implements
         View.OnClickListener, NextAlarmController.NextAlarmChangeCallback {
     private static final String TAG = "QuickStatusBarHeader";
     private static final boolean DEBUG = false;
@@ -249,8 +249,9 @@
                 com.android.internal.R.dimen.quick_qs_offset_height);
         mSystemIconsView.setLayoutParams(mSystemIconsView.getLayoutParams());
 
-        getLayoutParams().height =
-                resources.getDimensionPixelSize(com.android.internal.R.dimen.quick_qs_total_height);
+        getLayoutParams().height = resources.getDimensionPixelSize(mQsDisabled
+                ? com.android.internal.R.dimen.quick_qs_offset_height
+                : com.android.internal.R.dimen.quick_qs_total_height);
         setLayoutParams(getLayoutParams());
 
         updateStatusIconAlphaAnimator();
@@ -320,20 +321,18 @@
                 TOOLTIP_NOT_YET_SHOWN_COUNT);
     }
 
-    @Override
     public void disable(int state1, int state2, boolean animate) {
         final boolean disabled = (state2 & DISABLE2_QUICK_SETTINGS) != 0;
         if (disabled == mQsDisabled) return;
         mQsDisabled = disabled;
         mHeaderQsPanel.setDisabledByPolicy(disabled);
-        final int rawHeight = (int) getResources().getDimension(
-                com.android.internal.R.dimen.quick_qs_total_height);
-        getLayoutParams().height = disabled ? (rawHeight - mHeaderQsPanel.getHeight()) : rawHeight;
+        mHeaderTextContainerView.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        mQuickQsStatusIcons.setVisibility(mQsDisabled ? View.GONE : View.VISIBLE);
+        updateResources();
     }
 
     @Override
     public void onAttachedToWindow() {
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).addCallbacks(this);
         Dependency.get(StatusBarIconController.class).addIconGroup(mIconManager);
         requestApplyInsets();
     }
@@ -354,7 +353,6 @@
     @VisibleForTesting
     public void onDetachedFromWindow() {
         setListening(false);
-        SysUiServiceProvider.getComponent(getContext(), CommandQueue.class).removeCallbacks(this);
         Dependency.get(StatusBarIconController.class).removeIconGroup(mIconManager);
         super.onDetachedFromWindow();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index 75bc9558..30e9afd8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -21,7 +21,6 @@
 
 import android.annotation.TargetApi;
 import android.app.ActivityManager;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -62,6 +61,7 @@
 
     private static final String TAG = "RecentsOnboarding";
     private static final boolean RESET_PREFS_FOR_DEBUG = false;
+    private static final boolean ONBOARDING_ENABLED = false;
     private static final long SHOW_DELAY_MS = 500;
     private static final long SHOW_HIDE_DURATION_MS = 300;
     // Don't show the onboarding until the user has launched this number of apps.
@@ -184,6 +184,9 @@
     }
 
     public void onConnectedToLauncher() {
+        if (!ONBOARDING_ENABLED) {
+            return;
+        }
         boolean alreadySeenRecentsOnboarding = Prefs.getBoolean(mContext,
                 Prefs.Key.HAS_SEEN_RECENTS_ONBOARDING, false);
         if (!mTaskListenerRegistered && !alreadySeenRecentsOnboarding) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index b81e9af..29c2edc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -26,6 +26,7 @@
 import android.util.ArraySet;
 import android.util.AttributeSet;
 import android.util.Log;
+import android.view.MotionEvent;
 import android.view.NotificationHeaderView;
 import android.view.View;
 import android.view.ViewGroup;
@@ -1631,6 +1632,42 @@
         return null;
     }
 
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        float y = ev.getY();
+        // We still want to distribute touch events to the remote input even if it's outside the
+        // view boundary. We're therefore manually dispatching these events to the remote view
+        RemoteInputView riv = getRemoteInputForView(getViewForVisibleType(mVisibleType));
+        if (riv != null && riv.getVisibility() == VISIBLE) {
+            int inputStart = mUnrestrictedContentHeight - riv.getHeight();
+            if (y <= mUnrestrictedContentHeight && y >= inputStart) {
+                ev.offsetLocation(0, -inputStart);
+                return riv.dispatchTouchEvent(ev);
+            }
+        }
+        return super.dispatchTouchEvent(ev);
+    }
+
+    /**
+     * Overridden to make sure touches to the reply action bar actually go through to this view
+     */
+    @Override
+    public boolean pointInView(float localX, float localY, float slop) {
+        float top = mClipTopAmount;
+        float bottom = mUnrestrictedContentHeight;
+        return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
+                localY < (bottom + slop);
+    }
+
+    private RemoteInputView getRemoteInputForView(View child) {
+        if (child == mExpandedChild) {
+            return mExpandedRemoteInput;
+        } else if (child == mHeadsUpChild) {
+            return mHeadsUpRemoteInput;
+        }
+        return null;
+    }
+
     public int getExpandHeight() {
         int viewType = VISIBLE_TYPE_EXPANDED;
         if (mExpandedChild == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index a93be00..6238526 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -308,15 +308,15 @@
             minimize.setVisibility(GONE);
         }
 
-        // Set up app settings link
+        // Set up app settings link (i.e. Customize)
         TextView settingsLinkView = findViewById(R.id.app_settings);
         Intent settingsIntent = getAppSettingsIntent(mPm, mPkg, mSingleNotificationChannel,
                 mSbn.getId(), mSbn.getTag());
-        if (settingsIntent != null
+        if (!mIsForBlockingHelper
+                && settingsIntent != null
                 && !TextUtils.isEmpty(mSbn.getNotification().getSettingsText())) {
             settingsLinkView.setVisibility(VISIBLE);
-            settingsLinkView.setText(mContext.getString(R.string.notification_app_settings,
-                    mSbn.getNotification().getSettingsText()));
+            settingsLinkView.setText(mContext.getString(R.string.notification_app_settings));
             settingsLinkView.setOnClickListener((View view) -> {
                 mAppSettingsClickListener.onClick(view, settingsIntent);
             });
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
index e248db4..ec243fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationButton.java
@@ -24,8 +24,8 @@
     private String mLongIntent;
     private boolean mBroadcastIntent;
     private boolean mSelected = false;
-    private float mSelectedAlpha;
-    private float mUnselectedAlpha;
+    private float mSelectedAlpha = 1f;
+    private float mUnselectedAlpha = 1f;
     private int mSelectedIconResourceId;
     private int mIconResourceId;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 2c335a3..cc143bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -111,7 +111,6 @@
     private final Context mContext;
     protected final ScrimView mScrimBehind;
     protected final ScrimView mScrimInFront;
-    private final LightBarController mLightBarController;
     private final UnlockMethodCache mUnlockMethodCache;
     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     private final DozeParameters mDozeParameters;
@@ -145,6 +144,8 @@
     private int mCurrentBehindTint;
     private boolean mWallpaperVisibilityTimedOut;
     private int mScrimsVisibility;
+    private final Consumer<GradientColors> mScrimInFrontColorListener;
+    private final Consumer<Float> mScrimBehindAlphaListener;
     private final Consumer<Integer> mScrimVisibleListener;
     private boolean mBlankScreen;
     private boolean mScreenBlankingCallbackCalled;
@@ -161,17 +162,20 @@
     private boolean mWakeLockHeld;
     private boolean mKeyguardOccluded;
 
-    public ScrimController(LightBarController lightBarController, ScrimView scrimBehind,
-            ScrimView scrimInFront, Consumer<Integer> scrimVisibleListener,
-            DozeParameters dozeParameters, AlarmManager alarmManager) {
+    public ScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+            Consumer<Float> scrimBehindAlphaListener,
+            Consumer<GradientColors> scrimInFrontColorListener,
+            Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
+            AlarmManager alarmManager) {
         mScrimBehind = scrimBehind;
         mScrimInFront = scrimInFront;
+        mScrimBehindAlphaListener = scrimBehindAlphaListener;
+        mScrimInFrontColorListener = scrimInFrontColorListener;
         mScrimVisibleListener = scrimVisibleListener;
         mContext = scrimBehind.getContext();
         mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
         mDarkenWhileDragging = !mUnlockMethodCache.canSkipBouncer();
         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
-        mLightBarController = lightBarController;
         mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
         mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
                 "hide_aod_wallpaper", new Handler());
@@ -370,6 +374,8 @@
 
             setOrAdaptCurrentAnimation(mScrimBehind);
             setOrAdaptCurrentAnimation(mScrimInFront);
+
+            mScrimBehindAlphaListener.accept(mScrimBehind.getViewAlpha());
         }
     }
 
@@ -478,7 +484,7 @@
             float minOpacity = ColorUtils.calculateMinimumBackgroundAlpha(textColor, mainColor,
                     4.5f /* minimumContrast */) / 255f;
             mScrimBehindAlpha = Math.max(mScrimBehindAlphaResValue, minOpacity);
-            mLightBarController.setScrimColor(mScrimInFront.getColors());
+            mScrimInFrontColorListener.accept(mScrimInFront.getColors());
         }
 
         // We want to override the back scrim opacity for the AOD state
@@ -705,9 +711,8 @@
             }
         }
 
-        // TODO factor mLightBarController out of this class
         if (scrim == mScrimBehind) {
-            mLightBarController.setScrimAlpha(alpha);
+            mScrimBehindAlphaListener.accept(alpha);
         }
 
         final boolean wantsAlphaUpdate = alpha != currentAlpha;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 9c5cf306..0072dc0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -916,8 +916,14 @@
 
         ScrimView scrimBehind = mStatusBarWindow.findViewById(R.id.scrim_behind);
         ScrimView scrimInFront = mStatusBarWindow.findViewById(R.id.scrim_in_front);
-        mScrimController = SystemUIFactory.getInstance().createScrimController(mLightBarController,
+        mScrimController = SystemUIFactory.getInstance().createScrimController(
                 scrimBehind, scrimInFront, mLockscreenWallpaper,
+                scrimBehindAlpha -> {
+                    mLightBarController.setScrimAlpha(scrimBehindAlpha);
+                },
+                scrimInFrontColor -> {
+                    mLightBarController.setScrimColor(scrimInFrontColor);
+                },
                 scrimsVisible -> {
                     if (mStatusBarWindowManager != null) {
                         mStatusBarWindowManager.setScrimsVisibility(scrimsVisible);
@@ -1428,13 +1434,13 @@
     }
 
     public void addQsTile(ComponentName tile) {
-        if (mQSPanel.getHost() != null) {
+        if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().addTile(tile);
         }
     }
 
     public void remQsTile(ComponentName tile) {
-        if (mQSPanel.getHost() != null) {
+        if (mQSPanel != null && mQSPanel.getHost() != null) {
             mQSPanel.getHost().removeTile(tile);
         }
     }
@@ -4998,6 +5004,14 @@
 
     @Override
     public void onNotificationClicked(StatusBarNotification sbn, ExpandableNotificationRow row) {
+        RemoteInputController controller = mRemoteInputManager.getController();
+        if (controller.isRemoteInputActive(row.getEntry())
+                && !TextUtils.isEmpty(row.getActiveRemoteInputText())) {
+            // We have an active remote input typed and the user clicked on the notification.
+            // this was probably unintentional, so we're closing the edit text instead.
+            controller.closeRemoteInputs();
+            return;
+        }
         Notification notification = sbn.getNotification();
         final PendingIntent intent = notification.contentIntent != null
                 ? notification.contentIntent
@@ -5061,12 +5075,7 @@
                     Intent fillInIntent = null;
                     Entry entry = row.getEntry();
                     CharSequence remoteInputText = null;
-                    RemoteInputController controller = mRemoteInputManager.getController();
-                    if (controller.isRemoteInputActive(entry)) {
-                        remoteInputText = row.getActiveRemoteInputText();
-                    }
-                    if (TextUtils.isEmpty(remoteInputText)
-                            && !TextUtils.isEmpty(entry.remoteInputText)) {
+                    if (!TextUtils.isEmpty(entry.remoteInputText)) {
                         remoteInputText = entry.remoteInputText;
                     }
                     if (!TextUtils.isEmpty(remoteInputText)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index baeaaad..9aa8044 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -16,9 +16,6 @@
 
 package com.android.systemui.statusbar.policy;
 
-import libcore.icu.LocaleData;
-
-import android.app.ActivityManager;
 import android.app.StatusBarManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -46,6 +43,7 @@
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.R;
 import com.android.systemui.SysUiServiceProvider;
+import com.android.systemui.settings.CurrentUserTracker;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.phone.StatusBarIconController;
 import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -53,6 +51,8 @@
 import com.android.systemui.tuner.TunerService;
 import com.android.systemui.tuner.TunerService.Tunable;
 
+import libcore.icu.LocaleData;
+
 import java.text.SimpleDateFormat;
 import java.util.Calendar;
 import java.util.Locale;
@@ -66,6 +66,9 @@
 
     public static final String CLOCK_SECONDS = "clock_seconds";
 
+    private final CurrentUserTracker mCurrentUserTracker;
+    private int mCurrentUserId;
+
     private boolean mClockVisibleByPolicy = true;
     private boolean mClockVisibleByUser = true;
 
@@ -117,6 +120,12 @@
         } finally {
             a.recycle();
         }
+        mCurrentUserTracker = new CurrentUserTracker(context) {
+            @Override
+            public void onUserSwitched(int newUserId) {
+                mCurrentUserId = newUserId;
+            }
+        };
     }
 
     @Override
@@ -141,6 +150,8 @@
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).addDarkReceiver(this);
             }
+            mCurrentUserTracker.startTracking();
+            mCurrentUserId = mCurrentUserTracker.getCurrentUserId();
         }
 
         // NOTE: It's safe to do these after registering the receiver since the receiver always runs
@@ -166,6 +177,7 @@
             if (mShowDark) {
                 Dependency.get(DarkIconDispatcher.class).removeDarkReceiver(this);
             }
+            mCurrentUserTracker.stopTracking();
         }
     }
 
@@ -302,7 +314,7 @@
 
     private final CharSequence getSmallTime() {
         Context context = getContext();
-        boolean is24 = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser());
+        boolean is24 = DateFormat.is24HourFormat(context, mCurrentUserId);
         LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
 
         final char MAGIC1 = '\uEF00';
@@ -392,8 +404,7 @@
             } else if (hhmm != null && hhmm.length() == 4) {
                 int hh = Integer.parseInt(hhmm.substring(0, 2));
                 int mm = Integer.parseInt(hhmm.substring(2));
-                boolean is24 = DateFormat.is24HourFormat(
-                        getContext(), ActivityManager.getCurrentUser());
+                boolean is24 = DateFormat.is24HourFormat(getContext(), mCurrentUserId);
                 if (is24) {
                     mCalendar.set(Calendar.HOUR_OF_DAY, hh);
                 } else {
diff --git a/packages/SystemUI/tests/AndroidTest.xml b/packages/SystemUI/tests/AndroidTest.xml
index 53839a9b..fc353a1 100644
--- a/packages/SystemUI/tests/AndroidTest.xml
+++ b/packages/SystemUI/tests/AndroidTest.xml
@@ -24,5 +24,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.systemui.tests" />
         <option name="runner" value="android.testing.TestableInstrumentation" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index d86e947..658ac73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -696,6 +696,29 @@
         assertEquals(GONE, settingsLink.getVisibility());
     }
 
+    @Test
+    public void testBindHeader_noSettingsLinkWhenIsForBlockingHelper() throws Exception {
+        final String settingsText = "work chats";
+        final ResolveInfo ri = new ResolveInfo();
+        ri.activityInfo = new ActivityInfo();
+        ri.activityInfo.packageName = TEST_PACKAGE_NAME;
+        ri.activityInfo.name = "something";
+        List<ResolveInfo> ris = new ArrayList<>();
+        ris.add(ri);
+        when(mMockPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(ris);
+        mNotificationChannel.setImportance(IMPORTANCE_LOW);
+        Notification n = new Notification.Builder(mContext, mNotificationChannel.getId())
+                .setSettingsText(settingsText).build();
+        StatusBarNotification sbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME,
+                0, null, 0, 0, n, UserHandle.CURRENT, null, 0);
+
+        mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+                TEST_PACKAGE_NAME, mNotificationChannel, 1, sbn, null, null, null, false, true,
+                true);
+        final TextView settingsLink = mNotificationInfo.findViewById(R.id.app_settings);
+        assertEquals(GONE, settingsLink.getVisibility());
+    }
+
 
     @Test
     public void testWillBeRemovedReturnsFalseBeforeBind() throws Exception {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index 82129a1..0416232 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -42,6 +42,7 @@
 import android.testing.TestableLooper;
 import android.view.View;
 
+import com.android.internal.colorextraction.ColorExtractor.GradientColors;
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.statusbar.ScrimView;
@@ -65,9 +66,12 @@
     private SynchronousScrimController mScrimController;
     private ScrimView mScrimBehind;
     private ScrimView mScrimInFront;
+    private Consumer<Float> mScrimBehindAlphaCallback;
+    private Consumer<GradientColors> mScrimInFrontColorCallback;
     private Consumer<Integer> mScrimVisibilityCallback;
+    private float mScrimBehindAlpha;
+    private GradientColors mScrimInFrontColor;
     private int mScrimVisibility;
-    private LightBarController mLightBarController;
     private DozeParameters mDozeParamenters;
     private WakeLock mWakeLock;
     private boolean mAlwaysOnEnabled;
@@ -75,19 +79,20 @@
 
     @Before
     public void setup() {
-        mLightBarController = mock(LightBarController.class);
         mScrimBehind = spy(new ScrimView(getContext()));
         mScrimInFront = new ScrimView(getContext());
         mWakeLock = mock(WakeLock.class);
         mAlarmManager = mock(AlarmManager.class);
         mAlwaysOnEnabled = true;
+        mScrimBehindAlphaCallback = (Float alpha) -> mScrimBehindAlpha = alpha;
+        mScrimInFrontColorCallback = (GradientColors color) -> mScrimInFrontColor = color;
         mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible;
         mDozeParamenters = mock(DozeParameters.class);
         when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
         when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
-        mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind,
-                mScrimInFront, mScrimVisibilityCallback, mDozeParamenters,
-                mAlarmManager);
+        mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
+                mScrimBehindAlphaCallback, mScrimInFrontColorCallback, mScrimVisibilityCallback,
+                mDozeParamenters, mAlarmManager);
     }
 
     @Test
@@ -206,6 +211,28 @@
     }
 
     @Test
+    public void panelExpansion() {
+        mScrimController.setPanelExpansion(0f);
+        mScrimController.setPanelExpansion(0.5f);
+        mScrimController.transitionTo(ScrimState.UNLOCKED);
+        mScrimController.finishAnimationsImmediately();
+
+        reset(mScrimBehind);
+        mScrimController.setPanelExpansion(0f);
+        mScrimController.setPanelExpansion(1.0f);
+        mScrimController.onPreDraw();
+
+        Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
+                mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
+
+        mScrimController.setPanelExpansion(0f);
+        mScrimController.onPreDraw();
+
+        Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
+                mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
+    }
+
+    @Test
     public void panelExpansionAffectsAlpha() {
         mScrimController.setPanelExpansion(0f);
         mScrimController.setPanelExpansion(0.5f);
@@ -531,11 +558,12 @@
         private boolean mAnimationCancelled;
         boolean mOnPreDrawCalled;
 
-        SynchronousScrimController(LightBarController lightBarController,
-                ScrimView scrimBehind, ScrimView scrimInFront,
+        SynchronousScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
+                Consumer<Float> scrimBehindAlphaListener,
+                Consumer<GradientColors> scrimInFrontColorListener,
                 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
                 AlarmManager alarmManager) {
-            super(lightBarController, scrimBehind, scrimInFront,
+            super(scrimBehind, scrimInFront, scrimBehindAlphaListener, scrimInFrontColorListener,
                     scrimVisibleListener, dozeParameters, alarmManager);
             mHandler = new FakeHandler(Looper.myLooper());
         }
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index b6ac3fb..446c0a1 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -4779,7 +4779,7 @@
     // CATEGORY: SETTINGS
     ACTION_MOBILE_NETWORK_MANUAL_SELECT_NETWORK = 1210;
 
-    // FIELD - Manually selected mobile network
+    // Not used anymore.
     FIELD_MOBILE_NETWORK = 1211;
 
     // OPEN: Settings > Network & Internet > Mobile network > Access Point Names
@@ -5583,6 +5583,36 @@
     // OS: P
     SETTINGS_GESTURE_SWIPE_UP = 1374;
 
+    // OPEN: Settings > Storage > Dialog to format a storage volume
+    // CATEGORY: SETTINGS
+    // OS: P
+    DIALOG_VOLUME_FORMAT = 1375;
+
+    // OPEN: DND onboarding activity > screen on checkbox
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ONBOARDING_SCREEN_ON = 1376;
+
+    // OPEN: DND onboarding activity > screen off checkbox
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ONBOARDING_SCREEN_OFF = 1377;
+
+    // OPEN: DND onboarding activity > Ok button
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ONBOARDING_OK = 1378;
+
+    // OPEN: DND onboarding activity > Settings link
+    // CATEGORY: SETTINGS
+    // OS: P
+    ACTION_ZEN_ONBOARDING_SETTINGS = 1379;
+
+    // OPEN: DND onboarding activity
+    // CATEGORY: SETTINGS
+    // OS: P
+    SETTINGS_ZEN_ONBOARDING = 1380;
+
     // ---- End P Constants, all P constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 59cb135..6463bed 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -52,6 +52,8 @@
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.PacketKeepalive;
 import android.net.IConnectivityManager;
+import android.net.IIpConnectivityMetrics;
+import android.net.INetdEventCallback;
 import android.net.INetworkManagementEventObserver;
 import android.net.INetworkPolicyListener;
 import android.net.INetworkPolicyManager;
@@ -140,6 +142,7 @@
 import com.android.server.connectivity.DataConnectionStats;
 import com.android.server.connectivity.DnsManager;
 import com.android.server.connectivity.DnsManager.PrivateDnsConfig;
+import com.android.server.connectivity.DnsManager.PrivateDnsValidationUpdate;
 import com.android.server.connectivity.IpConnectivityMetrics;
 import com.android.server.connectivity.KeepaliveTracker;
 import com.android.server.connectivity.LingerMonitor;
@@ -155,6 +158,7 @@
 import com.android.server.connectivity.Tethering;
 import com.android.server.connectivity.Vpn;
 import com.android.server.connectivity.tethering.TetheringDependencies;
+import com.android.server.net.BaseNetdEventCallback;
 import com.android.server.net.BaseNetworkObserver;
 import com.android.server.net.LockdownVpnTracker;
 import com.android.server.net.NetworkPolicyManagerInternal;
@@ -256,6 +260,7 @@
     private INetworkStatsService mStatsService;
     private INetworkPolicyManager mPolicyManager;
     private NetworkPolicyManagerInternal mPolicyManagerInternal;
+    private IIpConnectivityMetrics mIpConnectivityMetrics;
 
     private String mCurrentTcpBufferSizes;
 
@@ -414,6 +419,9 @@
     // Handle changes in Private DNS settings.
     private static final int EVENT_PRIVATE_DNS_SETTINGS_CHANGED = 37;
 
+    // Handle private DNS validation status updates.
+    private static final int EVENT_PRIVATE_DNS_VALIDATION_UPDATE = 38;
+
     private static String eventName(int what) {
         return sMagicDecoderRing.get(what, Integer.toString(what));
     }
@@ -1553,6 +1561,41 @@
         return true;
     }
 
+    @VisibleForTesting
+    protected final INetdEventCallback mNetdEventCallback = new BaseNetdEventCallback() {
+        @Override
+        public void onPrivateDnsValidationEvent(int netId, String ipAddress,
+                String hostname, boolean validated) {
+            try {
+                mHandler.sendMessage(mHandler.obtainMessage(
+                        EVENT_PRIVATE_DNS_VALIDATION_UPDATE,
+                        new PrivateDnsValidationUpdate(netId,
+                                InetAddress.parseNumericAddress(ipAddress),
+                                hostname, validated)));
+            } catch (IllegalArgumentException e) {
+                loge("Error parsing ip address in validation event");
+            }
+        }
+    };
+
+    @VisibleForTesting
+    protected void registerNetdEventCallback() {
+        mIpConnectivityMetrics =
+                (IIpConnectivityMetrics) IIpConnectivityMetrics.Stub.asInterface(
+                ServiceManager.getService(IpConnectivityLog.SERVICE_NAME));
+        if (mIpConnectivityMetrics == null) {
+            Slog.wtf(TAG, "Missing IIpConnectivityMetrics");
+        }
+
+        try {
+            mIpConnectivityMetrics.addNetdEventCallback(
+                    INetdEventCallback.CALLBACK_CALLER_CONNECTIVITY_SERVICE,
+                    mNetdEventCallback);
+        } catch (Exception e) {
+            loge("Error registering netd callback: " + e);
+        }
+    }
+
     private final INetworkPolicyListener mPolicyListener = new NetworkPolicyManager.Listener() {
         @Override
         public void onUidRulesChanged(int uid, int uidRules) {
@@ -1738,6 +1781,7 @@
 
     void systemReady() {
         loadGlobalProxy();
+        registerNetdEventCallback();
 
         synchronized (this) {
             mSystemReady = true;
@@ -2288,6 +2332,9 @@
 
         for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) {
             handlePerNetworkPrivateDnsConfig(nai, cfg);
+            if (networkRequiresValidation(nai)) {
+                handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
+            }
         }
     }
 
@@ -2312,6 +2359,15 @@
         updateDnses(nai.linkProperties, null, nai.network.netId);
     }
 
+    private void handlePrivateDnsValidationUpdate(PrivateDnsValidationUpdate update) {
+        NetworkAgentInfo nai = getNetworkAgentInfoForNetId(update.netId);
+        if (nai == null) {
+            return;
+        }
+        mDnsManager.updatePrivateDnsValidation(update);
+        handleUpdateLinkProperties(nai, new LinkProperties(nai.linkProperties));
+    }
+
     private void updateLingerState(NetworkAgentInfo nai, long now) {
         // 1. Update the linger timer. If it's changed, reschedule or cancel the alarm.
         // 2. If the network was lingering and there are now requests, unlinger it.
@@ -3002,6 +3058,10 @@
                 case EVENT_PRIVATE_DNS_SETTINGS_CHANGED:
                     handlePrivateDnsSettingsChanged();
                     break;
+                case EVENT_PRIVATE_DNS_VALIDATION_UPDATE:
+                    handlePrivateDnsValidationUpdate(
+                            (PrivateDnsValidationUpdate) msg.obj);
+                    break;
             }
         }
     }
@@ -4575,6 +4635,11 @@
 
         updateRoutes(newLp, oldLp, netId);
         updateDnses(newLp, oldLp, netId);
+        // Make sure LinkProperties represents the latest private DNS status.
+        // This does not need to be done before updateDnses because the
+        // LinkProperties are not the source of the private DNS configuration.
+        // updateDnses will fetch the private DNS configuration from DnsManager.
+        mDnsManager.updatePrivateDnsStatus(netId, newLp);
 
         // Start or stop clat accordingly to network state.
         networkAgent.updateClat(mNetd);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 75bad46..04d54e1 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -52,6 +52,7 @@
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
+import static android.content.pm.ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
@@ -118,6 +119,7 @@
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
+import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
 import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
 import static android.provider.Settings.System.FONT_SCALE;
@@ -1282,17 +1284,24 @@
 
     private final class FontScaleSettingObserver extends ContentObserver {
         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
+        private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
 
         public FontScaleSettingObserver() {
             super(mHandler);
             ContentResolver resolver = mContext.getContentResolver();
             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
+            resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
+                    UserHandle.USER_ALL);
         }
 
         @Override
         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
             if (mFontScaleUri.equals(uri)) {
                 updateFontScaleIfNeeded(userId);
+            } else if (mHideErrorDialogsUri.equals(uri)) {
+                synchronized (ActivityManagerService.this) {
+                    updateShouldShowDialogsLocked(getGlobalConfiguration());
+                }
             }
         }
     }
@@ -1949,7 +1958,7 @@
     final ActivityManagerConstants mConstants;
 
     // Encapsulates the global setting "hidden_api_blacklist_exemptions"
-    final HiddenApiBlacklist mHiddenApiBlacklist;
+    final HiddenApiSettings mHiddenApiBlacklist;
 
     PackageManagerInternal mPackageManagerInt;
 
@@ -2884,17 +2893,19 @@
     }
 
     /**
-     * Encapsulates the global setting "hidden_api_blacklist_exemptions", including tracking the
-     * latest value via a content observer.
+     * Encapsulates global settings related to hidden API enforcement behaviour, including tracking
+     * the latest value via a content observer.
      */
-    static class HiddenApiBlacklist extends ContentObserver {
+    static class HiddenApiSettings extends ContentObserver {
 
         private final Context mContext;
         private boolean mBlacklistDisabled;
         private String mExemptionsStr;
         private List<String> mExemptions = Collections.emptyList();
+        @HiddenApiEnforcementPolicy private int mPolicyPreP = HIDDEN_API_ENFORCEMENT_DEFAULT;
+        @HiddenApiEnforcementPolicy private int mPolicyP = HIDDEN_API_ENFORCEMENT_DEFAULT;
 
-        public HiddenApiBlacklist(Handler handler, Context context) {
+        public HiddenApiSettings(Handler handler, Context context) {
             super(handler);
             mContext = context;
         }
@@ -2904,6 +2915,14 @@
                     Settings.Global.getUriFor(Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS),
                     false,
                     this);
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS),
+                    false,
+                    this);
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(Settings.Global.HIDDEN_API_POLICY_P_APPS),
+                    false,
+                    this);
             update();
         }
 
@@ -2923,13 +2942,32 @@
                 }
                 zygoteProcess.setApiBlacklistExemptions(mExemptions);
             }
+            mPolicyPreP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_PRE_P_APPS);
+            mPolicyP = getValidEnforcementPolicy(Settings.Global.HIDDEN_API_POLICY_P_APPS);
+        }
 
+        private @HiddenApiEnforcementPolicy int getValidEnforcementPolicy(String settingsKey) {
+            int policy = Settings.Global.getInt(mContext.getContentResolver(), settingsKey,
+                    ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT);
+            if (ApplicationInfo.isValidHiddenApiEnforcementPolicy(policy)) {
+                return policy;
+            } else {
+                return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT;
+            }
         }
 
         boolean isDisabled() {
             return mBlacklistDisabled;
         }
 
+        @HiddenApiEnforcementPolicy int getPolicyForPrePApps() {
+            return mPolicyPreP;
+        }
+
+        @HiddenApiEnforcementPolicy int getPolicyForPApps() {
+            return mPolicyP;
+        }
+
         public void onChange(boolean selfChange) {
             update();
         }
@@ -3102,7 +3140,7 @@
             }
         };
 
-        mHiddenApiBlacklist = new HiddenApiBlacklist(mHandler, mContext);
+        mHiddenApiBlacklist = new HiddenApiSettings(mHandler, mContext);
 
         Watchdog.getInstance().addMonitor(this);
         Watchdog.getInstance().addThread(mHandler);
@@ -4218,6 +4256,9 @@
             }
 
             if (!disableHiddenApiChecks && !mHiddenApiBlacklist.isDisabled()) {
+                app.info.maybeUpdateHiddenApiEnforcementPolicy(
+                        mHiddenApiBlacklist.getPolicyForPrePApps(),
+                        mHiddenApiBlacklist.getPolicyForPApps());
                 @HiddenApiEnforcementPolicy int policy =
                         app.info.getHiddenApiEnforcementPolicy();
                 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT);
@@ -22449,7 +22490,7 @@
                 mUserController.getCurrentUserId());
 
         // TODO: If our config changes, should we auto dismiss any currently showing dialogs?
-        mShowDialogs = shouldShowDialogs(mTempConfig);
+        updateShouldShowDialogsLocked(mTempConfig);
 
         AttributeCache ac = AttributeCache.instance();
         if (ac != null) {
@@ -22704,7 +22745,7 @@
      * A thought: SystemUI might also want to get told about this, the Power
      * dialog / global actions also might want different behaviors.
      */
-    private static boolean shouldShowDialogs(Configuration config) {
+    private void updateShouldShowDialogsLocked(Configuration config) {
         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
                                    && config.navigation == Configuration.NAVIGATION_NONAV);
@@ -22713,7 +22754,9 @@
                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
                 && modeType != Configuration.UI_MODE_TYPE_TELEVISION
                 && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
-        return inputMethodExists && uiModeSupportsDialogs;
+        final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
+                HIDE_ERROR_DIALOGS, 0) != 0;
+        mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/am/RecentTasks.java b/services/core/java/com/android/server/am/RecentTasks.java
index 365c436..2b988d3 100644
--- a/services/core/java/com/android/server/am/RecentTasks.java
+++ b/services/core/java/com/android/server/am/RecentTasks.java
@@ -534,8 +534,8 @@
             final TaskRecord tr = mTasks.get(i);
             final String taskPackageName =
                     tr.getBaseIntent().getComponent().getPackageName();
-            if (tr.userId != userId) return;
-            if (!taskPackageName.equals(packageName)) return;
+            if (tr.userId != userId) continue;
+            if (!taskPackageName.equals(packageName)) continue;
 
             mService.mStackSupervisor.removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS,
                     "remove-package-task");
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index a294334..b6e414a2 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1184,11 +1184,6 @@
             Slog.w(TAG, "No user info for user #" + targetUserId);
             return false;
         }
-        if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mInjector.getContext())) {
-            Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
-                    + " when device is in demo mode");
-            return false;
-        }
         if (!targetUserInfo.supportsSwitchTo()) {
             Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
             return false;
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 2a361a0..7aaac06 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -37,10 +37,10 @@
 import android.net.dns.ResolvUtil;
 import android.os.Binder;
 import android.os.INetworkManagementService;
-import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.text.TextUtils;
+import android.util.Pair;
 import android.util.Slog;
 
 import com.android.server.connectivity.MockableSystemProperties;
@@ -50,8 +50,12 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Map;
+import java.util.Objects;
 import java.util.stream.Collectors;
+import java.util.Set;
 import java.util.StringJoiner;
 
 
@@ -110,6 +114,7 @@
  */
 public class DnsManager {
     private static final String TAG = DnsManager.class.getSimpleName();
+    private static final PrivateDnsConfig PRIVATE_DNS_OFF = new PrivateDnsConfig();
 
     /* Defaults for resolver parameters. */
     private static final int DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800;
@@ -183,11 +188,89 @@
         };
     }
 
+    public static class PrivateDnsValidationUpdate {
+        final public int netId;
+        final public InetAddress ipAddress;
+        final public String hostname;
+        final public boolean validated;
+
+        public PrivateDnsValidationUpdate(int netId, InetAddress ipAddress,
+                String hostname, boolean validated) {
+            this.netId = netId;
+            this.ipAddress = ipAddress;
+            this.hostname = hostname;
+            this.validated = validated;
+        }
+    }
+
+    private static class PrivateDnsValidationStatuses {
+        enum ValidationStatus {
+            IN_PROGRESS,
+            FAILED,
+            SUCCEEDED
+        }
+
+        // Validation statuses of <hostname, ipAddress> pairs for a single netId
+        private Map<Pair<String, InetAddress>, ValidationStatus> mValidationMap;
+
+        private PrivateDnsValidationStatuses() {
+            mValidationMap = new HashMap<>();
+        }
+
+        private boolean hasValidatedServer() {
+            for (ValidationStatus status : mValidationMap.values()) {
+                if (status == ValidationStatus.SUCCEEDED) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private void updateTrackedDnses(String[] ipAddresses, String hostname) {
+            Set<Pair<String, InetAddress>> latestDnses = new HashSet<>();
+            for (String ipAddress : ipAddresses) {
+                try {
+                    latestDnses.add(new Pair(hostname,
+                            InetAddress.parseNumericAddress(ipAddress)));
+                } catch (IllegalArgumentException e) {}
+            }
+            // Remove <hostname, ipAddress> pairs that should not be tracked.
+            for (Iterator<Map.Entry<Pair<String, InetAddress>, ValidationStatus>> it =
+                    mValidationMap.entrySet().iterator(); it.hasNext(); ) {
+                Map.Entry<Pair<String, InetAddress>, ValidationStatus> entry = it.next();
+                if (!latestDnses.contains(entry.getKey())) {
+                    it.remove();
+                }
+            }
+            // Add new <hostname, ipAddress> pairs that should be tracked.
+            for (Pair<String, InetAddress> p : latestDnses) {
+                if (!mValidationMap.containsKey(p)) {
+                    mValidationMap.put(p, ValidationStatus.IN_PROGRESS);
+                }
+            }
+        }
+
+        private void updateStatus(PrivateDnsValidationUpdate update) {
+            Pair<String, InetAddress> p = new Pair(update.hostname,
+                    update.ipAddress);
+            if (!mValidationMap.containsKey(p)) {
+                return;
+            }
+            if (update.validated) {
+                mValidationMap.put(p, ValidationStatus.SUCCEEDED);
+            } else {
+                mValidationMap.put(p, ValidationStatus.FAILED);
+            }
+        }
+    }
+
     private final Context mContext;
     private final ContentResolver mContentResolver;
     private final INetworkManagementService mNMS;
     private final MockableSystemProperties mSystemProperties;
+    // TODO: Replace these Maps with SparseArrays.
     private final Map<Integer, PrivateDnsConfig> mPrivateDnsMap;
+    private final Map<Integer, PrivateDnsValidationStatuses> mPrivateDnsValidationMap;
 
     private int mNumDnsEntries;
     private int mSampleValidity;
@@ -203,6 +286,7 @@
         mNMS = nms;
         mSystemProperties = sp;
         mPrivateDnsMap = new HashMap<>();
+        mPrivateDnsValidationMap = new HashMap<>();
 
         // TODO: Create and register ContentObservers to track every setting
         // used herein, posting messages to respond to changes.
@@ -214,6 +298,7 @@
 
     public void removeNetwork(Network network) {
         mPrivateDnsMap.remove(network.netId);
+        mPrivateDnsValidationMap.remove(network.netId);
     }
 
     public PrivateDnsConfig updatePrivateDns(Network network, PrivateDnsConfig cfg) {
@@ -223,6 +308,40 @@
                 : mPrivateDnsMap.remove(network.netId);
     }
 
+    public void updatePrivateDnsStatus(int netId, LinkProperties lp) {
+        // Use the PrivateDnsConfig data pushed to this class instance
+        // from ConnectivityService.
+        final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
+                PRIVATE_DNS_OFF);
+
+        final boolean useTls = privateDnsCfg.useTls;
+        final boolean strictMode = privateDnsCfg.inStrictMode();
+        final String tlsHostname = strictMode ? privateDnsCfg.hostname : "";
+
+        if (strictMode) {
+            lp.setUsePrivateDns(true);
+            lp.setPrivateDnsServerName(tlsHostname);
+        } else if (useTls) {
+            // We are in opportunistic mode. Private DNS should be used if there
+            // is a known DNS-over-TLS validated server.
+            boolean validated = mPrivateDnsValidationMap.containsKey(netId) &&
+                    mPrivateDnsValidationMap.get(netId).hasValidatedServer();
+            lp.setUsePrivateDns(validated);
+            lp.setPrivateDnsServerName(null);
+        } else {
+            // Private DNS is disabled.
+            lp.setUsePrivateDns(false);
+            lp.setPrivateDnsServerName(null);
+        }
+    }
+
+    public void updatePrivateDnsValidation(PrivateDnsValidationUpdate update) {
+        final PrivateDnsValidationStatuses statuses =
+                mPrivateDnsValidationMap.get(update.netId);
+        if (statuses == null) return;
+        statuses.updateStatus(update);
+    }
+
     public void setDnsConfigurationForNetwork(
             int netId, LinkProperties lp, boolean isDefaultNetwork) {
         final String[] assignedServers = NetworkUtils.makeStrings(lp.getDnsServers());
@@ -238,10 +357,11 @@
         //
         // At this time we do not attempt to enable Private DNS on non-Internet
         // networks like IMS.
-        final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.get(netId);
+        final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
+                PRIVATE_DNS_OFF);
 
-        final boolean useTls = (privateDnsCfg != null) && privateDnsCfg.useTls;
-        final boolean strictMode = (privateDnsCfg != null) && privateDnsCfg.inStrictMode();
+        final boolean useTls = privateDnsCfg.useTls;
+        final boolean strictMode = privateDnsCfg.inStrictMode();
         final String tlsHostname = strictMode ? privateDnsCfg.hostname : "";
         final String[] tlsServers =
                 strictMode ? NetworkUtils.makeStrings(
@@ -251,6 +371,17 @@
                 : useTls ? assignedServers  // Opportunistic
                 : new String[0];            // Off
 
+        // Prepare to track the validation status of the DNS servers in the
+        // resolver config when private DNS is in opportunistic or strict mode.
+        if (useTls) {
+            if (!mPrivateDnsValidationMap.containsKey(netId)) {
+                mPrivateDnsValidationMap.put(netId, new PrivateDnsValidationStatuses());
+            }
+            mPrivateDnsValidationMap.get(netId).updateTrackedDnses(tlsServers, tlsHostname);
+        } else {
+            mPrivateDnsValidationMap.remove(netId);
+        }
+
         Slog.d(TAG, String.format("setDnsConfigurationForNetwork(%d, %s, %s, %s, %s, %s)",
                 netId, Arrays.toString(assignedServers), Arrays.toString(domainStrs),
                 Arrays.toString(params), tlsHostname, Arrays.toString(tlsServers)));
diff --git a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
index 3868ea6..906a6a3 100644
--- a/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
+++ b/services/core/java/com/android/server/connectivity/MultipathPolicyTracker.java
@@ -57,6 +57,7 @@
 import android.telephony.TelephonyManager;
 import android.util.DebugUtils;
 import android.util.Pair;
+import android.util.Range;
 import android.util.Slog;
 
 import com.android.internal.R;
@@ -266,9 +267,9 @@
         }
 
         private long getRemainingDailyBudget(long limitBytes,
-                Pair<ZonedDateTime, ZonedDateTime> cycle) {
-            final long start = cycle.first.toInstant().toEpochMilli();
-            final long end = cycle.second.toInstant().toEpochMilli();
+                Range<ZonedDateTime> cycle) {
+            final long start = cycle.getLower().toInstant().toEpochMilli();
+            final long end = cycle.getUpper().toInstant().toEpochMilli();
             final long totalBytes = getNetworkTotalBytes(start, end);
             final long remainingBytes = totalBytes == -1 ? 0 : Math.max(0, limitBytes - totalBytes);
             // 1 + ((end - now - 1) / millisInDay with integers is equivalent to:
@@ -389,7 +390,7 @@
 
     private static boolean hasActiveCycle(NetworkPolicy policy) {
         return policy.hasCycle() && policy.lastLimitSnooze <
-                policy.cycleIterator().next().first.toInstant().toEpochMilli();
+                policy.cycleIterator().next().getLower().toInstant().toEpochMilli();
     }
 
     // Only ever updated on the handler thread. Accessed from other binder threads to retrieve
diff --git a/services/core/java/com/android/server/display/AutomaticBrightnessController.java b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
index bfd34ac..f403953 100644
--- a/services/core/java/com/android/server/display/AutomaticBrightnessController.java
+++ b/services/core/java/com/android/server/display/AutomaticBrightnessController.java
@@ -222,6 +222,9 @@
     }
 
     public int getAutomaticScreenBrightness() {
+        if (!mAmbientLuxValid) {
+            return -1;
+        }
         if (mDisplayPolicy == DisplayPowerRequest.POLICY_DOZE) {
             return (int) (mScreenAutoBrightness * mDozeScaleFactor);
         }
@@ -346,6 +349,7 @@
         pw.println("  mLightSensorEnabled=" + mLightSensorEnabled);
         pw.println("  mLightSensorEnableTime=" + TimeUtils.formatUptime(mLightSensorEnableTime));
         pw.println("  mAmbientLux=" + mAmbientLux);
+        pw.println("  mAmbientLuxValid=" + mAmbientLuxValid);
         pw.println("  mAmbientLightHorizon=" + mAmbientLightHorizon);
         pw.println("  mBrighteningLuxThreshold=" + mBrighteningLuxThreshold);
         pw.println("  mDarkeningLuxThreshold=" + mDarkeningLuxThreshold);
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index 93e0bd5..0f531a8 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -36,11 +36,13 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
+import android.content.res.TypedArray;
 import android.graphics.Point;
 import android.hardware.SensorManager;
 import android.hardware.display.AmbientBrightnessDayStats;
 import android.hardware.display.BrightnessChangeEvent;
 import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.Curve;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.display.DisplayViewport;
@@ -72,8 +74,10 @@
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.IntArray;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.Spline;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Surface;
@@ -276,6 +280,11 @@
 
     private final Injector mInjector;
 
+    // The minimum brightness curve, which guarantess that any brightness curve that dips below it
+    // is rejected by the system.
+    private final Curve mMinimumBrightnessCurve;
+    private final Spline mMinimumBrightnessSpline;
+
     public DisplayManagerService(Context context) {
         this(context, new Injector());
     }
@@ -289,8 +298,15 @@
         mUiHandler = UiThread.getHandler();
         mDisplayAdapterListener = new DisplayAdapterListener();
         mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
+        Resources resources = mContext.getResources();
         mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
                 com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
+        float[] lux = getFloatArray(resources.obtainTypedArray(
+                com.android.internal.R.array.config_minimumBrightnessCurveLux));
+        float[] nits = getFloatArray(resources.obtainTypedArray(
+                com.android.internal.R.array.config_minimumBrightnessCurveNits));
+        mMinimumBrightnessCurve = new Curve(lux, nits);
+        mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
 
         PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
         mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting();
@@ -1032,9 +1048,15 @@
         }
     }
 
+    @VisibleForTesting
+    Curve getMinimumBrightnessCurveInternal() {
+        return mMinimumBrightnessCurve;
+    }
+
     private void setBrightnessConfigurationForUserInternal(
             @Nullable BrightnessConfiguration c, @UserIdInt int userId,
             @Nullable String packageName) {
+        validateBrightnessConfiguration(c);
         final int userSerial = getUserManager().getUserSerialNumber(userId);
         synchronized (mSyncRoot) {
             try {
@@ -1049,6 +1071,28 @@
         }
     }
 
+    @VisibleForTesting
+    void validateBrightnessConfiguration(BrightnessConfiguration config) {
+        if (config == null) {
+            return;
+        }
+        if (isBrightnessConfigurationTooDark(config)) {
+            throw new IllegalArgumentException("brightness curve is too dark");
+        }
+    }
+
+    private boolean isBrightnessConfigurationTooDark(BrightnessConfiguration config) {
+        Pair<float[], float[]> curve = config.getCurve();
+        float[] lux = curve.first;
+        float[] nits = curve.second;
+        for (int i = 0; i < lux.length; i++) {
+            if (nits[i] < mMinimumBrightnessSpline.interpolate(lux[i])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     private void loadBrightnessConfiguration() {
         synchronized (mSyncRoot) {
             final int userSerial = getUserManager().getUserSerialNumber(mCurrentUserId);
@@ -1369,6 +1413,16 @@
         }
     }
 
+    private static float[] getFloatArray(TypedArray array) {
+        int length = array.length();
+        float[] floatArray = new float[length];
+        for (int i = 0; i < length; i++) {
+            floatArray[i] = array.getFloat(i, Float.NaN);
+        }
+        array.recycle();
+        return floatArray;
+    }
+
     /**
      * This is the object that everything in the display manager locks on.
      * We make it an inner class within the {@link DisplayManagerService} to so that it is
@@ -1999,6 +2053,16 @@
             }
         }
 
+        @Override // Binder call
+        public Curve getMinimumBrightnessCurve() {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                return getMinimumBrightnessCurveInternal();
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
         void setBrightness(int brightness) {
             Settings.System.putIntForUser(mContext.getContentResolver(),
                     Settings.System.SCREEN_BRIGHTNESS, brightness, UserHandle.USER_CURRENT);
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index 88b2a36..0700ab3 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -534,17 +534,33 @@
 
     private void destroyWeaverSlot(long handle, int userId) {
         int slot = loadWeaverSlot(handle, userId);
+        destroyState(WEAVER_SLOT_NAME, handle, userId);
         if (slot != INVALID_WEAVER_SLOT) {
-            try {
-                weaverEnroll(slot, null, null);
-            } catch (RemoteException e) {
-                Log.w(TAG, "Failed to destroy slot", e);
+            Set<Integer> usedSlots = getUsedWeaverSlots();
+            if (!usedSlots.contains(slot)) {
+                Log.i(TAG, "Destroy weaver slot " + slot + " for user " + userId);
+                try {
+                    weaverEnroll(slot, null, null);
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Failed to destroy slot", e);
+                }
+            } else {
+                Log.w(TAG, "Skip destroying reused weaver slot " + slot + " for user " + userId);
             }
         }
-        destroyState(WEAVER_SLOT_NAME, handle, userId);
     }
 
-    private int getNextAvailableWeaverSlot() {
+    /**
+     * Return the set of weaver slots that are currently in use by all users on the device.
+     * <p>
+     * <em>Note:</em> Users who are in the process of being deleted are not tracked here
+     * (due to them being marked as partial in UserManager so not visible from
+     * {@link UserManager#getUsers}). As a result their weaver slots will not be considered
+     * taken and can be reused by new users. Care should be taken when cleaning up the
+     * deleted user in {@link #removeUser}, to prevent a reused slot from being erased
+     * unintentionally.
+     */
+    private Set<Integer> getUsedWeaverSlots() {
         Map<Integer, List<Long>> slotHandles = mStorage.listSyntheticPasswordHandlesForAllUsers(
                 WEAVER_SLOT_NAME);
         HashSet<Integer> slots = new HashSet<>();
@@ -554,8 +570,13 @@
                 slots.add(slot);
             }
         }
+        return slots;
+    }
+
+    private int getNextAvailableWeaverSlot() {
+        Set<Integer> usedSlots = getUsedWeaverSlots();
         for (int i = 0; i < mWeaverConfig.slots; i++) {
-            if (!slots.contains(i)) {
+            if (!usedSlots.contains(i)) {
                 return i;
             }
         }
@@ -592,6 +613,7 @@
         if (isWeaverAvailable()) {
             // Weaver based user password
             int weaverSlot = getNextAvailableWeaverSlot();
+            Log.i(TAG, "Weaver enroll password to slot " + weaverSlot + " for user " + userId);
             byte[] weaverSecret = weaverEnroll(weaverSlot, passwordTokenToWeaverKey(pwdToken), null);
             if (weaverSecret == null) {
                 Log.e(TAG, "Fail to enroll user password under weaver " + userId);
@@ -749,6 +771,7 @@
         if (isWeaverAvailable()) {
             int slot = getNextAvailableWeaverSlot();
             try {
+                Log.i(TAG, "Weaver enroll token to slot " + slot + " for user " + userId);
                 weaverEnroll(slot, null, tokenData.weaverSecret);
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to enroll weaver secret when activating token", e);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 1782ae5..8e77373 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -39,6 +39,7 @@
 import static android.net.ConnectivityManager.RESTRICT_BACKGROUND_STATUS_WHITELISTED;
 import static android.net.ConnectivityManager.TYPE_MOBILE;
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
@@ -195,6 +196,7 @@
 import android.util.DataUnit;
 import android.util.Log;
 import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -503,6 +505,10 @@
     @GuardedBy("mNetworkPoliciesSecondLock")
     private final SparseBooleanArray mNetworkMetered = new SparseBooleanArray();
 
+    /** Map from network ID to last observed roaming state */
+    @GuardedBy("mNetworkPoliciesSecondLock")
+    private final SparseBooleanArray mNetworkRoaming = new SparseBooleanArray();
+
     /** Map from netId to subId as of last update */
     @GuardedBy("mNetworkPoliciesSecondLock")
     private final SparseIntArray mNetIdToSubId = new SparseIntArray();
@@ -1018,6 +1024,16 @@
         }
     };
 
+    private static boolean updateCapabilityChange(SparseBooleanArray lastValues, boolean newValue,
+            Network network) {
+        final boolean lastValue = lastValues.get(network.netId, false);
+        final boolean changed = (lastValue != newValue) || lastValues.indexOfKey(network.netId) < 0;
+        if (changed) {
+            lastValues.put(network.netId, newValue);
+        }
+        return changed;
+    }
+
     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
         @Override
         public void onCapabilitiesChanged(Network network,
@@ -1025,13 +1041,18 @@
             if (network == null || networkCapabilities == null) return;
 
             synchronized (mNetworkPoliciesSecondLock) {
-                final boolean oldMetered = mNetworkMetered.get(network.netId, false);
                 final boolean newMetered = !networkCapabilities
                         .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
+                final boolean meteredChanged = updateCapabilityChange(
+                        mNetworkMetered, newMetered, network);
 
-                if ((oldMetered != newMetered) || mNetworkMetered.indexOfKey(network.netId) < 0) {
+                final boolean newRoaming = !networkCapabilities
+                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
+                final boolean roamingChanged = updateCapabilityChange(
+                        mNetworkRoaming, newRoaming, network);
+
+                if (meteredChanged || roamingChanged) {
                     mLogger.meterednessChanged(network.netId, newMetered);
-                    mNetworkMetered.put(network.netId, newMetered);
                     updateNetworkRulesNL();
                 }
             }
@@ -1770,18 +1791,21 @@
 
             final long quotaBytes;
             final long limitBytes = plan.getDataLimitBytes();
-            if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
+            if (!state.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_ROAMING)) {
+                // Clamp to 0 when roaming
+                quotaBytes = 0;
+            } else if (limitBytes == SubscriptionPlan.BYTES_UNKNOWN) {
                 quotaBytes = OPPORTUNISTIC_QUOTA_UNKNOWN;
             } else if (limitBytes == SubscriptionPlan.BYTES_UNLIMITED) {
                 // Unlimited data; let's use 20MiB/day (600MiB/month)
                 quotaBytes = quotaUnlimited;
             } else {
                 // Limited data; let's only use 10% of remaining budget
-                final Pair<ZonedDateTime, ZonedDateTime> cycle = plan.cycleIterator().next();
-                final long start = cycle.first.toInstant().toEpochMilli();
-                final long end = cycle.second.toInstant().toEpochMilli();
+                final Range<ZonedDateTime> cycle = plan.cycleIterator().next();
+                final long start = cycle.getLower().toInstant().toEpochMilli();
+                final long end = cycle.getUpper().toInstant().toEpochMilli();
                 final Instant now = mClock.instant();
-                final long startOfDay = ZonedDateTime.ofInstant(now, cycle.first.getZone())
+                final long startOfDay = ZonedDateTime.ofInstant(now, cycle.getLower().getZone())
                         .truncatedTo(ChronoUnit.DAYS)
                         .toInstant().toEpochMilli();
                 final long totalBytes = getTotalBytes(
diff --git a/services/core/java/com/android/server/net/NetworkStatsCollection.java b/services/core/java/com/android/server/net/NetworkStatsCollection.java
index 2ef754e..ab52523 100644
--- a/services/core/java/com/android/server/net/NetworkStatsCollection.java
+++ b/services/core/java/com/android/server/net/NetworkStatsCollection.java
@@ -47,7 +47,7 @@
 import android.util.AtomicFile;
 import android.util.IntArray;
 import android.util.MathUtils;
-import android.util.Pair;
+import android.util.Range;
 import android.util.Slog;
 import android.util.proto.ProtoOutputStream;
 
@@ -266,11 +266,11 @@
         long collectEnd = end;
 
         if (augmentEnd != SubscriptionPlan.TIME_UNKNOWN) {
-            final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = augmentPlan.cycleIterator();
+            final Iterator<Range<ZonedDateTime>> it = augmentPlan.cycleIterator();
             while (it.hasNext()) {
-                final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
-                final long cycleStart = cycle.first.toInstant().toEpochMilli();
-                final long cycleEnd = cycle.second.toInstant().toEpochMilli();
+                final Range<ZonedDateTime> cycle = it.next();
+                final long cycleStart = cycle.getLower().toInstant().toEpochMilli();
+                final long cycleEnd = cycle.getUpper().toInstant().toEpochMilli();
                 if (cycleStart <= augmentEnd && augmentEnd < cycleEnd) {
                     augmentStart = cycleStart;
                     collectStart = Long.min(collectStart, augmentStart);
diff --git a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
index 17c5868..766d8ca 100644
--- a/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
+++ b/services/core/java/com/android/server/net/watchlist/NetworkWatchlistShellCommand.java
@@ -91,7 +91,7 @@
         final long ident = Binder.clearCallingIdentity();
         try {
             // Reset last report time
-            if (!WatchlistConfig.getInstance().isConfigSecure()) {
+            if (WatchlistConfig.getInstance().isConfigSecure()) {
                 pw.println("Error: Cannot force generate report under production config");
                 return -1;
             }
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 586abc1..156f702 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -32,6 +32,7 @@
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.database.ContentObserver;
+import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.AudioManagerInternal;
@@ -1198,8 +1199,6 @@
 
     @VisibleForTesting
     protected Notification createZenUpgradeNotification() {
-        Intent intent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         final Bundle extras = new Bundle();
         extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
                 mContext.getResources().getString(R.string.global_action_settings));
@@ -1210,15 +1209,20 @@
             title = R.string.zen_upgrade_notification_visd_title;
             content = R.string.zen_upgrade_notification_visd_content;
         }
+        Intent onboardingIntent = new Intent(Settings.ZEN_MODE_ONBOARDING);
+        onboardingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         return new Notification.Builder(mContext, SystemNotificationChannels.DO_NOT_DISTURB)
+                .setAutoCancel(true)
                 .setSmallIcon(R.drawable.ic_settings_24dp)
+                .setLargeIcon(Icon.createWithResource(mContext, R.drawable.ic_zen_24dp))
                 .setContentTitle(mContext.getResources().getString(title))
                 .setContentText(mContext.getResources().getString(content))
+                .setContentIntent(PendingIntent.getActivity(mContext, 0, onboardingIntent,
+                        PendingIntent.FLAG_UPDATE_CURRENT))
                 .setAutoCancel(true)
                 .setLocalOnly(true)
                 .addExtras(extras)
                 .setStyle(new Notification.BigTextStyle())
-                .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0, null))
                 .build();
     }
 
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index bc9fa4b..dbf0940 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -256,8 +256,6 @@
         int flags = origIntent.getFlags();
         final Intent intent = new Intent();
         intent.setFlags(flags
-                | Intent.FLAG_ACTIVITY_NEW_TASK
-                | Intent.FLAG_ACTIVITY_CLEAR_TASK
                 | Intent.FLAG_ACTIVITY_NO_HISTORY
                 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
         if (token != null) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 26d4037..5b45cbe 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5305,7 +5305,7 @@
         synchronized (mPackages) {
             final String[] packageNames = getPackagesForUid(uid);
             final PackageParser.Package pkg = (packageNames != null && packageNames.length > 0)
-                    ? mPackages.get(packageNames[0])
+                    ? mSettings.getPackageLPr(packageNames[0]).getPackage()
                     : null;
             return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());
         }
@@ -8071,7 +8071,6 @@
                 callingUid = mIsolatedOwners.get(callingUid);
             }
             final PackageSetting ps = mSettings.mPackages.get(packageName);
-            PackageParser.Package pkg = mPackages.get(packageName);
             final boolean returnAllowed =
                     ps != null
                     && (isCallerSameApp(packageName, callingUid)
@@ -8142,7 +8141,7 @@
     }
 
     private boolean isCallerSameApp(String packageName, int uid) {
-        PackageParser.Package pkg = mPackages.get(packageName);
+        PackageParser.Package pkg = mSettings.getPackageLPr(packageName).getPackage();
         return pkg != null
                 && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
     }
@@ -23625,6 +23624,13 @@
         }
 
         @Override
+        public Object getPackageSetting(String packageName) {
+            synchronized (mPackages) {
+                return mSettings.getPackageLPr(packageName);
+            }
+        }
+
+        @Override
         public PackageList getPackageList(PackageListObserver observer) {
             synchronized (mPackages) {
                 final int N = mPackages.size();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index f5b52fc..065133b 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -212,12 +212,11 @@
             return PackageManager.PERMISSION_DENIED;
         }
 
-        final PackageParser.Package pkg = mPackageManagerInt.getPackage(pkgName);
-        if (pkg != null && pkg.mExtras != null) {
-            if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
+        final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(pkgName);
+        if (ps != null && ps.getPackage() != null) {
+            if (mPackageManagerInt.filterAppAccess(ps.getPackage(), callingUid, userId)) {
                 return PackageManager.PERMISSION_DENIED;
             }
-            final PackageSetting ps = (PackageSetting) pkg.mExtras;
             final boolean instantApp = ps.getInstantApp(userId);
             final PermissionsState permissionsState = ps.getPermissionsState();
             if (permissionsState.hasPermission(permName, userId)) {
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 1575694..165a409 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -113,63 +113,73 @@
         mListener.onWindowsGone();
     };
 
-    private final Runnable mAddStartingWindow = () -> {
-        final StartingData startingData;
-        final AppWindowToken container;
+    private final Runnable mAddStartingWindow = new Runnable() {
 
-        synchronized (mWindowMap) {
-            if (mContainer == null) {
-                if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
-                        + " add starting window");
+        @Override
+        public void run() {
+            final StartingData startingData;
+            final AppWindowToken container;
+
+            synchronized (mWindowMap) {
+                if (mContainer == null) {
+                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "mContainer was null while trying to"
+                            + " add starting window");
+                    return;
+                }
+
+                // There can only be one adding request, silly caller!
+                mService.mAnimationHandler.removeCallbacks(this);
+
+                startingData = mContainer.startingData;
+                container = mContainer;
+            }
+
+            if (startingData == null) {
+                // Animation has been canceled... do nothing.
+                if (DEBUG_STARTING_WINDOW)
+                    Slog.v(TAG_WM, "startingData was nulled out before handling"
+                            + " mAddStartingWindow: " + mContainer);
                 return;
             }
-            startingData = mContainer.startingData;
-            container = mContainer;
-        }
 
-        if (startingData == null) {
-            // Animation has been canceled... do nothing.
-            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "startingData was nulled out before handling"
-                    + " mAddStartingWindow: " + mContainer);
-            return;
-        }
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
+                    + AppWindowContainerController.this + ": startingData="
+                    + container.startingData);
 
-        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Add starting "
-                + this + ": startingData=" + container.startingData);
-
-        StartingSurface surface = null;
-        try {
-            surface = startingData.createStartingSurface(container);
-        } catch (Exception e) {
-            Slog.w(TAG_WM, "Exception when adding starting window", e);
-        }
-        if (surface != null) {
-            boolean abort = false;
-            synchronized(mWindowMap) {
-                // If the window was successfully added, then
-                // we need to remove it.
-                if (container.removed || container.startingData == null) {
-                    if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
-                            "Aborted starting " + container
-                                    + ": removed=" + container.removed
-                                    + " startingData=" + container.startingData);
-                    container.startingWindow = null;
-                    container.startingData = null;
-                    abort = true;
-                } else {
-                    container.startingSurface = surface;
+            StartingSurface surface = null;
+            try {
+                surface = startingData.createStartingSurface(container);
+            } catch (Exception e) {
+                Slog.w(TAG_WM, "Exception when adding starting window", e);
+            }
+            if (surface != null) {
+                boolean abort = false;
+                synchronized (mWindowMap) {
+                    // If the window was successfully added, then
+                    // we need to remove it.
+                    if (container.removed || container.startingData == null) {
+                        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM,
+                                "Aborted starting " + container
+                                        + ": removed=" + container.removed
+                                        + " startingData=" + container.startingData);
+                        container.startingWindow = null;
+                        container.startingData = null;
+                        abort = true;
+                    } else {
+                        container.startingSurface = surface;
+                    }
+                    if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM,
+                            "Added starting " + mContainer
+                                    + ": startingWindow="
+                                    + container.startingWindow + " startingView="
+                                    + container.startingSurface);
                 }
-                if (DEBUG_STARTING_WINDOW && !abort) Slog.v(TAG_WM,
-                        "Added starting " + mContainer
-                                + ": startingWindow="
-                                + container.startingWindow + " startingView="
-                                + container.startingSurface);
+                if (abort) {
+                    surface.remove();
+                }
+            } else if (DEBUG_STARTING_WINDOW) {
+                Slog.v(TAG_WM, "Surface returned was null: " + mContainer);
             }
-            if (abort) {
-                surface.remove();
-            }
-        } else if (DEBUG_STARTING_WINDOW) {
-            Slog.v(TAG_WM, "Surface returned was null: " + mContainer);
         }
     };
 
@@ -558,8 +568,10 @@
         // Note: we really want to do sendMessageAtFrontOfQueue() because we
         // want to process the message ASAP, before any other queued
         // messages.
-        if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
-        mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
+        if (!mService.mAnimationHandler.hasCallbacks(mAddStartingWindow)) {
+            if (DEBUG_STARTING_WINDOW) Slog.v(TAG_WM, "Enqueueing ADD_STARTING");
+            mService.mAnimationHandler.postAtFrontOfQueue(mAddStartingWindow);
+        }
     }
 
     private boolean createSnapshot(TaskSnapshot snapshot) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fa7eff2..2b5620c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -1243,6 +1243,10 @@
                     Slog.w(TAG_WM, "Attempted to add window with exiting application token "
                           + token + ".  Aborting.");
                     return WindowManagerGlobal.ADD_APP_EXITING;
+                } else if (type == TYPE_APPLICATION_STARTING && atoken.startingWindow != null) {
+                    Slog.w(TAG_WM, "Attempted to add starting window to token with already existing"
+                            + " starting window");
+                    return WindowManagerGlobal.ADD_DUPLICATE_ADD;
                 }
             } else if (rootType == TYPE_INPUT_METHOD) {
                 if (token.windowType != TYPE_INPUT_METHOD) {
@@ -1930,7 +1934,15 @@
                 winAnimator.setOpaqueLocked(false);
             }
 
-            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0;
+            final int oldVisibility = win.mViewVisibility;
+
+            // If the window is becoming visible, visibleOrAdding may change which may in turn
+            // change the IME target.
+            final boolean becameVisible =
+                    (oldVisibility == View.INVISIBLE || oldVisibility == View.GONE)
+                            && viewVisibility == View.VISIBLE;
+            boolean imMayMove = (flagChanges & (FLAG_ALT_FOCUSABLE_IM | FLAG_NOT_FOCUSABLE)) != 0
+                    || becameVisible;
             final boolean isDefaultDisplay = win.isDefaultDisplay();
             boolean focusMayChange = isDefaultDisplay && (win.mViewVisibility != viewVisibility
                     || ((flagChanges & FLAG_NOT_FOCUSABLE) != 0)
@@ -1946,7 +1958,6 @@
             win.mRelayoutCalled = true;
             win.mInRelayout = true;
 
-            final int oldVisibility = win.mViewVisibility;
             win.mViewVisibility = viewVisibility;
             if (DEBUG_SCREEN_ON) {
                 RuntimeException stack = new RuntimeException();
diff --git a/services/tests/servicestests/AndroidTest.xml b/services/tests/servicestests/AndroidTest.xml
index 0ec16b5..8f989df 100644
--- a/services/tests/servicestests/AndroidTest.xml
+++ b/services/tests/servicestests/AndroidTest.xml
@@ -28,5 +28,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.servicestests" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index d908b8e..cecc94b 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -18,6 +18,7 @@
 
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
 import static android.net.ConnectivityManager.TYPE_WIFI;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING;
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.net.NetworkPolicy.LIMIT_DISABLED;
 import static android.net.NetworkPolicy.SNOOZE_NEVER;
@@ -30,6 +31,7 @@
 import static android.net.NetworkStats.SET_ALL;
 import static android.net.NetworkStats.TAG_ALL;
 import static android.net.NetworkTemplate.buildTemplateMobileAll;
+import static android.net.NetworkTemplate.buildTemplateWifi;
 import static android.net.TrafficStats.MB_IN_BYTES;
 import static android.telephony.CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED;
 import static android.telephony.CarrierConfigManager.DATA_CYCLE_THRESHOLD_DISABLED;
@@ -43,6 +45,7 @@
 
 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_JOBS;
 import static com.android.server.net.NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH;
+import static com.android.server.net.NetworkPolicyManagerService.OPPORTUNISTIC_QUOTA_UNKNOWN;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_LIMIT_SNOOZED;
 import static com.android.server.net.NetworkPolicyManagerService.TYPE_RAPID;
@@ -65,6 +68,7 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -121,7 +125,7 @@
 import android.text.format.Time;
 import android.util.DataUnit;
 import android.util.Log;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.telephony.PhoneConstants;
@@ -201,7 +205,8 @@
     private static final int TEST_SUB_ID = 42;
     private static final int TEST_NET_ID = 24;
 
-    private static NetworkTemplate sTemplateWifi = NetworkTemplate.buildTemplateWifi(TEST_SSID);
+    private static NetworkTemplate sTemplateWifi = buildTemplateWifi(TEST_SSID);
+    private static NetworkTemplate sTemplateMobileAll = buildTemplateMobileAll(TEST_IMSI);
 
     /**
      * Path on assets where files used by {@link NetPolicyXml} are located.
@@ -221,6 +226,7 @@
     private @Mock IActivityManager mActivityManager;
     private @Mock INetworkManagementService mNetworkManager;
     private @Mock IConnectivityManager mConnManager;
+    private @Mock ConnectivityManager mConnectivityManager;
     private @Mock NotificationManager mNotifManager;
     private @Mock PackageManager mPackageManager;
     private @Mock IPackageManager mIpm;
@@ -228,6 +234,9 @@
     private @Mock CarrierConfigManager mCarrierConfigManager;
     private @Mock TelephonyManager mTelephonyManager;
 
+    private ArgumentCaptor<ConnectivityManager.NetworkCallback> mNetworkCallbackCaptor =
+            ArgumentCaptor.forClass(ConnectivityManager.NetworkCallback.class);
+
     private ActivityManagerInternal mActivityManagerInternal;
     private NetworkStatsManagerInternal mStatsService;
 
@@ -331,6 +340,8 @@
                         return mTelephonyManager;
                     case Context.NOTIFICATION_SERVICE:
                         return mNotifManager;
+                    case Context.CONNECTIVITY_SERVICE:
+                        return mConnectivityManager;
                     default:
                         return super.getSystemService(name);
                 }
@@ -394,6 +405,8 @@
                 .thenReturn(buildApplicationInfo(PKG_NAME_C));
         when(mNetworkManager.isBandwidthControlEnabled()).thenReturn(true);
         when(mNetworkManager.setDataSaverModeEnabled(anyBoolean())).thenReturn(true);
+        doNothing().when(mConnectivityManager)
+                .registerNetworkCallback(any(), mNetworkCallbackCaptor.capture());
 
         // Prepare NPMS.
         mService.systemReady(mService.networkScoreAndNetworkManagementServiceReady());
@@ -821,11 +834,11 @@
     private static long computeLastCycleBoundary(long currentTime, NetworkPolicy policy) {
         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
                 ZoneId.systemDefault());
-        final Iterator<Pair<ZonedDateTime, ZonedDateTime>> it = policy.cycleIterator();
+        final Iterator<Range<ZonedDateTime>> it = policy.cycleIterator();
         while (it.hasNext()) {
-            final Pair<ZonedDateTime, ZonedDateTime> cycle = it.next();
-            if (cycle.first.toInstant().toEpochMilli() < currentTime) {
-                return cycle.first.toInstant().toEpochMilli();
+            final Range<ZonedDateTime> cycle = it.next();
+            if (cycle.getLower().toInstant().toEpochMilli() < currentTime) {
+                return cycle.getLower().toInstant().toEpochMilli();
             }
         }
         throw new IllegalStateException(
@@ -835,7 +848,7 @@
     private static long computeNextCycleBoundary(long currentTime, NetworkPolicy policy) {
         RecurrenceRule.sClock = Clock.fixed(Instant.ofEpochMilli(currentTime),
                 ZoneId.systemDefault());
-        return policy.cycleIterator().next().second.toInstant().toEpochMilli();
+        return policy.cycleIterator().next().getUpper().toInstant().toEpochMilli();
     }
 
     @Test
@@ -1015,10 +1028,8 @@
         mService.updateNetworks();
 
         // Define simple data plan
-        final SubscriptionPlan plan = SubscriptionPlan.Builder
-                .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
-                .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED)
-                .build();
+        final SubscriptionPlan plan = buildMonthlyDataPlan(
+                ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
         mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
                 mServiceContext.getOpPackageName());
 
@@ -1122,10 +1133,8 @@
         mService.updateNetworks();
 
         // Define simple data plan which gives us effectively 60MB/day
-        final SubscriptionPlan plan = SubscriptionPlan.Builder
-                .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
-                .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED)
-                .build();
+        final SubscriptionPlan plan = buildMonthlyDataPlan(
+                ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), DataUnit.MEGABYTES.toBytes(1800));
         mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
                 mServiceContext.getOpPackageName());
 
@@ -1497,21 +1506,13 @@
         final NetworkStatsHistory history = new NetworkStatsHistory(TimeUnit.HOURS.toMillis(1));
         final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 0);
         when(mStatsService.getNetworkTotalBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<Long>() {
-                    @Override
-                    public Long answer(InvocationOnMock invocation) throws Throwable {
-                        final NetworkStatsHistory.Entry entry = history.getValues(
-                                invocation.getArgument(1), invocation.getArgument(2), null);
-                        return entry.rxBytes + entry.txBytes;
-                    }
+                .thenAnswer(invocation -> {
+                    final NetworkStatsHistory.Entry entry = history.getValues(
+                            invocation.getArgument(1), invocation.getArgument(2), null);
+                    return entry.rxBytes + entry.txBytes;
                 });
         when(mStatsService.getNetworkUidBytes(any(), anyLong(), anyLong()))
-                .thenAnswer(new Answer<NetworkStats>() {
-                    @Override
-                    public NetworkStats answer(InvocationOnMock invocation) throws Throwable {
-                        return stats;
-                    }
-                });
+                .thenReturn(stats);
 
         // Get active mobile network in place
         expectMobileDefaults();
@@ -1535,17 +1536,18 @@
             mService.updateNetworks();
 
             // No quotas
-            assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
-            assertEquals(-1, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+            assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(OPPORTUNISTIC_QUOTA_UNKNOWN,
+                    internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
         }
 
         // Limited data plan
         {
-            final SubscriptionPlan plan = SubscriptionPlan.Builder
-                    .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
-                    .setDataLimit(DataUnit.MEGABYTES.toBytes(1800), LIMIT_BEHAVIOR_DISABLED)
-                    .build();
-            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+            final SubscriptionPlan plan = buildMonthlyDataPlan(
+                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
+                    DataUnit.MEGABYTES.toBytes(1800));
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
                     mServiceContext.getOpPackageName());
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
@@ -1561,13 +1563,45 @@
                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
         }
 
+        // Limited data plan, over quota
+        {
+            final SubscriptionPlan plan = buildMonthlyDataPlan(
+                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"),
+                    DataUnit.MEGABYTES.toBytes(100));
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
+                    mServiceContext.getOpPackageName());
+
+            reset(mTelephonyManager, mNetworkManager, mNotifManager);
+            expectMobileDefaults();
+
+            mService.updateNetworks();
+
+            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+        }
+
+        // Roaming
+        {
+            final SubscriptionPlan plan = buildMonthlyDataPlan(
+                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
+                    mServiceContext.getOpPackageName());
+
+            reset(mTelephonyManager, mNetworkManager, mNotifManager);
+            expectMobileDefaults();
+            expectNetworkState(true /* roaming */);
+
+            mService.updateNetworks();
+
+            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
+            assertEquals(0L, internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+        }
+
         // Unlimited data plan
         {
-            final SubscriptionPlan plan = SubscriptionPlan.Builder
-                    .createRecurringMonthly(ZonedDateTime.parse("2015-11-01T00:00:00.00Z"))
-                    .setDataLimit(BYTES_UNLIMITED, LIMIT_BEHAVIOR_DISABLED)
-                    .build();
-            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[] { plan },
+            final SubscriptionPlan plan = buildMonthlyDataPlan(
+                    ZonedDateTime.parse("2015-11-01T00:00:00.00Z"), BYTES_UNLIMITED);
+            mService.setSubscriptionPlans(TEST_SUB_ID, new SubscriptionPlan[]{plan},
                     mServiceContext.getOpPackageName());
 
             reset(mTelephonyManager, mNetworkManager, mNotifManager);
@@ -1580,9 +1614,27 @@
                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_JOBS));
             assertEquals(DataUnit.MEBIBYTES.toBytes(10),
                     internal.getSubscriptionOpportunisticQuota(net, QUOTA_TYPE_MULTIPATH));
+
+            // Capabilities change to roaming
+            final ConnectivityManager.NetworkCallback callback = mNetworkCallbackCaptor.getValue();
+            assertNotNull(callback);
+            expectNetworkState(true /* roaming */);
+            callback.onCapabilitiesChanged(
+                    new Network(TEST_NET_ID),
+                    buildNetworkCapabilities(TEST_SUB_ID, true /* roaming */));
+
+            assertEquals(0, internal.getSubscriptionOpportunisticQuota(
+                    new Network(TEST_NET_ID), NetworkPolicyManagerInternal.QUOTA_TYPE_MULTIPATH));
         }
     }
 
+    private SubscriptionPlan buildMonthlyDataPlan(ZonedDateTime start, long limitBytes) {
+        return SubscriptionPlan.Builder
+                .createRecurringMonthly(start)
+                .setDataLimit(limitBytes, LIMIT_BEHAVIOR_DISABLED)
+                .build();
+    }
+
     private ApplicationInfo buildApplicationInfo(String label) {
         final ApplicationInfo ai = new ApplicationInfo();
         ai.nonLocalizedLabel = label;
@@ -1602,9 +1654,12 @@
         return lp;
     }
 
-    private NetworkCapabilities buildNetworkCapabilities(int subId) {
+    private NetworkCapabilities buildNetworkCapabilities(int subId, boolean roaming) {
         final NetworkCapabilities nc = new NetworkCapabilities();
         nc.addTransportType(TRANSPORT_CELLULAR);
+        if (!roaming) {
+            nc.addCapability(NET_CAPABILITY_NOT_ROAMING);
+        }
         nc.setNetworkSpecifier(new StringNetworkSpecifier(String.valueOf(subId)));
         return nc;
     }
@@ -1658,16 +1713,20 @@
                 hasIt ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED);
     }
 
+    private void expectNetworkState(boolean roaming) throws Exception {
+        when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
+                new NetworkState(buildNetworkInfo(),
+                        buildLinkProperties(TEST_IFACE),
+                        buildNetworkCapabilities(TEST_SUB_ID, roaming),
+                        new Network(TEST_NET_ID), TEST_IMSI, null)
+        });
+    }
+
     private void expectMobileDefaults() throws Exception {
         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(
                 new int[] { TEST_SUB_ID });
         when(mTelephonyManager.getSubscriberId(TEST_SUB_ID)).thenReturn(TEST_IMSI);
-        when(mConnManager.getAllNetworkState()).thenReturn(new NetworkState[] {
-                new NetworkState(buildNetworkInfo(),
-                        buildLinkProperties(TEST_IFACE),
-                        buildNetworkCapabilities(TEST_SUB_ID),
-                        new Network(TEST_NET_ID), TEST_IMSI, null)
-        });
+        expectNetworkState(false /* roaming */);
     }
 
     private void verifyAdvisePersistThreshold() throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
index 1192114..592f7b1 100644
--- a/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/RecentTasksTest.java
@@ -39,6 +39,7 @@
 
 import static java.lang.Integer.MAX_VALUE;
 
+import android.annotation.TestApi;
 import android.app.ActivityManager;
 import android.app.ActivityManager.RecentTaskInfo;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -594,6 +595,23 @@
     }
 
     @Test
+    public void testRemovePackageByName() throws Exception {
+        // Add a number of tasks with the same package name
+        mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task1").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg2", ".Task2").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg3", ".Task3").build());
+        mRecentTasks.add(createTaskBuilder("com.android.pkg1", ".Task4").build());
+        mRecentTasks.removeTasksByPackageName("com.android.pkg1", TEST_USER_0_ID);
+
+        final ArrayList<TaskRecord> tasks = mRecentTasks.getRawTasks();
+        for (int i = 0; i < tasks.size(); i++) {
+            if (tasks.get(i).intent.getComponent().getPackageName().equals("com.android.pkg1")) {
+                fail("Expected com.android.pkg1 tasks to be removed");
+            }
+        }
+    }
+
+    @Test
     public void testNotRecentsComponent_denyApiAccess() throws Exception {
         doReturn(PackageManager.PERMISSION_DENIED).when(mService).checkPermission(anyString(),
                 anyInt(), anyInt());
@@ -694,8 +712,12 @@
     }
 
     private TaskBuilder createTaskBuilder(String className) {
+        return createTaskBuilder(mContext.getPackageName(), className);
+    }
+
+    private TaskBuilder createTaskBuilder(String packageName, String className) {
         return new TaskBuilder(mService.mStackSupervisor)
-                .setComponent(new ComponentName(mContext.getPackageName(), className))
+                .setComponent(new ComponentName(packageName, className))
                 .setStack(mStack)
                 .setTaskId(LAST_TASK_ID++)
                 .setUserId(TEST_USER_0_ID);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 2f2afd7..ceee60c 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -17,12 +17,15 @@
 package com.android.server.display;
 
 import android.content.Context;
+import android.hardware.display.BrightnessConfiguration;
+import android.hardware.display.Curve;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayViewport;
 import android.hardware.display.IVirtualDisplayCallback;
 import android.hardware.input.InputManagerInternal;
 import android.os.Handler;
 import android.os.IBinder;
+import android.os.UserHandle;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.view.SurfaceControl;
@@ -226,6 +229,62 @@
                 + " virtual display adapter");
     }
 
+    /**
+     * Tests that an exception is raised for too dark a brightness configuration.
+     */
+    public void testTooDarkBrightnessConfigurationThrowException() {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
+        float[] lux = minimumBrightnessCurve.getX();
+        float[] minimumNits = minimumBrightnessCurve.getY();
+        float[] nits = new float[minimumNits.length];
+        // For every control point, assert that making it slightly lower than the minimum throws an
+        // exception.
+        for (int i = 0; i < nits.length; i++) {
+            for (int j = 0; j < nits.length; j++) {
+                nits[j] = minimumNits[j];
+                if (j == i) {
+                    nits[j] -= 0.1f;
+                }
+                if (nits[j] < 0) {
+                    nits[j] = 0;
+                }
+            }
+            BrightnessConfiguration config =
+                    new BrightnessConfiguration.Builder(lux, nits).build();
+            Exception thrown = null;
+            try {
+                displayManager.validateBrightnessConfiguration(config);
+            } catch (IllegalArgumentException e) {
+                thrown = e;
+            }
+            assertNotNull("Building too dark a brightness configuration must throw an exception");
+        }
+    }
+
+    /**
+     * Tests that no exception is raised for not too dark a brightness configuration.
+     */
+    public void testBrightEnoughBrightnessConfigurationDoesNotThrowException() {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        Curve minimumBrightnessCurve = displayManager.getMinimumBrightnessCurveInternal();
+        float[] lux = minimumBrightnessCurve.getX();
+        float[] nits = minimumBrightnessCurve.getY();
+        BrightnessConfiguration config = new BrightnessConfiguration.Builder(lux, nits).build();
+        displayManager.validateBrightnessConfiguration(config);
+    }
+
+    /**
+     * Tests that null brightness configurations are alright.
+     */
+    public void testNullBrightnessConfiguration() {
+        DisplayManagerService displayManager =
+                new DisplayManagerService(mContext, mShortMockedInjector);
+        displayManager.validateBrightnessConfiguration(null);
+    }
+
     private void registerDefaultDisplays(DisplayManagerService displayManager) {
         Handler handler = displayManager.getDisplayHandler();
         // Would prefer to call displayManager.onStart() directly here but it performs binderService
diff --git a/services/tests/uiservicestests/AndroidTest.xml b/services/tests/uiservicestests/AndroidTest.xml
index d3b9d4a..11e8f09 100644
--- a/services/tests/uiservicestests/AndroidTest.xml
+++ b/services/tests/uiservicestests/AndroidTest.xml
@@ -24,5 +24,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.uiservices" />
         <option name="runner" value="android.testing.TestableInstrumentation" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 3acc277..d02a983 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -201,12 +201,12 @@
                 AudioAttributes.USAGE_MEDIA);
         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
                 AudioAttributes.USAGE_GAME);
+        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(false,
+                AudioAttributes.USAGE_UNKNOWN);
 
         // Alarms only will silence system noises (but not vibrations)
         verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
                 AudioAttributes.USAGE_ASSISTANCE_SONIFICATION, AppOpsManager.OP_PLAY_AUDIO);
-        verify(mZenModeHelperSpy, atLeastOnce()).applyRestrictions(true,
-                AudioAttributes.USAGE_UNKNOWN);
     }
 
     @Test
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 754fe68..a9389be 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -477,6 +477,9 @@
      * <p>
      * Contains {@link #EXTRA_SUBSCRIPTION_INDEX} to indicate which subscription
      * the user is interested in.
+     * <p>
+     * Receivers should protect themselves by checking that the sender holds the
+     * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @SystemApi
@@ -1719,6 +1722,8 @@
      * </ul>
      *
      * @param subId the subscriber this relationship applies to
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) {
@@ -1744,10 +1749,13 @@
      * {@link CarrierConfigManager#KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING}.
      * </ul>
      *
-     * @param subId the subscriber this relationship applies to
+     * @param subId the subscriber this relationship applies to. An empty list
+     *            may be sent to clear any existing plans.
      * @param plans the list of plans. The first plan is always the primary and
      *            most important plan. Any additional plans are secondary and
      *            may not be displayed or used by decision making logic.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) {
@@ -1788,6 +1796,8 @@
      *            be automatically cleared, or {@code 0} to leave in the
      *            requested state until explicitly cleared, or the next reboot,
      *            whichever happens first.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered,
@@ -1822,6 +1832,8 @@
      *            be automatically cleared, or {@code 0} to leave in the
      *            requested state until explicitly cleared, or the next reboot,
      *            whichever happens first.
+     * @throws SecurityException if the caller doesn't meet the requirements
+     *             outlined above.
      */
     @SystemApi
     public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested,
diff --git a/telephony/java/android/telephony/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java
index 4ffb70b..ef2a364 100644
--- a/telephony/java/android/telephony/SubscriptionPlan.java
+++ b/telephony/java/android/telephony/SubscriptionPlan.java
@@ -24,7 +24,7 @@
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.util.Pair;
+import android.util.Range;
 import android.util.RecurrenceRule;
 
 import com.android.internal.util.Preconditions;
@@ -209,7 +209,7 @@
      * any recurrence rules. The iterator starts from the currently active cycle
      * and walks backwards through time.
      */
-    public Iterator<Pair<ZonedDateTime, ZonedDateTime>> cycleIterator() {
+    public Iterator<Range<ZonedDateTime>> cycleIterator() {
         return cycleRule.cycleIterator();
     }
 
@@ -227,6 +227,9 @@
         /**
          * Start defining a {@link SubscriptionPlan} that covers a very specific
          * window of time, and never automatically recurs.
+         *
+         * @param start The exact time at which the plan starts.
+         * @param end The exact time at which the plan ends.
          */
         public static Builder createNonrecurring(ZonedDateTime start, ZonedDateTime end) {
             if (!end.isAfter(start)) {
@@ -237,28 +240,40 @@
         }
 
         /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every month. It will always recur on the same day of a
-         * particular month. When a particular month ends before the defined
-         * recurrence day, the plan will recur on the last instant of that
-         * month.
+         * Start defining a {@link SubscriptionPlan} that starts at a specific
+         * time, and automatically recurs after each specific period of time,
+         * repeating indefinitely.
+         * <p>
+         * When the given period is set to exactly one month, the plan will
+         * always recur on the day of the month defined by
+         * {@link ZonedDateTime#getDayOfMonth()}. When a particular month ends
+         * before this day, the plan will recur on the last possible instant of
+         * that month.
+         *
+         * @param start The exact time at which the plan starts.
+         * @param period The period after which the plan automatically recurs.
          */
+        public static Builder createRecurring(ZonedDateTime start, Period period) {
+            return new Builder(start, null, period);
+        }
+
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringMonthly(ZonedDateTime start) {
             return new Builder(start, null, Period.ofMonths(1));
         }
 
-        /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every week.
-         */
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringWeekly(ZonedDateTime start) {
             return new Builder(start, null, Period.ofDays(7));
         }
 
-        /**
-         * Start defining a {@link SubscriptionPlan} that will recur
-         * automatically every day.
-         */
+        /** {@hide} */
+        @SystemApi
+        @Deprecated
         public static Builder createRecurringDaily(ZonedDateTime start) {
             return new Builder(start, null, Period.ofDays(1));
         }
diff --git a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
index 2f52c0a..dfb6e2c 100644
--- a/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
+++ b/telephony/java/android/telephony/ims/stub/ImsFeatureConfiguration.java
@@ -77,6 +77,11 @@
             result = 31 * result + featureType;
             return result;
         }
+
+        @Override
+        public String toString() {
+            return "{s=" + slotId + ", f=" + featureType + "}";
+        }
     }
 
     /**
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 03fc84d..7e8b2de 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -829,6 +829,16 @@
     boolean isResolvingImsBinding();
 
     /**
+    *  @return true if the ImsService to bind to for the slot id specified was set, false otherwise.
+    */
+    boolean setImsService(int slotId, boolean isCarrierImsService, String packageName);
+
+    /**
+    * @return the package name of the carrier/device ImsService associated with this slot.
+    */
+    String getImsService(int slotId, boolean isCarrierImsService);
+
+    /**
      * Set the network selection mode to automatic.
      *
      * @param subId the id of the subscription to update.
diff --git a/tests/DexLoggerIntegrationTests/AndroidTest.xml b/tests/DexLoggerIntegrationTests/AndroidTest.xml
index 8ed19f8..fb1bef6 100644
--- a/tests/DexLoggerIntegrationTests/AndroidTest.xml
+++ b/tests/DexLoggerIntegrationTests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.frameworks.dexloggertest"/>
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/UsbTests/AndroidTest.xml b/tests/UsbTests/AndroidTest.xml
index 0b623fb..4affad3 100644
--- a/tests/UsbTests/AndroidTest.xml
+++ b/tests/UsbTests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest">
         <option name="package" value="com.android.server.usb"/>
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
+        <option name="hidden-api-checks" value="false"/>
     </test>
-</configuration>
\ No newline at end of file
+</configuration>
diff --git a/tests/net/AndroidTest.xml b/tests/net/AndroidTest.xml
index f8ecc6b..6e020a3 100644
--- a/tests/net/AndroidTest.xml
+++ b/tests/net/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.net" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index b0e11c4..482d6e1 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -161,6 +161,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -879,6 +880,10 @@
             return mMetricsService;
         }
 
+        @Override
+        protected void registerNetdEventCallback() {
+        }
+
         public WrappedNetworkMonitor getLastCreatedWrappedNetworkMonitor() {
             return mLastCreatedNetworkMonitor;
         }
@@ -3777,6 +3782,11 @@
         // The default on Android is opportunistic mode ("Automatic").
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
 
+        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+        final NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR).build();
+        mCm.requestNetwork(cellRequest, cellNetworkCallback);
+
         mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
         waitForIdle();
         // CS tells netd about the empty DNS config for this network.
@@ -3812,6 +3822,14 @@
         assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
         reset(mNetworkManagementService);
+        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
+                mCellNetworkAgent);
+        CallbackInfo cbi = cellNetworkCallback.expectCallback(
+                CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OFF, "ignored.example.com");
         verify(mNetworkManagementService, times(1)).setDnsConfigurationForNetwork(
@@ -3821,6 +3839,7 @@
         assertTrue(ArrayUtils.containsAll(mStringArrayCaptor.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
         reset(mNetworkManagementService);
+        cellNetworkCallback.assertNoCallback();
 
         setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
         verify(mNetworkManagementService, atLeastOnce()).setDnsConfigurationForNetwork(
@@ -3833,8 +3852,112 @@
         assertTrue(ArrayUtils.containsAll(tlsServers.getValue(),
                 new String[]{"2001:db8::1", "192.0.2.1"}));
         reset(mNetworkManagementService);
+        cellNetworkCallback.assertNoCallback();
 
-        // Can't test strict mode without properly mocking out the DNS lookups.
+        setPrivateDnsSettings(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, "strict.example.com");
+        // Can't test dns configuration for strict mode without properly mocking
+        // out the DNS lookups, but can test that LinkProperties is updated.
+        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertEquals("strict.example.com", ((LinkProperties)cbi.arg).getPrivateDnsServerName());
+    }
+
+    @Test
+    public void testLinkPropertiesWithPrivateDnsValidationEvents() throws Exception {
+        // The default on Android is opportunistic mode ("Automatic").
+        setPrivateDnsSettings(PRIVATE_DNS_MODE_OPPORTUNISTIC, "ignored.example.com");
+
+        final TestNetworkCallback cellNetworkCallback = new TestNetworkCallback();
+        final NetworkRequest cellRequest = new NetworkRequest.Builder()
+                .addTransportType(TRANSPORT_CELLULAR).build();
+        mCm.requestNetwork(cellRequest, cellNetworkCallback);
+
+        mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
+        waitForIdle();
+        LinkProperties lp = new LinkProperties();
+        mCellNetworkAgent.sendLinkProperties(lp);
+        mCellNetworkAgent.connect(false);
+        waitForIdle();
+        cellNetworkCallback.expectCallback(CallbackState.AVAILABLE, mCellNetworkAgent);
+        cellNetworkCallback.expectCallback(CallbackState.NETWORK_CAPABILITIES,
+                mCellNetworkAgent);
+        CallbackInfo cbi = cellNetworkCallback.expectCallback(
+                CallbackState.LINK_PROPERTIES, mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        Set<InetAddress> dnsServers = new HashSet<>();
+        checkDnsServers(cbi.arg, dnsServers);
+
+        // Send a validation event for a server that is not part of the current
+        // resolver config. The validation event should be ignored.
+        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
+                mCellNetworkAgent.getNetwork().netId, "", "145.100.185.18", true);
+        cellNetworkCallback.assertNoCallback();
+
+        // Add a dns server to the LinkProperties.
+        LinkProperties lp2 = new LinkProperties(lp);
+        lp2.addDnsServer(InetAddress.getByName("145.100.185.16"));
+        mCellNetworkAgent.sendLinkProperties(lp2);
+        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        dnsServers.add(InetAddress.getByName("145.100.185.16"));
+        checkDnsServers(cbi.arg, dnsServers);
+
+        // Send a validation event containing a hostname that is not part of
+        // the current resolver config. The validation event should be ignored.
+        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
+                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "hostname", true);
+        cellNetworkCallback.assertNoCallback();
+
+        // Send a validation event where validation failed.
+        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
+                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", false);
+        cellNetworkCallback.assertNoCallback();
+
+        // Send a validation event where validation succeeded for a server in
+        // the current resolver config. A LinkProperties callback with updated
+        // private dns fields should be sent.
+        mService.mNetdEventCallback.onPrivateDnsValidationEvent(
+                mCellNetworkAgent.getNetwork().netId, "145.100.185.16", "", true);
+        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        checkDnsServers(cbi.arg, dnsServers);
+
+        // The private dns fields in LinkProperties should be preserved when
+        // the network agent sends unrelated changes.
+        LinkProperties lp3 = new LinkProperties(lp2);
+        lp3.setMtu(1300);
+        mCellNetworkAgent.sendLinkProperties(lp3);
+        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertTrue(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        checkDnsServers(cbi.arg, dnsServers);
+        assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
+
+        // Removing the only validated server should affect the private dns
+        // fields in LinkProperties.
+        LinkProperties lp4 = new LinkProperties(lp3);
+        lp4.removeDnsServer(InetAddress.getByName("145.100.185.16"));
+        mCellNetworkAgent.sendLinkProperties(lp4);
+        cbi = cellNetworkCallback.expectCallback(CallbackState.LINK_PROPERTIES,
+                mCellNetworkAgent);
+        cellNetworkCallback.assertNoCallback();
+        assertFalse(((LinkProperties)cbi.arg).isPrivateDnsActive());
+        assertNull(((LinkProperties)cbi.arg).getPrivateDnsServerName());
+        dnsServers.remove(InetAddress.getByName("145.100.185.16"));
+        checkDnsServers(cbi.arg, dnsServers);
+        assertEquals(1300, ((LinkProperties)cbi.arg).getMtu());
     }
 
     private void checkDirectlyConnectedRoutes(Object callbackObj,
@@ -3854,6 +3977,13 @@
         assertTrue(observedRoutes.containsAll(expectedRoutes));
     }
 
+    private static void checkDnsServers(Object callbackObj, Set<InetAddress> dnsServers) {
+        assertTrue(callbackObj instanceof LinkProperties);
+        LinkProperties lp = (LinkProperties) callbackObj;
+        assertEquals(dnsServers.size(), lp.getDnsServers().size());
+        assertTrue(lp.getDnsServers().containsAll(dnsServers));
+    }
+
     private static <T> void assertEmpty(T[] ts) {
         int length = ts.length;
         assertEquals("expected empty array, but length was " + length, 0, length);
diff --git a/tests/net/java/com/android/server/connectivity/DnsManagerTest.java b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
new file mode 100644
index 0000000..bcd8bf3
--- /dev/null
+++ b/tests/net/java/com/android/server/connectivity/DnsManagerTest.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2018, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.connectivity;
+
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
+import static android.net.ConnectivityManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.os.INetworkManagementService;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.server.connectivity.MockableSystemProperties;
+
+import java.net.InetAddress;
+
+import org.junit.runner.RunWith;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link DnsManager}.
+ *
+ * Build, install and run with:
+ *  runtest frameworks-net -c com.android.server.connectivity.DnsManagerTest
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class DnsManagerTest {
+    static final int TEST_NETID = 100;
+    static final int TEST_NETID_ALTERNATE = 101;
+    static final int TEST_NETID_UNTRACKED = 102;
+    final boolean IS_DEFAULT = true;
+    final boolean NOT_DEFAULT = false;
+
+    DnsManager mDnsManager;
+    MockContentResolver mContentResolver;
+
+    @Mock Context mCtx;
+    @Mock INetworkManagementService mNMService;
+    @Mock MockableSystemProperties mSystemProperties;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mContentResolver = new MockContentResolver();
+        mContentResolver.addProvider(Settings.AUTHORITY,
+                new FakeSettingsProvider());
+        when(mCtx.getContentResolver()).thenReturn(mContentResolver);
+        mDnsManager = new DnsManager(mCtx, mNMService, mSystemProperties);
+
+        // Clear the private DNS settings
+        Settings.Global.putString(mContentResolver,
+                Settings.Global.PRIVATE_DNS_MODE, "");
+        Settings.Global.putString(mContentResolver,
+                Settings.Global.PRIVATE_DNS_SPECIFIER, "");
+    }
+
+    @Test
+    public void testTrackedValidationUpdates() throws Exception {
+        mDnsManager.updatePrivateDns(new Network(TEST_NETID),
+                mDnsManager.getPrivateDnsConfig());
+        mDnsManager.updatePrivateDns(new Network(TEST_NETID_ALTERNATE),
+                mDnsManager.getPrivateDnsConfig());
+        LinkProperties lp = new LinkProperties();
+        lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
+        lp.addDnsServer(InetAddress.getByName("4.4.4.4"));
+
+        // Send a validation event that is tracked on the alternate netId
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID_ALTERNATE, lp, NOT_DEFAULT);
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_ALTERNATE,
+                InetAddress.parseNumericAddress("4.4.4.4"), "", true));
+        LinkProperties fixedLp = new LinkProperties(lp);
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
+        assertFalse(fixedLp.isPrivateDnsActive());
+        assertNull(fixedLp.getPrivateDnsServerName());
+        fixedLp = new LinkProperties(lp);
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID_ALTERNATE, fixedLp);
+        assertTrue(fixedLp.isPrivateDnsActive());
+        assertNull(fixedLp.getPrivateDnsServerName());
+
+        // Switch to strict mode
+        Settings.Global.putString(mContentResolver,
+                Settings.Global.PRIVATE_DNS_MODE,
+                PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
+        Settings.Global.putString(mContentResolver,
+                Settings.Global.PRIVATE_DNS_SPECIFIER, "strictmode.com");
+        mDnsManager.updatePrivateDns(new Network(TEST_NETID),
+                mDnsManager.getPrivateDnsConfig());
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
+        fixedLp = new LinkProperties(lp);
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, fixedLp);
+        assertTrue(fixedLp.isPrivateDnsActive());
+        assertEquals("strictmode.com", fixedLp.getPrivateDnsServerName());
+        fixedLp = new LinkProperties(lp);
+    }
+
+    @Test
+    public void testIgnoreUntrackedValidationUpdates() throws Exception {
+        // The PrivateDnsConfig map is empty, so no validation events will
+        // be tracked.
+        LinkProperties lp = new LinkProperties();
+        lp.addDnsServer(InetAddress.getByName("3.3.3.3"));
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Validation event has untracked netId
+        mDnsManager.updatePrivateDns(new Network(TEST_NETID),
+                mDnsManager.getPrivateDnsConfig());
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID_UNTRACKED,
+                InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Validation event has untracked ipAddress
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("4.4.4.4"), "", true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Validation event has untracked hostname
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("3.3.3.3"), "hostname",
+                true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Validation event failed
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("3.3.3.3"), "", false));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Network removed
+        mDnsManager.removeNetwork(new Network(TEST_NETID));
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+
+        // Turn private DNS mode off
+        Settings.Global.putString(mContentResolver,
+                Settings.Global.PRIVATE_DNS_MODE, PRIVATE_DNS_MODE_OFF);
+        mDnsManager.updatePrivateDns(new Network(TEST_NETID),
+                mDnsManager.getPrivateDnsConfig());
+        mDnsManager.setDnsConfigurationForNetwork(TEST_NETID, lp, IS_DEFAULT);
+        mDnsManager.updatePrivateDnsValidation(
+                new DnsManager.PrivateDnsValidationUpdate(TEST_NETID,
+                InetAddress.parseNumericAddress("3.3.3.3"), "", true));
+        mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
+        assertFalse(lp.isPrivateDnsActive());
+        assertNull(lp.getPrivateDnsServerName());
+    }
+}
diff --git a/wifi/tests/AndroidTest.xml b/wifi/tests/AndroidTest.xml
index 764eb2b..45c7a17 100644
--- a/wifi/tests/AndroidTest.xml
+++ b/wifi/tests/AndroidTest.xml
@@ -23,5 +23,6 @@
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.wifi.test" />
         <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
     </test>
 </configuration>