Merge "Remove unused string for Bluetooth Active device summary" into pi-dev
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 1abb94c..7bc997d 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -211,6 +211,7 @@
 Landroid/app/ApplicationPackageManager;->mPM:Landroid/content/pm/IPackageManager;
 Landroid/app/ApplicationPackageManager;->shouldShowRequestPermissionRationale(Ljava/lang/String;)Z
 Landroid/app/AppOpsManager$OpEntry;->getDuration()I
+Landroid/app/AppOpsManager$OpEntry;->getMode()I
 Landroid/app/AppOpsManager$OpEntry;->getRejectTime()J
 Landroid/app/AppOpsManager;->checkOp(IILjava/lang/String;)I
 Landroid/app/AppOpsManager;->checkOpNoThrow(IILjava/lang/String;)I
@@ -285,6 +286,7 @@
 Landroid/app/DownloadManager;->setAccessFilename(Z)V
 Landroid/app/Fragment;->mChildFragmentManager:Landroid/app/FragmentManagerImpl;
 Landroid/app/Fragment;->mWho:Ljava/lang/String;
+Landroid/app/FragmentManagerImpl;->loadAnimator(Landroid/app/Fragment;IZI)Landroid/animation/Animator;
 Landroid/app/FragmentManagerImpl;->mAdded:Ljava/util/ArrayList;
 Landroid/app/FragmentManagerImpl;->mStateSaved:Z
 Landroid/app/FragmentManagerImpl;->noteStateNotSaved()V
@@ -302,6 +304,7 @@
 Landroid/app/IActivityManager;->getConfiguration()Landroid/content/res/Configuration;
 Landroid/app/IActivityManager;->getIntentSender(ILjava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I[Landroid/content/Intent;[Ljava/lang/String;ILandroid/os/Bundle;I)Landroid/content/IIntentSender;
 Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
+Landroid/app/IActivityManager;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
 Landroid/app/IActivityManager;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
 Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
 Landroid/app/IActivityManager;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
@@ -695,6 +698,7 @@
 Landroid/content/pm/IPackageDataObserver$Stub$Proxy;->mRemote:Landroid/os/IBinder;
 Landroid/content/pm/IPackageDataObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDataObserver;
 Landroid/content/pm/IPackageDataObserver;->onRemoveCompleted(Ljava/lang/String;Z)V
+Landroid/content/pm/IPackageDeleteObserver$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageDeleteObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/pm/IPackageDeleteObserver;
 Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/content/pm/IPackageDeleteObserver2$Stub$Proxy;->mRemote:Landroid/os/IBinder;
@@ -767,6 +771,7 @@
 Landroid/content/pm/PackageInstaller$SessionParams;->sizeBytes:J
 Landroid/content/pm/PackageItemInfo;->setForceSafeLabels(Z)V
 Landroid/content/pm/PackageManager;->buildRequestPermissionsIntent([Ljava/lang/String;)Landroid/content/Intent;
+Landroid/content/pm/PackageManager;->deletePackage(Ljava/lang/String;Landroid/content/pm/IPackageDeleteObserver;I)V
 Landroid/content/pm/PackageManager;->freeStorage(JLandroid/content/IntentSender;)V
 Landroid/content/pm/PackageManager;->freeStorage(Ljava/lang/String;JLandroid/content/IntentSender;)V
 Landroid/content/pm/PackageManager;->freeStorageAndNotify(JLandroid/content/pm/IPackageDataObserver;)V
@@ -843,6 +848,7 @@
 Landroid/content/pm/Signature;->getPublicKey()Ljava/security/PublicKey;
 Landroid/content/pm/UserInfo;-><init>(ILjava/lang/String;I)V
 Landroid/content/pm/UserInfo;->FLAG_PRIMARY:I
+Landroid/content/pm/UserInfo;->getUserHandle()Landroid/os/UserHandle;
 Landroid/content/pm/UserInfo;->id:I
 Landroid/content/pm/UserInfo;->isPrimary()Z
 Landroid/content/pm/UserInfo;->serialNumber:I
@@ -961,6 +967,7 @@
 Landroid/database/AbstractCursor;->mExtras:Landroid/os/Bundle;
 Landroid/database/AbstractCursor;->mNotifyUri:Landroid/net/Uri;
 Landroid/database/AbstractWindowedCursor;->clearOrCreateWindow(Ljava/lang/String;)V
+Landroid/database/AbstractWindowedCursor;->closeWindow()V
 Landroid/database/CursorWindow;->mWindowPtr:J
 Landroid/database/CursorWindow;->sCursorWindowSize:I
 Landroid/database/CursorWindow;->sWindowToPidMap:Landroid/util/LongSparseArray;
@@ -969,6 +976,7 @@
 Landroid/database/sqlite/SQLiteCustomFunction;->name:Ljava/lang/String;
 Landroid/database/sqlite/SQLiteCustomFunction;->numArgs:I
 Landroid/database/sqlite/SQLiteDatabase;->CONFLICT_VALUES:[Ljava/lang/String;
+Landroid/database/sqlite/SQLiteDatabase;->getThreadSession()Landroid/database/sqlite/SQLiteSession;
 Landroid/database/sqlite/SQLiteDatabase;->mConfigurationLocked:Landroid/database/sqlite/SQLiteDatabaseConfiguration;
 Landroid/database/sqlite/SQLiteDatabase;->mConnectionPoolLocked:Landroid/database/sqlite/SQLiteConnectionPool;
 Landroid/database/sqlite/SQLiteDatabase;->reopenReadWrite()V
@@ -977,6 +985,7 @@
 Landroid/database/sqlite/SQLiteDebug$PagerStats;->memoryUsed:I
 Landroid/database/sqlite/SQLiteDebug$PagerStats;->pageCacheOverflow:I
 Landroid/database/sqlite/SQLiteOpenHelper;->mName:Ljava/lang/String;
+Landroid/database/sqlite/SQLiteSession;->beginTransaction(ILandroid/database/sqlite/SQLiteTransactionListener;ILandroid/os/CancellationSignal;)V
 Landroid/database/sqlite/SQLiteStatement;-><init>(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;[Ljava/lang/Object;)V
 Landroid/ddm/DdmHandleAppName;->getAppName()Ljava/lang/String;
 Landroid/ddm/DdmHandleAppName;->setAppName(Ljava/lang/String;I)V
@@ -1044,6 +1053,7 @@
 Landroid/graphics/drawable/GradientDrawable;->getOpticalInsets()Landroid/graphics/Insets;
 Landroid/graphics/drawable/GradientDrawable;->mGradientState:Landroid/graphics/drawable/GradientDrawable$GradientState;
 Landroid/graphics/drawable/GradientDrawable;->mPadding:Landroid/graphics/Rect;
+Landroid/graphics/drawable/Icon;->createWithResource(Landroid/content/res/Resources;I)Landroid/graphics/drawable/Icon;
 Landroid/graphics/drawable/Icon;->getBitmap()Landroid/graphics/Bitmap;
 Landroid/graphics/drawable/Icon;->getDataBytes()[B
 Landroid/graphics/drawable/Icon;->getDataLength()I
@@ -1227,6 +1237,7 @@
 Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->data:[B
 Landroid/hardware/soundtrigger/SoundTrigger$RecognitionConfig;->keyphrases:[Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseRecognitionExtra;
 Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;-><init>(IIZIIIZLandroid/media/AudioFormat;[B)V
+Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->captureSession:I
 Landroid/hardware/soundtrigger/SoundTrigger$RecognitionEvent;->data:[B
 Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->data:[B
 Landroid/hardware/soundtrigger/SoundTrigger$SoundModel;->uuid:Ljava/util/UUID;
@@ -1774,6 +1785,7 @@
 Landroid/os/HwParcel;-><init>(Z)V
 Landroid/os/HwRemoteBinder;-><init>()V
 Landroid/os/IBatteryPropertiesRegistrar$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Landroid/os/IDeviceIdleController;->getAppIdTempWhitelist()[I
 Landroid/os/IPermissionController$Stub$Proxy;->checkPermission(Ljava/lang/String;II)Z
 Landroid/os/IPermissionController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/os/IPermissionController;
 Landroid/os/IPowerManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -1829,6 +1841,7 @@
 Landroid/os/Process;->getTotalMemory()J
 Landroid/os/Process;->getUidForPid(I)I
 Landroid/os/Process;->isIsolated(I)Z
+Landroid/os/Process;->parseProcLine([BII[I[Ljava/lang/String;[J[F)Z
 Landroid/os/Process;->readProcFile(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z
 Landroid/os/Process;->readProcLines(Ljava/lang/String;[Ljava/lang/String;[J)V
 Landroid/os/Process;->setArgV0(Ljava/lang/String;)V
@@ -1868,6 +1881,7 @@
 Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
 Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String;
 Landroid/os/storage/StorageVolume;->mPath:Ljava/io/File;
+Landroid/os/storage/StorageVolume;->mRemovable:Z
 Landroid/os/storage/VolumeInfo;->buildStorageVolume(Landroid/content/Context;IZ)Landroid/os/storage/StorageVolume;
 Landroid/os/storage/VolumeInfo;->getDisk()Landroid/os/storage/DiskInfo;
 Landroid/os/storage/VolumeInfo;->getEnvironmentForState(I)Ljava/lang/String;
@@ -1885,6 +1899,7 @@
 Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span;
 Landroid/os/StrictMode;->getThreadPolicyMask()I
 Landroid/os/StrictMode;->onBinderStrictModePolicyChange(I)V
+Landroid/os/StrictMode;->sLastVmViolationTime:Ljava/util/HashMap;
 Landroid/os/StrictMode;->violationsBeingTimed:Ljava/lang/ThreadLocal;
 Landroid/os/SystemProperties;-><init>()V
 Landroid/os/SystemProperties;->addChangeCallback(Ljava/lang/Runnable;)V
@@ -2376,6 +2391,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;->deleteMessageFromIcc(I)Z
+Landroid/telephony/SmsManager;->getAllMessagesFromIcc()Ljava/util/ArrayList;
 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
@@ -2402,6 +2419,7 @@
 Landroid/telephony/TelephonyManager;->getITelephony()Lcom/android/internal/telephony/ITelephony;
 Landroid/telephony/TelephonyManager;->getLine1Number(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getMultiSimConfiguration()Landroid/telephony/TelephonyManager$MultiSimVariants;
+Landroid/telephony/TelephonyManager;->getNai(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkClass(I)I
 Landroid/telephony/TelephonyManager;->getNetworkCountryIso(I)Ljava/lang/String;
 Landroid/telephony/TelephonyManager;->getNetworkOperator(I)Ljava/lang/String;
@@ -2629,6 +2647,7 @@
 Landroid/view/IWindowManager;->getAnimationScale(I)F
 Landroid/view/IWindowManager;->hasNavigationBar()Z
 Landroid/view/IWindowManager;->setAnimationScale(IF)V
+Landroid/view/IWindowManager;->setAnimationScales([F)V
 Landroid/view/IWindowManager;->setShelfHeight(ZI)V
 Landroid/view/IWindowManager;->setStrictModeVisualIndicatorPreference(Ljava/lang/String;)V
 Landroid/view/IWindowSession$Stub$Proxy;->relayout(Landroid/view/IWindow;ILandroid/view/WindowManager$LayoutParams;IIIIJLandroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/view/DisplayCutout$ParcelableWrapper;Landroid/util/MergedConfiguration;Landroid/view/Surface;)I
@@ -2884,6 +2903,7 @@
 Landroid/view/ViewTreeObserver$InternalInsetsInfo;->TOUCHABLE_INSETS_REGION:I
 Landroid/view/ViewTreeObserver;->addOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
 Landroid/view/ViewTreeObserver;->removeOnComputeInternalInsetsListener(Landroid/view/ViewTreeObserver$OnComputeInternalInsetsListener;)V
+Landroid/view/Window;->addPrivateFlags(I)V
 Landroid/view/Window;->mAppName:Ljava/lang/String;
 Landroid/view/Window;->mAppToken:Landroid/os/IBinder;
 Landroid/view/Window;->mCallback:Landroid/view/Window$Callback;
@@ -3196,6 +3216,7 @@
 Landroid/widget/TextView;->mSingleLine:Z
 Landroid/widget/TextView;->mText:Ljava/lang/CharSequence;
 Landroid/widget/TextView;->mTextPaint:Landroid/text/TextPaint;
+Landroid/widget/TextView;->mTextSelectHandleLeftRes:I
 Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;Landroid/widget/TextView$BufferType;ZI)V
 Landroid/widget/Toast$TN;->mNextView:Landroid/view/View;
 Landroid/widget/Toast$TN;->mParams:Landroid/view/WindowManager$LayoutParams;
@@ -3301,9 +3322,13 @@
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
 Lcom/android/internal/app/IVoiceInteractionManagerService;->getKeyphraseSoundModel(ILjava/lang/String;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;
 Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
+Lcom/android/internal/content/PackageMonitor;->onPackageRemoved(Ljava/lang/String;I)V
+Lcom/android/internal/content/PackageMonitor;->register(Landroid/content/Context;Landroid/os/Looper;Z)V
 Lcom/android/internal/content/ReferrerIntent;-><init>(Landroid/content/Intent;Ljava/lang/String;)V
 Lcom/android/internal/content/ReferrerIntent;->mReferrer:Ljava/lang/String;
 Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
+Lcom/android/internal/logging/MetricsLogger;-><init>()V
+Lcom/android/internal/logging/MetricsLogger;->write(Landroid/metrics/LogMaker;)V
 Lcom/android/internal/os/BatterySipper;-><init>(Lcom/android/internal/os/BatterySipper$DrainType;Landroid/os/BatteryStats$Uid;D)V
 Lcom/android/internal/os/BatterySipper;->add(Lcom/android/internal/os/BatterySipper;)V
 Lcom/android/internal/os/BatterySipper;->drainType:Lcom/android/internal/os/BatterySipper$DrainType;
@@ -3676,6 +3701,7 @@
 Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
 Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J
 Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
+Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
 Ldalvik/system/BaseDexClassLoader;->addDexPath(Ljava/lang/String;)V
 Ldalvik/system/BaseDexClassLoader;->getLdLibraryPath()Ljava/lang/String;
 Ldalvik/system/BaseDexClassLoader;->pathList:Ldalvik/system/DexPathList;
@@ -3701,6 +3727,7 @@
 Ldalvik/system/DexPathList$NativeLibraryElement;->path:Ljava/io/File;
 Ldalvik/system/DexPathList;-><init>(Ljava/lang/ClassLoader;Ljava/lang/String;Ljava/lang/String;Ljava/io/File;)V
 Ldalvik/system/DexPathList;->addDexPath(Ljava/lang/String;Ljava/io/File;)V
+Ldalvik/system/DexPathList;->addNativePath(Ljava/util/Collection;)V
 Ldalvik/system/DexPathList;->definingContext:Ljava/lang/ClassLoader;
 Ldalvik/system/DexPathList;->dexElements:[Ldalvik/system/DexPathList$Element;
 Ldalvik/system/DexPathList;->loadDexFile(Ljava/io/File;Ljava/io/File;Ljava/lang/ClassLoader;[Ldalvik/system/DexPathList$Element;)Ldalvik/system/DexFile;
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 037a87b..3f66747 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2683,7 +2683,7 @@
         // TODO(lifecycler): Can't switch to use #handleLaunchActivity() because it will try to
         // call #reportSizeConfigurations(), but the server might not know anything about the
         // activity if it was launched from LocalAcvitivyManager.
-        return performLaunchActivity(r);
+        return performLaunchActivity(r, null /* customIntent */);
     }
 
     public final Activity getActivity(IBinder token) {
@@ -2768,7 +2768,7 @@
     }
 
     /**  Core implementation of activity launch. */
-    private Activity performLaunchActivity(ActivityClientRecord r) {
+    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
         ActivityInfo aInfo = r.activityInfo;
         if (r.packageInfo == null) {
             r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
@@ -2838,6 +2838,9 @@
                         r.embeddedID, r.lastNonConfigurationInstances, config,
                         r.referrer, r.voiceInteractor, window, r.configCallback);
 
+                if (customIntent != null) {
+                    activity.mIntent = customIntent;
+                }
                 r.lastNonConfigurationInstances = null;
                 checkAndBlockForNetworkAccess();
                 activity.mStartedActivity = false;
@@ -2982,7 +2985,7 @@
      */
     @Override
     public Activity handleLaunchActivity(ActivityClientRecord r,
-            PendingTransactionActions pendingActions) {
+            PendingTransactionActions pendingActions, Intent customIntent) {
         // If we are getting ready to gc after going to the background, well
         // we are back active so skip it.
         unscheduleGcIdler();
@@ -3005,7 +3008,7 @@
         }
         WindowManagerGlobal.initialize();
 
-        final Activity a = performLaunchActivity(r);
+        final Activity a = performLaunchActivity(r, customIntent);
 
         if (a != null) {
             r.createdConfig = new Configuration(mConfiguration);
@@ -4699,6 +4702,8 @@
             List<ResultInfo> pendingResults, List<ReferrerIntent> pendingIntents,
             PendingTransactionActions pendingActions, boolean startsNotResumed,
             Configuration overrideConfig, String reason) {
+        // Preserve last used intent, it may be set from Activity#setIntent().
+        final Intent customIntent = r.activity.mIntent;
         // Need to ensure state is saved.
         if (!r.paused) {
             performPauseActivity(r, false, reason, null /* pendingActions */);
@@ -4731,7 +4736,7 @@
         r.startsNotResumed = startsNotResumed;
         r.overrideConfig = overrideConfig;
 
-        handleLaunchActivity(r, pendingActions);
+        handleLaunchActivity(r, pendingActions, customIntent);
     }
 
     @Override
@@ -5333,8 +5338,8 @@
                                         }
                                     }
                                 }
-                                final List<String> oldPaths =
-                                        sPackageManager.getPreviousCodePaths(packageName);
+                                final ArrayList<String> oldPaths = new ArrayList<>();
+                                LoadedApk.makePaths(this, pkgInfo.getApplicationInfo(), oldPaths);
                                 pkgInfo.updateApplicationInfo(aInfo, oldPaths);
                             } catch (RemoteException e) {
                             }
@@ -5512,6 +5517,7 @@
         Process.setArgV0(data.processName);
         android.ddm.DdmHandleAppName.setAppName(data.processName,
                                                 UserHandle.myUserId());
+        VMRuntime.setProcessPackageName(data.appInfo.packageName);
 
         if (mProfiler.profileFd != null) {
             mProfiler.startProfiling();
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index 7257044..0ed50f2 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -25,6 +25,8 @@
 
 import dalvik.system.PathClassLoader;
 
+import java.util.Collection;
+
 /** @hide */
 public class ApplicationLoaders {
     public static ApplicationLoaders getDefault() {
@@ -121,6 +123,17 @@
         baseDexClassLoader.addDexPath(dexPath);
     }
 
+    /**
+     * @hide
+     */
+    void addNative(ClassLoader classLoader, Collection<String> libPaths) {
+        if (!(classLoader instanceof PathClassLoader)) {
+            throw new IllegalStateException("class loader is not a PathClassLoader");
+        }
+        final PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader;
+        baseDexClassLoader.addNativePath(libPaths);
+    }
+
     private final ArrayMap<String, ClassLoader> mLoaders = new ArrayMap<>();
 
     private static final ApplicationLoaders gApplicationLoaders = new ApplicationLoaders();
diff --git a/core/java/android/app/ClientTransactionHandler.java b/core/java/android/app/ClientTransactionHandler.java
index ea0d703..d9c7cf3 100644
--- a/core/java/android/app/ClientTransactionHandler.java
+++ b/core/java/android/app/ClientTransactionHandler.java
@@ -18,6 +18,7 @@
 import android.app.servertransaction.ClientTransaction;
 import android.app.servertransaction.PendingTransactionActions;
 import android.app.servertransaction.TransactionExecutor;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
@@ -140,7 +141,7 @@
 
     /** Perform activity launch. */
     public abstract Activity handleLaunchActivity(ActivityThread.ActivityClientRecord r,
-            PendingTransactionActions pendingActions);
+            PendingTransactionActions pendingActions, Intent customIntent);
 
     /** Perform activity start. */
     public abstract void handleStartActivity(ActivityThread.ActivityClientRecord r,
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index fc7d9a5..8c0cd23 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -90,6 +90,7 @@
 public final class LoadedApk {
     static final String TAG = "LoadedApk";
     static final boolean DEBUG = false;
+    private static final String PROPERTY_NAME_APPEND_NATIVE = "pi.append_native_lib_paths";
 
     private final ActivityThread mActivityThread;
     final String mPackageName;
@@ -723,6 +724,10 @@
             needToSetupJitProfiles = true;
         }
 
+        if (!libPaths.isEmpty() && SystemProperties.getBoolean(PROPERTY_NAME_APPEND_NATIVE, true)) {
+            ApplicationLoaders.getDefault().addNative(mClassLoader, libPaths);
+        }
+
         if (addedPaths != null && addedPaths.size() > 0) {
             final String add = TextUtils.join(File.pathSeparator, addedPaths);
             ApplicationLoaders.getDefault().addPath(mClassLoader, add);
diff --git a/core/java/android/app/servertransaction/LaunchActivityItem.java b/core/java/android/app/servertransaction/LaunchActivityItem.java
index 7be82bf..6bae359 100644
--- a/core/java/android/app/servertransaction/LaunchActivityItem.java
+++ b/core/java/android/app/servertransaction/LaunchActivityItem.java
@@ -75,7 +75,7 @@
                 mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                 mPendingResults, mPendingNewIntents, mIsForward,
                 mProfilerInfo, client);
-        client.handleLaunchActivity(r, pendingActions);
+        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
         Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
     }
 
diff --git a/core/java/android/app/servertransaction/TransactionExecutor.java b/core/java/android/app/servertransaction/TransactionExecutor.java
index 5c803a5..43a2b4c 100644
--- a/core/java/android/app/servertransaction/TransactionExecutor.java
+++ b/core/java/android/app/servertransaction/TransactionExecutor.java
@@ -173,7 +173,8 @@
             log("Transitioning to state: " + state);
             switch (state) {
                 case ON_CREATE:
-                    mTransactionHandler.handleLaunchActivity(r, mPendingActions);
+                    mTransactionHandler.handleLaunchActivity(r, mPendingActions,
+                            null /* customIntent */);
                     break;
                 case ON_START:
                     mTransactionHandler.handleStartActivity(r, mPendingActions);
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
index 6b1222f..0269b6c 100644
--- a/core/java/android/content/pm/ComponentInfo.java
+++ b/core/java/android/content/pm/ComponentInfo.java
@@ -96,7 +96,8 @@
         encryptionAware = directBootAware = orig.directBootAware;
     }
 
-    @Override public CharSequence loadLabel(PackageManager pm) {
+    /** @hide */
+    @Override public CharSequence loadUnsafeLabel(PackageManager pm) {
         if (nonLocalizedLabel != null) {
             return nonLocalizedLabel;
         }
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2be33e9..c988fa9 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -644,8 +644,6 @@
 
     boolean isPackageDeviceAdminOnAnyUser(String packageName);
 
-    List<String> getPreviousCodePaths(in String packageName);
-
     int getInstallReason(String packageName, int userId);
 
     ParceledListSlice getSharedLibraries(in String packageName, int flags, int userId);
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 53ffd55..07fbfb5 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -43,6 +43,8 @@
  */
 public class PackageItemInfo {
     private static final float MAX_LABEL_SIZE_PX = 500f;
+    /** The maximum length of a safe label, in characters */
+    private static final int MAX_SAFE_LABEL_LENGTH = 50000;
 
     private static volatile boolean sForceSafeLabels = false;
 
@@ -187,7 +189,8 @@
         // If the label contains new line characters it may push the UI
         // down to hide a part of it. Labels shouldn't have new line
         // characters, so just truncate at the first time one is seen.
-        final int labelLength = labelStr.length();
+        final int labelLength = Math.min(labelStr.length(), MAX_SAFE_LABEL_LENGTH);
+        final StringBuffer sb = new StringBuffer(labelLength);
         int offset = 0;
         while (offset < labelLength) {
             final int codePoint = labelStr.codePointAt(offset);
@@ -199,14 +202,19 @@
                 break;
             }
             // replace all non-break space to " " in order to be trimmed
+            final int charCount = Character.charCount(codePoint);
             if (type == Character.SPACE_SEPARATOR) {
-                labelStr = labelStr.substring(0, offset) + " " + labelStr.substring(offset +
-                        Character.charCount(codePoint));
+                sb.append(' ');
+            } else {
+                sb.append(labelStr.charAt(offset));
+                if (charCount == 2) {
+                    sb.append(labelStr.charAt(offset + 1));
+                }
             }
-            offset += Character.charCount(codePoint);
+            offset += charCount;
         }
 
-        labelStr = labelStr.trim();
+        labelStr = sb.toString().trim();
         if (labelStr.isEmpty()) {
             return packageName;
         }
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index c58cde0..7adea6a8 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -128,6 +128,14 @@
     private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>();
 
     /**
+     * To avoid leaking WeakReferences to garbage collected Themes on the
+     * mThemeRefs list, we flush the list of stale references any time the
+     * mThemeRefNextFlushSize is reached.
+     */
+    private static final int MIN_THEME_REFS_FLUSH_SIZE = 32;
+    private int mThemeRefsNextFlushSize = MIN_THEME_REFS_FLUSH_SIZE;
+
+    /**
      * Returns the most appropriate default theme for the specified target SDK version.
      * <ul>
      * <li>Below API 11: Gingerbread
@@ -1770,6 +1778,13 @@
         theme.setImpl(mResourcesImpl.newThemeImpl());
         synchronized (mThemeRefs) {
             mThemeRefs.add(new WeakReference<>(theme));
+
+            // Clean up references to garbage collected themes
+            if (mThemeRefs.size() > mThemeRefsNextFlushSize) {
+                mThemeRefs.removeIf(ref -> ref.get() == null);
+                mThemeRefsNextFlushSize = Math.max(MIN_THEME_REFS_FLUSH_SIZE,
+                        2 * mThemeRefs.size());
+            }
         }
         return theme;
     }
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 9b20ed2..11afd21 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -157,8 +157,9 @@
     public static final String DISALLOW_CONFIG_LOCALE = "no_config_locale";
 
     /**
-     * Specifies if a user is disallowed from installing applications.
-     * The default value is <code>false</code>.
+     * Specifies if a user is disallowed from installing applications. This user restriction also
+     * prevents device owners and profile owners installing apps. The default value is
+     * {@code false}.
      *
      * <p>Key for user restrictions.
      * <p>Type: Boolean
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index da47bcb..24f531d 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -114,9 +114,10 @@
 
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
-    @StringDef({WIDGET_TYPE_TEXTVIEW, WIDGET_TYPE_WEBVIEW, WIDGET_TYPE_EDITTEXT,
-            WIDGET_TYPE_EDIT_WEBVIEW, WIDGET_TYPE_CUSTOM_TEXTVIEW, WIDGET_TYPE_CUSTOM_EDITTEXT,
-            WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW, WIDGET_TYPE_UNKNOWN})
+    @StringDef({WIDGET_TYPE_TEXTVIEW, WIDGET_TYPE_EDITTEXT, WIDGET_TYPE_UNSELECTABLE_TEXTVIEW,
+            WIDGET_TYPE_WEBVIEW, WIDGET_TYPE_EDIT_WEBVIEW, WIDGET_TYPE_CUSTOM_TEXTVIEW,
+            WIDGET_TYPE_CUSTOM_EDITTEXT, WIDGET_TYPE_CUSTOM_UNSELECTABLE_TEXTVIEW,
+            WIDGET_TYPE_UNKNOWN})
     @interface WidgetType {}
 
     /** The widget involved in the text classification session is a standard
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 4db3607..a22f345 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -104,8 +104,16 @@
             sReceiverInfo.set(ri);
         }
         ri.addView(this);
+        // The view may not be added to the view hierarchy immediately right after setTime()
+        // is called which means it won't get any update from intents before being added.
+        // In such case, the view might show the incorrect relative time after being added to the
+        // view hierarchy until the next update intent comes.
+        // So we update the time here if mShowRelativeTime is enabled to prevent this case.
+        if (mShowRelativeTime) {
+            update();
+        }
     }
-        
+
     @Override
     protected void onDetachedFromWindow() {
         super.onDetachedFromWindow();
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index a1e6fd8..c388148 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -282,7 +282,10 @@
         }
     }
 
-    private static void createNativeLibrarySubdir(File path) throws IOException {
+    /**
+     * @hide
+     */
+    public static void createNativeLibrarySubdir(File path) throws IOException {
         if (!path.isDirectory()) {
             path.delete();
 
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index cc95df7..2db5739 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -308,10 +308,8 @@
     public void onDraw(Canvas c) {
         super.onDraw(c);
 
-        // When we are resizing, we need the fallback background to cover the area where we have our
-        // system bar background views as the navigation bar will be hidden during resizing.
-        mBackgroundFallback.draw(isResizing() ? this : mContentRoot, mContentRoot, c,
-                mWindow.mContentParent);
+        mBackgroundFallback.draw(this, mContentRoot, c, mWindow.mContentParent,
+                mStatusColorViewState.view, mNavigationColorViewState.view);
     }
 
     @Override
diff --git a/core/java/com/android/internal/widget/BackgroundFallback.java b/core/java/com/android/internal/widget/BackgroundFallback.java
index 309f80c..2b05f1e 100644
--- a/core/java/com/android/internal/widget/BackgroundFallback.java
+++ b/core/java/com/android/internal/widget/BackgroundFallback.java
@@ -46,8 +46,11 @@
      * @param root The view group containing the content.
      * @param c The canvas to draw the background onto.
      * @param content The view where the actual app content is contained in.
+     * @param coveringView1 A potentially opaque view drawn atop the content
+     * @param coveringView2 A potentially opaque view drawn atop the content
      */
-    public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content) {
+    public void draw(ViewGroup boundsView, ViewGroup root, Canvas c, View content,
+            View coveringView1, View coveringView2) {
         if (!hasFallback()) {
             return;
         }
@@ -55,6 +58,10 @@
         // Draw the fallback in the padding.
         final int width = boundsView.getWidth();
         final int height = boundsView.getHeight();
+
+        final int rootOffsetX = root.getLeft();
+        final int rootOffsetY = root.getTop();
+
         int left = width;
         int top = height;
         int right = 0;
@@ -71,17 +78,58 @@
                         ((ViewGroup) child).getChildCount() == 0) {
                     continue;
                 }
-            } else if (child.getVisibility() != View.VISIBLE || childBg == null ||
-                    childBg.getOpacity() != PixelFormat.OPAQUE) {
+            } else if (child.getVisibility() != View.VISIBLE || !isOpaque(childBg)) {
                 // Potentially translucent or invisible children don't count, and we assume
                 // the content view will cover the whole area if we're in a background
                 // fallback situation.
                 continue;
             }
-            left = Math.min(left, child.getLeft());
-            top = Math.min(top, child.getTop());
-            right = Math.max(right, child.getRight());
-            bottom = Math.max(bottom, child.getBottom());
+            left = Math.min(left, rootOffsetX + child.getLeft());
+            top = Math.min(top, rootOffsetY + child.getTop());
+            right = Math.max(right, rootOffsetX + child.getRight());
+            bottom = Math.max(bottom, rootOffsetY + child.getBottom());
+        }
+
+        // If one of the bar backgrounds is a solid color and covers the entire padding on a side
+        // we can drop that padding.
+        boolean eachBarCoversTopInY = true;
+        for (int i = 0; i < 2; i++) {
+            View v = (i == 0) ? coveringView1 : coveringView2;
+            if (v == null || v.getVisibility() != View.VISIBLE
+                    || v.getAlpha() != 1f || !isOpaque(v.getBackground())) {
+                eachBarCoversTopInY = false;
+                continue;
+            }
+
+            // Bar covers entire left padding
+            if (v.getTop() <= 0 && v.getBottom() >= height
+                    && v.getLeft() <= 0 && v.getRight() >= left) {
+                left = 0;
+            }
+            // Bar covers entire right padding
+            if (v.getTop() <= 0 && v.getBottom() >= height
+                    && v.getLeft() <= right && v.getRight() >= width) {
+                right = width;
+            }
+            // Bar covers entire top padding
+            if (v.getTop() <= 0 && v.getBottom() >= top
+                    && v.getLeft() <= 0 && v.getRight() >= width) {
+                top = 0;
+            }
+            // Bar covers entire bottom padding
+            if (v.getTop() <= bottom && v.getBottom() >= height
+                    && v.getLeft() <= 0 && v.getRight() >= width) {
+                bottom = height;
+            }
+
+            eachBarCoversTopInY &= v.getTop() <= 0 && v.getBottom() >= top;
+        }
+
+        // Special case: Sometimes, both covering views together may cover the top inset, but
+        // neither does on its own.
+        if (eachBarCoversTopInY && (viewsCoverEntireWidth(coveringView1, coveringView2, width)
+                || viewsCoverEntireWidth(coveringView2, coveringView1, width))) {
+            top = 0;
         }
 
         if (left >= right || top >= bottom) {
@@ -106,4 +154,24 @@
             mBackgroundFallback.draw(c);
         }
     }
+
+    private boolean isOpaque(Drawable childBg) {
+        return childBg != null && childBg.getOpacity() == PixelFormat.OPAQUE;
+    }
+
+    /**
+     * Returns true if {@code view1} starts before or on {@code 0} and extends at least
+     * up to {@code view2}, and that view extends at least to {@code width}.
+     *
+     * @param view1 the first view to check if it covers the width
+     * @param view2 the second view to check if it covers the width
+     * @param width the width to check for
+     * @return returns true if both views together cover the entire width (and view1 is to the left
+     *         of view2)
+     */
+    private boolean viewsCoverEntireWidth(View view1, View view2, int width) {
+        return view1.getLeft() <= 0
+                && view1.getRight() >= view2.getLeft()
+                && view2.getRight() >= width;
+    }
 }
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 9ef58ab..1750dac 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -16,7 +16,11 @@
 
 package android.app.activity;
 
+import static android.content.Intent.ACTION_EDIT;
+import static android.content.Intent.ACTION_VIEW;
+
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import android.app.Activity;
 import android.app.ActivityThread;
@@ -27,6 +31,7 @@
 import android.app.servertransaction.ResumeActivityItem;
 import android.app.servertransaction.StopActivityItem;
 import android.content.Intent;
+import android.os.IBinder;
 import android.support.test.InstrumentationRegistry;
 import android.support.test.filters.MediumTest;
 import android.support.test.rule.ActivityTestRule;
@@ -94,6 +99,36 @@
         });
     }
 
+    /** Verify that custom intent set via Activity#setIntent() is preserved on relaunch. */
+    @Test
+    public void testCustomIntentPreservedOnRelaunch() throws Exception {
+        final Intent initIntent = new Intent();
+        initIntent.setAction(ACTION_VIEW);
+        final Activity activity = mActivityTestRule.launchActivity(initIntent);
+        IBinder token = activity.getActivityToken();
+
+        final ActivityThread activityThread = activity.getActivityThread();
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            // Recreate and check that intent is still the same.
+            activity.recreate();
+
+            final Activity newActivity = activityThread.getActivity(token);
+            assertTrue("Original intent must be preserved after recreate",
+                    initIntent.filterEquals(newActivity.getIntent()));
+
+            // Set custom intent, recreate and check if it is preserved.
+            final Intent customIntent = new Intent();
+            customIntent.setAction(ACTION_EDIT);
+            newActivity.setIntent(customIntent);
+
+            activity.recreate();
+
+            final Activity lastActivity = activityThread.getActivity(token);
+            assertTrue("Custom intent must be preserved after recreate",
+                    customIntent.filterEquals(lastActivity.getIntent()));
+        });
+    }
+
     private static ClientTransaction newRelaunchResumeTransaction(Activity activity) {
         final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(null,
                 null, 0, new MergedConfiguration(), false /* preserveWindow */);
diff --git a/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java b/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java
new file mode 100644
index 0000000..e21143d
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/widget/BackgroundFallbackTest.java
@@ -0,0 +1,262 @@
+/*
+ * 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.internal.widget;
+
+import static android.view.View.VISIBLE;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.test.InstrumentationRegistry;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+public class BackgroundFallbackTest {
+
+    private static final int NAVBAR_BOTTOM = 0;
+    private static final int NAVBAR_LEFT = 1;
+    private static final int NAVBAR_RIGHT = 2;
+
+    private static final int SCREEN_HEIGHT = 2000;
+    private static final int SCREEN_WIDTH = 1000;
+    private static final int STATUS_HEIGHT = 100;
+    private static final int NAV_SIZE = 200;
+
+    private static final boolean INSET_CONTENT_VIEWS = true;
+    private static final boolean DONT_INSET_CONTENT_VIEWS = false;
+
+    BackgroundFallback mFallback;
+    Drawable mDrawableMock;
+
+    ViewGroup mStatusBarView;
+    ViewGroup mNavigationBarView;
+
+    ViewGroup mDecorViewMock;
+    ViewGroup mContentRootMock;
+    ViewGroup mContentContainerMock;
+    ViewGroup mContentMock;
+
+    int mLastTop = 0;
+
+    @Before
+    public void setUp() throws Exception {
+        mFallback = new BackgroundFallback();
+        mDrawableMock = mock(Drawable.class);
+
+        mFallback.setDrawable(mDrawableMock);
+
+    }
+
+    @Test
+    public void hasFallback_withDrawable_true() {
+        mFallback.setDrawable(mDrawableMock);
+        assertThat(mFallback.hasFallback(), is(true));
+    }
+
+    @Test
+    public void hasFallback_withoutDrawable_false() {
+        mFallback.setDrawable(null);
+        assertThat(mFallback.hasFallback(), is(false));
+    }
+
+    @Test
+    public void draw_portrait_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_BOTTOM);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_portrait_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_BOTTOM);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackBottom(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_landscape_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_RIGHT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackRight(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_translucentBars_fallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyFallbackTop(STATUS_HEIGHT);
+        verifyFallbackLeft(NAV_SIZE);
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_landscape_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_RIGHT);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_noFallback() {
+        setUpViewHierarchy(INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    @Test
+    public void draw_seascape_translucentBars_noInsets_noFallback() {
+        setUpViewHierarchy(DONT_INSET_CONTENT_VIEWS, NAVBAR_LEFT);
+        setTranslucent(mStatusBarView);
+        setTranslucent(mNavigationBarView);
+
+        mFallback.draw(mDecorViewMock, mContentRootMock, null /* canvas */, mContentContainerMock,
+                mStatusBarView, mNavigationBarView);
+
+        verifyNoMoreInteractions(mDrawableMock);
+    }
+
+    private void verifyFallbackTop(int size) {
+        verify(mDrawableMock).setBounds(0, 0, SCREEN_WIDTH, size);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+        mLastTop = size;
+    }
+
+    private void verifyFallbackLeft(int size) {
+        verify(mDrawableMock).setBounds(0, mLastTop, size, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void verifyFallbackRight(int size) {
+        verify(mDrawableMock).setBounds(SCREEN_WIDTH - size, mLastTop, SCREEN_WIDTH, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void verifyFallbackBottom(int size) {
+        verify(mDrawableMock).setBounds(0, SCREEN_HEIGHT - size, SCREEN_WIDTH, SCREEN_HEIGHT);
+        verify(mDrawableMock, atLeastOnce()).draw(any());
+    }
+
+    private void setUpViewHierarchy(boolean insetContentViews, int navBarPosition) {
+        int insetLeft = 0;
+        int insetTop = 0;
+        int insetRight = 0;
+        int insetBottom = 0;
+
+        mStatusBarView = mockView(0, 0, SCREEN_WIDTH, STATUS_HEIGHT,
+                new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+        if (insetContentViews) {
+            insetTop = STATUS_HEIGHT;
+        }
+
+        switch (navBarPosition) {
+            case NAVBAR_BOTTOM:
+                mNavigationBarView = mockView(0, SCREEN_HEIGHT - NAV_SIZE, SCREEN_WIDTH,
+                        SCREEN_HEIGHT, new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetBottom = NAV_SIZE;
+                }
+                break;
+            case NAVBAR_LEFT:
+                mNavigationBarView = mockView(0, 0, NAV_SIZE, SCREEN_HEIGHT,
+                        new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetLeft = NAV_SIZE;
+                }
+                break;
+            case NAVBAR_RIGHT:
+                mNavigationBarView = mockView(SCREEN_WIDTH - NAV_SIZE, 0, SCREEN_WIDTH,
+                        SCREEN_HEIGHT, new ColorDrawable(Color.BLACK), VISIBLE, emptyList());
+                if (insetContentViews) {
+                    insetRight = NAV_SIZE;
+                }
+                break;
+        }
+
+        mContentMock = mockView(0, 0, SCREEN_WIDTH - insetLeft - insetRight,
+                SCREEN_HEIGHT - insetTop - insetBottom, null, VISIBLE, emptyList());
+        mContentContainerMock = mockView(0, 0, SCREEN_WIDTH - insetLeft - insetRight,
+                SCREEN_HEIGHT - insetTop - insetBottom, null, VISIBLE, asList(mContentMock));
+        mContentRootMock = mockView(insetLeft, insetTop, SCREEN_WIDTH - insetRight,
+                SCREEN_HEIGHT - insetBottom, null, VISIBLE, asList(mContentContainerMock));
+
+        mDecorViewMock = mockView(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, null, VISIBLE,
+                asList(mContentRootMock, mStatusBarView, mNavigationBarView));
+    }
+
+    private void setTranslucent(ViewGroup bar) {
+        bar.setBackground(new ColorDrawable(Color.TRANSPARENT));
+    }
+
+    private ViewGroup mockView(int left, int top, int right, int bottom, Drawable background,
+            int visibility, List<ViewGroup> children) {
+        final ViewGroup v = new FrameLayout(InstrumentationRegistry.getTargetContext());
+
+        v.layout(left, top, right, bottom);
+        v.setBackground(background);
+        v.setVisibility(visibility);
+
+        for (ViewGroup c : children) {
+            v.addView(c);
+        }
+
+        return v;
+    }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml b/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
deleted file mode 100644
index eff9b36..0000000
--- a/packages/SystemUI/res/layout/status_bar_dnd_suppressing_notifications.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-    Copyright 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.
--->
-
-<!-- Extends Framelayout -->
-<com.android.systemui.statusbar.DndSuppressingNotificationsView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/hidden_container"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:visibility="gone">
-    <TextView
-        android:id="@+id/hidden_notifications"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="64dp"
-        android:paddingTop="28dp"
-        android:gravity="top|center_horizontal"
-        android:textColor="?attr/wallpaperTextColor"
-        android:textSize="16sp"
-        android:text="@string/dnd_suppressing_shade_text"/>
-</com.android.systemui.statusbar.DndSuppressingNotificationsView>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 1b4b15e..f1f80c7 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1064,7 +1064,7 @@
     <string name="manage_notifications_text">Manage notifications</string>
 
     <!-- The text to show in the notifications shade when dnd is suppressing notifications. [CHAR LIMIT=100] -->
-    <string name="dnd_suppressing_shade_text">Notifications hidden by Do Not Disturb</string>
+    <string name="dnd_suppressing_shade_text">Do Not Disturb is hiding notifications</string>
 
     <!-- Media projection permission dialog action text. [CHAR LIMIT=60] -->
     <string name="media_projection_action_text">Start now</string>
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index f595d77..a7163bb 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -94,6 +94,8 @@
         String OVERVIEW_OPENED_FROM_HOME_COUNT = "OverviewOpenedFromHomeCount";
         String HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING = "HasSeenRecentsSwipeUpOnboarding";
         String HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING = "HasSeenRecentsQuickScrubOnboarding";
+        String HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE =
+                "HasDismissedRecentsQuickScrubOnboardingOnce";
         String SEEN_RINGER_GUIDANCE_COUNT = "RingerGuidanceCount";
         String QS_TILE_SPECS_REVEALED = "QsTileSpecsRevealed";
         String QS_HAS_TURNED_OFF_MOBILE_DATA = "QsHasTurnedOffMobileData";
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 087d481..ea3f95e 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -344,8 +344,8 @@
             } else if (GLOBAL_ACTION_KEY_SETTINGS.equals(actionKey)) {
                 mItems.add(getSettingsAction());
             } else if (GLOBAL_ACTION_KEY_LOCKDOWN.equals(actionKey)) {
-                if (Settings.Secure.getInt(mContext.getContentResolver(),
-                            Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0) != 0
+                if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
+                            Settings.Secure.LOCKDOWN_IN_POWER_MENU, 0, getCurrentUser().id) != 0
                         && shouldDisplayLockdown()) {
                     mItems.add(getLockdownAction());
                     mHasLockdownButton = true;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 441d29b..5adeec3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -67,6 +67,10 @@
     private static final long EDIT_ID = 10000;
     private static final long DIVIDER_ID = 20000;
 
+    private static final int ACTION_NONE = 0;
+    private static final int ACTION_ADD = 1;
+    private static final int ACTION_MOVE = 2;
+
     private final Context mContext;
 
     private final Handler mHandler = new Handler();
@@ -82,7 +86,7 @@
     private List<TileInfo> mAllTiles;
 
     private Holder mCurrentDrag;
-    private boolean mAccessibilityMoving;
+    private int mAccessibilityAction = ACTION_NONE;
     private int mAccessibilityFromIndex;
     private QSTileHost mHost;
 
@@ -172,7 +176,7 @@
 
     @Override
     public int getItemViewType(int position) {
-        if (mAccessibilityMoving && position == mEditIndex - 1) {
+        if (mAccessibilityAction == ACTION_ADD && position == mEditIndex - 1) {
             return TYPE_ACCESSIBLE_DROP;
         }
         if (position == mTileDividerIndex) {
@@ -266,18 +270,18 @@
         if (position > mEditIndex) {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_add_tile_label, info.state.label);
-        } else if (mAccessibilityMoving) {
+        } else if (mAccessibilityAction != ACTION_NONE) {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_position_label, position + 1);
         } else {
             info.state.contentDescription = mContext.getString(
                     R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label);
         }
-        holder.mTileView.onStateChanged(info.state);
+        holder.mTileView.handleStateChanged(info.state);
         holder.mTileView.setShowAppLabel(position > mEditIndex && !info.isSystem);
 
         if (mAccessibilityManager.isTouchExplorationEnabled()) {
-            final boolean selectable = !mAccessibilityMoving || position < mEditIndex;
+            final boolean selectable = mAccessibilityAction == ACTION_NONE || position < mEditIndex;
             holder.mTileView.setClickable(selectable);
             holder.mTileView.setFocusable(selectable);
             holder.mTileView.setImportantForAccessibility(selectable
@@ -288,13 +292,13 @@
                     @Override
                     public void onClick(View v) {
                         int position = holder.getAdapterPosition();
-                        if (mAccessibilityMoving) {
+                        if (mAccessibilityAction != ACTION_NONE) {
                             selectPosition(position, v);
                         } else {
                             if (position < mEditIndex && canRemoveTiles()) {
                                 showAccessibilityDialog(position, v);
                             } else {
-                                startAccessibleDrag(position);
+                                startAccessibleAdd(position);
                             }
                         }
                     }
@@ -302,21 +306,21 @@
             }
         }
     }
-    
+
     private boolean canRemoveTiles() {
         return mCurrentSpecs.size() > MIN_NUM_TILES;
     }
 
     private void selectPosition(int position, View v) {
-        // Remove the placeholder.
-        mAccessibilityMoving = false;
-        mTiles.remove(mEditIndex--);
-        notifyItemRemoved(mEditIndex - 1);
-        // Don't remove items when the last position is selected.
-        if (position == mEditIndex) position--;
-
+        if (mAccessibilityAction == ACTION_ADD) {
+            // Remove the placeholder.
+            mTiles.remove(mEditIndex--);
+            notifyItemRemoved(mEditIndex);
+            // Don't remove items when the last position is selected.
+            if (position == mEditIndex - 1) position--;
+        }
+        mAccessibilityAction = ACTION_NONE;
         move(mAccessibilityFromIndex, position, v);
-
         notifyDataSetChanged();
     }
 
@@ -331,7 +335,7 @@
                     @Override
                     public void onClick(DialogInterface dialog, int which) {
                         if (which == 0) {
-                            startAccessibleDrag(position);
+                            startAccessibleMove(position);
                         } else {
                             move(position, info.isSystem ? mEditIndex : mTileDividerIndex, v);
                             notifyItemChanged(mTileDividerIndex);
@@ -345,12 +349,18 @@
         dialog.show();
     }
 
-    private void startAccessibleDrag(int position) {
-        mAccessibilityMoving = true;
-        mNeedsFocus = true;
+    private void startAccessibleAdd(int position) {
         mAccessibilityFromIndex = position;
+        mAccessibilityAction = ACTION_ADD;
         // Add placeholder for last slot.
         mTiles.add(mEditIndex++, null);
+        mNeedsFocus = true;
+        notifyDataSetChanged();
+    }
+
+    private void startAccessibleMove(int position) {
+        mAccessibilityFromIndex = position;
+        mAccessibilityAction = ACTION_MOVE;
         notifyDataSetChanged();
     }
 
@@ -365,30 +375,26 @@
         CharSequence fromLabel = mTiles.get(from).state.label;
         move(from, to, mTiles);
         updateDividerLocations();
-        CharSequence announcement;
         if (to >= mEditIndex) {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE,
                     from);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed,
-                    fromLabel);
         } else if (from >= mEditIndex) {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD,
                     to);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_added,
-                    fromLabel, (to + 1));
+            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_added,
+                    fromLabel, (to + 1)));
         } else {
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE_SPEC,
                     strip(mTiles.get(to)));
             MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_MOVE,
                     to);
-            announcement = mContext.getString(R.string.accessibility_qs_edit_tile_moved,
-                    fromLabel, (to + 1));
+            v.announceForAccessibility(mContext.getString(R.string.accessibility_qs_edit_tile_moved,
+                    fromLabel, (to + 1)));
         }
-        v.announceForAccessibility(announcement);
         saveSpecs(mHost);
         return true;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
index 63be4b7..c7191f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -45,8 +45,8 @@
      * Pattern for {@link java.time.format.DateTimeFormatter} used to approximate the time to the
      * nearest hour and add on the AM/PM indicator.
      */
-    private static final String HOUR_MINUTE_DATE_TIME_PATTERN = "h a";
-    private static final String APPROXIMATE_HOUR_DATE_TIME_PATTERN = "h:m a";
+    private static final String PATTERN_HOUR = "h a";
+    private static final String PATTERN_HOUR_MINUTE = "h:mm a";
 
 
     private ColorDisplayController mController;
@@ -142,9 +142,7 @@
                 // Choose between just showing the hour or also showing the minutes (based on the
                 // user-selected toggle time). This helps reduce how much space the label takes.
                 toggleTimeFormat = DateTimeFormatter.ofPattern(
-                        toggleTime.getMinute() == 0
-                                ? HOUR_MINUTE_DATE_TIME_PATTERN
-                                : APPROXIMATE_HOUR_DATE_TIME_PATTERN);
+                        toggleTime.getMinute() == 0 ? PATTERN_HOUR : PATTERN_HOUR_MINUTE);
 
                 return mContext.getString(toggleTimeStringRes, toggleTime.format(toggleTimeFormat));
 
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
index ffa1444..31933d0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsOnboarding.java
@@ -19,6 +19,7 @@
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
 
+import static com.android.systemui.Prefs.Key.HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE;
 import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_QUICK_SCRUB_ONBOARDING;
 import static com.android.systemui.Prefs.Key.HAS_SEEN_RECENTS_SWIPE_UP_ONBOARDING;
 import static com.android.systemui.Prefs.Key.OVERVIEW_OPENED_COUNT;
@@ -66,7 +67,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 boolean ONBOARDING_ENABLED = true;
     private static final long SHOW_DELAY_MS = 500;
     private static final long SHOW_HIDE_DURATION_MS = 300;
     // Show swipe-up tips after opening overview from home this number of times.
@@ -76,9 +77,6 @@
     // After explicitly dismissing, show again after launching this number of apps for swipe-up
     // tips.
     private static final int SWIPE_UP_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 5;
-    // After explicitly dismissing, show again after launching this number of apps for QuickScrub
-    // tips.
-    private static final int QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS = 10;
 
     private final Context mContext;
     private final WindowManager mWindowManager;
@@ -99,7 +97,7 @@
     private boolean mHasDismissedSwipeUpTip;
     private boolean mHasDismissedQuickScrubTip;
     private int mNumAppsLaunchedSinceSwipeUpTipDismiss;
-    private int mNumAppsLaunchedSinceQuickScrubTipDismiss;
+    private int mOverviewOpenedCountSinceQuickScrubTipDismiss;
 
     private final SysUiTaskStackChangeListener mTaskListener = new SysUiTaskStackChangeListener() {
         @Override
@@ -145,10 +143,9 @@
                 } else {
                     if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
                         if (mHasDismissedQuickScrubTip) {
-                            mNumAppsLaunchedSinceQuickScrubTipDismiss++;
-                            if (mNumAppsLaunchedSinceQuickScrubTipDismiss
-                                    == QUICK_SCRUB_SHOW_ON_APP_LAUNCH_AFTER_DISMISS) {
-                                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
+                            if (mOverviewOpenedCountSinceQuickScrubTipDismiss
+                                    == QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+                                mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
                                 show(R.string.recents_quick_scrub_onboarding);
                             }
                         } else {
@@ -166,14 +163,19 @@
             new OverviewProxyService.OverviewProxyListener() {
                 @Override
                 public void onOverviewShown(boolean fromHome) {
-                    boolean alreadySeenRecentsOnboarding = hasSeenSwipeUpOnboarding();
-                    if (!alreadySeenRecentsOnboarding && !fromHome) {
+                    if (!hasSeenSwipeUpOnboarding() && !fromHome) {
                         setHasSeenSwipeUpOnboarding(true);
                     }
                     if (fromHome) {
                         setOpenedOverviewFromHomeCount(getOpenedOverviewFromHomeCount() + 1);
                     }
                     setOpenedOverviewCount(getOpenedOverviewCount() + 1);
+
+                    if (getOpenedOverviewCount() >= QUICK_SCRUB_SHOW_ON_OVERVIEW_OPENED_COUNT) {
+                        if (mHasDismissedQuickScrubTip) {
+                            mOverviewOpenedCountSinceQuickScrubTipDismiss++;
+                        }
+                    }
                 }
 
                 @Override
@@ -191,7 +193,11 @@
         public void onViewAttachedToWindow(View view) {
             if (view == mLayout) {
                 mLayoutAttachedToWindow = true;
-                mHasDismissedSwipeUpTip = false;
+                if (view.getTag().equals(R.string.recents_swipe_up_onboarding)) {
+                    mHasDismissedSwipeUpTip = false;
+                } else {
+                    mHasDismissedQuickScrubTip = false;
+                }
             }
         }
 
@@ -199,6 +205,17 @@
         public void onViewDetachedFromWindow(View view) {
             if (view == mLayout) {
                 mLayoutAttachedToWindow = false;
+                if (view.getTag().equals(R.string.recents_quick_scrub_onboarding)) {
+                    mHasDismissedQuickScrubTip = true;
+                    if (hasDismissedQuickScrubOnboardingOnce()) {
+                        // If user dismisses the quick scrub tip twice, we consider user has seen it
+                        // and do not show it again.
+                        setHasSeenQuickScrubOnboarding(true);
+                    } else {
+                        setHasDismissedQuickScrubOnboardingOnce(true);
+                    }
+                    mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
+                }
             }
         }
     };
@@ -228,15 +245,6 @@
             if (v.getTag().equals(R.string.recents_swipe_up_onboarding)) {
                 mHasDismissedSwipeUpTip = true;
                 mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
-            } else {
-                if (mHasDismissedQuickScrubTip) {
-                    // If user dismisses the quick scrub tip twice, we consider user has seen it
-                    // and do not show it again.
-                    setHasSeenQuickScrubOnboarding(true);
-                } else {
-                    mHasDismissedQuickScrubTip = true;
-                }
-                mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
             }
         });
 
@@ -252,6 +260,7 @@
         if (RESET_PREFS_FOR_DEBUG) {
             setHasSeenSwipeUpOnboarding(false);
             setHasSeenQuickScrubOnboarding(false);
+            setHasDismissedQuickScrubOnboardingOnce(false);
             setOpenedOverviewCount(0);
             setOpenedOverviewFromHomeCount(0);
         }
@@ -289,7 +298,7 @@
         mHasDismissedSwipeUpTip = false;
         mHasDismissedQuickScrubTip = false;
         mNumAppsLaunchedSinceSwipeUpTipDismiss = 0;
-        mNumAppsLaunchedSinceQuickScrubTipDismiss = 0;
+        mOverviewOpenedCountSinceQuickScrubTipDismiss = 0;
         hide(false);
     }
 
@@ -303,11 +312,15 @@
         if (!shouldShow()) {
             return;
         }
+        if (mLayoutAttachedToWindow) {
+            hide(false);
+        }
         mDismissView.setTag(stringRes);
+        mLayout.setTag(stringRes);
         mTextView.setText(stringRes);
         // Only show in portrait.
         int orientation = mContext.getResources().getConfiguration().orientation;
-        if (!mLayoutAttachedToWindow && orientation == Configuration.ORIENTATION_PORTRAIT) {
+        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
             mLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
 
             mWindowManager.addView(mLayout, getWindowLayoutParams());
@@ -348,11 +361,11 @@
                         .withLayer()
                         .setDuration(SHOW_HIDE_DURATION_MS)
                         .setInterpolator(new AccelerateInterpolator())
-                        .withEndAction(() -> mWindowManager.removeView(mLayout))
+                        .withEndAction(() -> mWindowManager.removeViewImmediate(mLayout))
                         .start();
             } else {
                 mLayout.animate().cancel();
-                mWindowManager.removeView(mLayout);
+                mWindowManager.removeViewImmediate(mLayout);
             }
         }
     }
@@ -400,6 +413,16 @@
         }
     }
 
+    private boolean hasDismissedQuickScrubOnboardingOnce() {
+        return Prefs.getBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE, false);
+    }
+
+    private void setHasDismissedQuickScrubOnboardingOnce(
+            boolean hasDismissedQuickScrubOnboardingOnce) {
+        Prefs.putBoolean(mContext, HAS_DISMISSED_RECENTS_QUICK_SCRUB_ONBOARDING_ONCE,
+                hasDismissedQuickScrubOnboardingOnce);
+    }
+
     private int getOpenedOverviewFromHomeCount() {
         return Prefs.getInt(mContext, OVERVIEW_OPENED_FROM_HOME_COUNT, 0);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java b/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
deleted file mode 100644
index db3a02d..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DndSuppressingNotificationsView.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * 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.systemui.statusbar;
-
-import android.annotation.ColorInt;
-import android.annotation.DrawableRes;
-import android.annotation.IntegerRes;
-import android.annotation.StringRes;
-import android.content.Context;
-import android.content.res.ColorStateList;
-import android.content.res.Configuration;
-import android.graphics.drawable.Icon;
-import android.util.AttributeSet;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.stack.ExpandableViewState;
-import com.android.systemui.statusbar.stack.StackScrollState;
-
-public class DndSuppressingNotificationsView extends StackScrollerDecorView {
-
-    private TextView mText;
-    private @StringRes int mTextId = R.string.dnd_suppressing_shade_text;
-
-    public DndSuppressingNotificationsView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    @Override
-    protected void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        mText.setText(mTextId);
-    }
-
-    @Override
-    protected View findContentView() {
-        return findViewById(R.id.hidden_container);
-    }
-
-    @Override
-    protected View findSecondaryView() {
-        return null;
-    }
-
-    public void setColor(@ColorInt int color) {
-        mText.setTextColor(color);
-    }
-
-    public void setOnContentClickListener(OnClickListener listener) {
-        mText.setOnClickListener(listener);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mText = findViewById(R.id.hidden_notifications);
-    }
-
-    @Override
-    public ExpandableViewState createNewViewState(StackScrollState stackScrollState) {
-        return new DndSuppressingViewState();
-    }
-
-    public class DndSuppressingViewState extends ExpandableViewState {
-        @Override
-        public void applyToView(View view) {
-            super.applyToView(view);
-            if (view instanceof DndSuppressingNotificationsView) {
-                DndSuppressingNotificationsView dndView = (DndSuppressingNotificationsView) view;
-                boolean visible = this.clipTopAmount <= mText.getPaddingTop() * 0.6f;
-                dndView.performVisibilityAnimation(visible && !dndView.willBeGone());
-            }
-        }
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 8bb73da..b650944 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -199,7 +199,6 @@
     private ValueAnimator mQsSizeChangeAnimator;
 
     private boolean mShowEmptyShadeView;
-    private boolean mShowDndView;
 
     private boolean mQsScrimEnabled = true;
     private boolean mLastAnnouncementWasQuickSettings;
@@ -1600,8 +1599,8 @@
         // When only empty shade view is visible in QS collapsed state, simulate that we would have
         // it in expanded QS state as well so we don't run into troubles when fading the view in/out
         // and expanding/collapsing the whole panel from/to quick settings.
-        if ((mNotificationStackScroller.getNotGoneChildCount() == 0
-                && mShowEmptyShadeView) || mShowDndView) {
+        if (mNotificationStackScroller.getNotGoneChildCount() == 0
+                && mShowEmptyShadeView) {
             notificationHeight = mNotificationStackScroller.getEmptyShadeViewHeight();
         }
         int maxQsHeight = mQsMaxExpansionHeight;
@@ -2244,17 +2243,13 @@
         return mDozing;
     }
 
-    public void showDndView(boolean dndViewVisible) {
-        mShowDndView = dndViewVisible;
-        mNotificationStackScroller.updateDndView(mShowDndView && !mQsExpanded);
-    }
-
     public void showEmptyShadeView(boolean emptyShadeViewVisible) {
         mShowEmptyShadeView = emptyShadeViewVisible;
         updateEmptyShadeView();
     }
 
     private void updateEmptyShadeView() {
+
         // Hide "No notifications" in QS.
         mNotificationStackScroller.updateEmptyShadeView(mShowEmptyShadeView && !mQsExpanded);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
index 1a1839d..d9ba313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -327,7 +327,7 @@
                 - mNavigationBarView.getPaddingTop();
         final int x1, x2, y1, y2;
         if (mIsVertical) {
-            x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingStart();
+            x1 = (width - mTrackThickness) / 2 + mNavigationBarView.getPaddingLeft();
             x2 = x1 + mTrackThickness;
             y1 = mDragPositive ? height / 2 : mTrackPadding;
             y2 = y1 + height / 2 - mTrackPadding;
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 5f07599..061677c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -20,7 +20,6 @@
 import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
 import static android.app.StatusBarManager.windowStateToString;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static android.provider.Settings.Global.ZEN_MODE_OFF;
 
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
 import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
@@ -169,7 +168,6 @@
 import com.android.systemui.keyguard.ScreenLifecycle;
 import com.android.systemui.keyguard.WakefulnessLifecycle;
 import com.android.systemui.plugins.ActivityStarter;
-import com.android.systemui.plugins.VolumeDialogController;
 import com.android.systemui.plugins.qs.QS;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.qs.QSFragment;
@@ -190,7 +188,6 @@
 import com.android.systemui.statusbar.BackDropView;
 import com.android.systemui.statusbar.CommandQueue;
 import com.android.systemui.statusbar.CrossFadeHelper;
-import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.DragDownHelper;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
@@ -416,7 +413,7 @@
     protected NotificationViewHierarchyManager mViewHierarchyManager;
     protected AppOpsListener mAppOpsListener;
     protected KeyguardViewMediator mKeyguardViewMediator;
-    protected ZenModeController mZenController;
+    private ZenModeController mZenController;
 
     /**
      * Helper that is responsible for showing the right toast when a disallowed activity operation
@@ -881,7 +878,6 @@
         mVisualStabilityManager.setVisibilityLocationProvider(mStackScroller);
 
         inflateEmptyShadeView();
-        inflateDndView();
         inflateFooterView();
 
         mBackdrop = mStatusBarWindow.findViewById(R.id.backdrop);
@@ -1149,7 +1145,6 @@
     protected void reevaluateStyles() {
         inflateFooterView();
         updateFooter();
-        inflateDndView();
         inflateEmptyShadeView();
         updateEmptyShadeView();
     }
@@ -1171,19 +1166,6 @@
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
     }
 
-    private void inflateDndView() {
-        if (mStackScroller == null) {
-            return;
-        }
-        mDndView = (DndSuppressingNotificationsView) LayoutInflater.from(mContext).inflate(
-                R.layout.status_bar_dnd_suppressing_notifications, mStackScroller, false);
-        mDndView.setOnContentClickListener(v -> {
-            Intent intent = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
-            startActivity(intent, true, true, Intent.FLAG_ACTIVITY_SINGLE_TOP);
-        });
-        mStackScroller.setDndView(mDndView);
-    }
-
     private void inflateFooterView() {
         if (mStackScroller == null) {
             return;
@@ -1477,11 +1459,9 @@
     @VisibleForTesting
     protected void updateFooter() {
         boolean showFooterView = mState != StatusBarState.KEYGUARD
-                && !areNotificationsHidden()
                 && mEntryManager.getNotificationData().getActiveNotifications().size() != 0
                 && !mRemoteInputManager.getController().isRemoteInputActive();
         boolean showDismissView = mClearAllEnabled && mState != StatusBarState.KEYGUARD
-                && !areNotificationsHidden()
                 && hasActiveClearableNotifications();
 
         mStackScroller.updateFooterView(showFooterView, showDismissView);
@@ -1504,13 +1484,10 @@
         return false;
     }
 
-    @VisibleForTesting
-    protected void updateEmptyShadeView() {
-        boolean showDndView = mState != StatusBarState.KEYGUARD && areNotificationsHidden();
-        boolean showEmptyShadeView = !showDndView
-                && mState != StatusBarState.KEYGUARD
-                && mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
-        mNotificationPanel.showDndView(showDndView);
+    private void updateEmptyShadeView() {
+        boolean showEmptyShadeView =
+                mState != StatusBarState.KEYGUARD &&
+                        mEntryManager.getNotificationData().getActiveNotifications().size() == 0;
         mNotificationPanel.showEmptyShadeView(showEmptyShadeView);
     }
 
@@ -5017,7 +4994,6 @@
     protected NotificationShelf mNotificationShelf;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
-    protected DndSuppressingNotificationsView mDndView;
 
     protected AssistManager mAssistManager;
 
@@ -5502,11 +5478,6 @@
                     mStackScroller.getChildCount() - offsetFromEnd++);
         }
 
-        if (mDndView != null) {
-            mStackScroller.changeViewPosition(mDndView,
-                    mStackScroller.getChildCount() - offsetFromEnd++);
-        }
-
         mStackScroller.changeViewPosition(mEmptyShadeView,
                 mStackScroller.getChildCount() - offsetFromEnd++);
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
index 6a8d3a5..48a9fb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemUIDialog.java
@@ -20,6 +20,7 @@
 import android.app.Dialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.UserHandle;
@@ -30,6 +31,7 @@
 import com.android.systemui.R;
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 
+
 /**
  * Base class for dialogs that should appear over panels and keyguard.
  */
@@ -99,24 +101,40 @@
     }
 
     public static void registerDismissListener(Dialog dialog) {
-        boolean[] registered = new boolean[1];
-        Context context = dialog.getContext();
-        final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (dialog != null) {
-                    dialog.dismiss();
-                }
-            }
-        };
-        context.registerReceiverAsUser(mReceiver, UserHandle.CURRENT,
-                new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), null, null);
-        registered[0] = true;
-        dialog.setOnDismissListener(d -> {
-            if (registered[0]) {
-                context.unregisterReceiver(mReceiver);
-                registered[0] = false;
-            }
-        });
+        DismissReceiver dismissReceiver = new DismissReceiver(dialog);
+        dismissReceiver.register();
     }
-}
+
+    private static class DismissReceiver extends BroadcastReceiver implements OnDismissListener {
+        private static final IntentFilter INTENT_FILTER = new IntentFilter();
+        static {
+            INTENT_FILTER.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+            INTENT_FILTER.addAction(Intent.ACTION_SCREEN_OFF);
+        }
+
+        private final Dialog mDialog;
+        private boolean mRegistered;
+
+        DismissReceiver(Dialog dialog) {
+            mDialog = dialog;
+        }
+
+        void register() {
+            mDialog.getContext()
+                    .registerReceiverAsUser(this, UserHandle.CURRENT, INTENT_FILTER, null, null);
+            mRegistered = true;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mDialog.dismiss();
+        }
+
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+            if (mRegistered) {
+                mDialog.getContext().unregisterReceiver(this);
+                mRegistered = false;
+            }
+        }
+    }}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index eeaa6cb..5275e27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -81,7 +81,6 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.statusbar.ActivatableNotificationView;
-import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.ExpandableView;
@@ -237,7 +236,6 @@
     protected boolean mScrollingEnabled;
     protected FooterView mFooterView;
     protected EmptyShadeView mEmptyShadeView;
-    protected DndSuppressingNotificationsView mDndView;
     private boolean mDismissAllInProgress;
     private boolean mFadeNotificationsOnDismiss;
 
@@ -1008,8 +1006,7 @@
     private float getAppearEndPosition() {
         int appearPosition;
         int notGoneChildCount = getNotGoneChildCount();
-        if ((mEmptyShadeView.getVisibility() == GONE && mDndView.getVisibility() == GONE)
-                && notGoneChildCount != 0) {
+        if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
             if (isHeadsUpTransition()
                     || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
                 appearPosition = getTopHeadsUpPinnedHeight();
@@ -1019,8 +1016,6 @@
                     appearPosition += mShelf.getIntrinsicHeight();
                 }
             }
-        } else if (mEmptyShadeView.getVisibility() == GONE) {
-            appearPosition = mDndView.getHeight();
         } else {
             appearPosition = mEmptyShadeView.getHeight();
         }
@@ -2613,6 +2608,19 @@
         return mShelf.getVisibility() == GONE ? 0 : mShelf.getIntrinsicHeight();
     }
 
+    public int getFirstChildIntrinsicHeight() {
+        final ExpandableView firstChild = getFirstChildNotGone();
+        int firstChildMinHeight = firstChild != null
+                ? firstChild.getIntrinsicHeight()
+                : mEmptyShadeView != null
+                        ? mEmptyShadeView.getIntrinsicHeight()
+                        : mCollapsedSize;
+        if (mOwnScrollY > 0) {
+            firstChildMinHeight = Math.max(firstChildMinHeight - mOwnScrollY, mCollapsedSize);
+        }
+        return firstChildMinHeight;
+    }
+
     public float getTopPaddingOverflow() {
         return mTopPaddingOverflow;
     }
@@ -3910,7 +3918,6 @@
         final int textColor = Utils.getColorAttr(context, R.attr.wallpaperTextColor);
         mFooterView.setTextColor(textColor);
         mEmptyShadeView.setTextColor(textColor);
-        mDndView.setColor(textColor);
     }
 
     public void goToFullShade(long delay) {
@@ -3918,7 +3925,6 @@
             mFooterView.setInvisible();
         }
         mEmptyShadeView.setInvisible();
-        mDndView.setInvisible();
         mGoToFullShadeNeedsAnimation = true;
         mGoToFullShadeDelay = delay;
         mNeedsAnimation = true;
@@ -4070,39 +4076,25 @@
         int newVisibility = visible ? VISIBLE : GONE;
 
         boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility) {
+        if (changedVisibility || newVisibility != GONE) {
             if (newVisibility != GONE) {
-                showFooterView(mEmptyShadeView);
+                int oldText = mEmptyShadeView.getTextResource();
+                int newText;
+                if (mStatusBar.areNotificationsHidden()) {
+                    newText = R.string.dnd_suppressing_shade_text;
+                } else {
+                    newText = R.string.empty_shade_text;
+                }
+                if (changedVisibility || !Objects.equals(oldText, newText)) {
+                    mEmptyShadeView.setText(newText);
+                    showFooterView(mEmptyShadeView);
+                }
             } else {
                 hideFooterView(mEmptyShadeView, true);
             }
         }
     }
 
-    public void setDndView(DndSuppressingNotificationsView dndView) {
-        int index = -1;
-        if (mDndView != null) {
-            index = indexOfChild(mDndView);
-            removeView(mDndView);
-        }
-        mDndView = dndView;
-        addView(mDndView, index);
-    }
-
-    public void updateDndView(boolean visible) {
-        int oldVisibility = mDndView.willBeGone() ? GONE : mDndView.getVisibility();
-        int newVisibility = visible ? VISIBLE : GONE;
-
-        boolean changedVisibility = oldVisibility != newVisibility;
-        if (changedVisibility) {
-            if (newVisibility != GONE) {
-                showFooterView(mDndView);
-            } else {
-                hideFooterView(mDndView, true);
-            }
-        }
-    }
-
     public void updateFooterView(boolean visible, boolean showDismissView) {
         if (mFooterView == null) {
             return;
@@ -4127,16 +4119,10 @@
         } else {
             footerView.setInvisible();
         }
-        Runnable onShowFinishRunnable = new Runnable() {
-            @Override
-            public void run() {
-                footerView.setVisibility(VISIBLE);
-                footerView.setWillBeGone(false);
-                updateContentHeight();
-                notifyHeightChangeListener(footerView);
-            }
-        };
-        footerView.performVisibilityAnimation(true, onShowFinishRunnable);
+        footerView.setVisibility(VISIBLE);
+        footerView.setWillBeGone(false);
+        updateContentHeight();
+        notifyHeightChangeListener(footerView);
     }
 
     private void hideFooterView(StackScrollerDecorView footerView, boolean isButtonVisible) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 41cf869..37e0005 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -78,7 +78,6 @@
 import com.android.systemui.statusbar.ActivatableNotificationView;
 import com.android.systemui.statusbar.AppOpsListener;
 import com.android.systemui.statusbar.CommandQueue;
-import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.ExpandableNotificationRow;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.FooterViewButton;
@@ -104,7 +103,6 @@
 import com.android.systemui.statusbar.policy.KeyguardMonitor;
 import com.android.systemui.statusbar.policy.KeyguardMonitorImpl;
 import com.android.systemui.statusbar.policy.UserSwitcherController;
-import com.android.systemui.statusbar.policy.ZenModeController;
 import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
 
 import org.junit.Before;
@@ -134,7 +132,6 @@
     @Mock private ScrimController mScrimController;
     @Mock private ArrayList<Entry> mNotificationList;
     @Mock private FingerprintUnlockController mFingerprintUnlockController;
-    @Mock private ZenModeController mZenController;
     @Mock private NotificationData mNotificationData;
 
     // Mock dependencies:
@@ -166,7 +163,6 @@
         mDependency.injectTestDependency(NotificationListener.class, mNotificationListener);
         mDependency.injectTestDependency(KeyguardMonitor.class, mock(KeyguardMonitorImpl.class));
         mDependency.injectTestDependency(AppOpsListener.class, mock(AppOpsListener.class));
-        mDependency.injectTestDependency(ZenModeController.class, mZenController);
 
         mContext.addMockSystemService(TrustManager.class, mock(TrustManager.class));
         mContext.addMockSystemService(FingerprintManager.class, mock(FingerprintManager.class));
@@ -217,7 +213,7 @@
                 mRemoteInputManager, mock(NotificationGroupManager.class),
                 mock(FalsingManager.class), mock(StatusBarWindowManager.class),
                 mock(NotificationIconAreaController.class), mock(DozeScrimController.class),
-                mock(NotificationShelf.class), mLockscreenUserManager, mZenController,
+                mock(NotificationShelf.class), mLockscreenUserManager,
                 mock(CommandQueue.class));
         mStatusBar.mContext = mContext;
         mStatusBar.mComponents = mContext.getComponents();
@@ -680,60 +676,6 @@
     }
 
     @Test
-    public void testDNDView_atEnd() {
-        // add footer
-        mStatusBar.reevaluateStyles();
-
-        // add notification
-        ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
-        mStackScroller.addContainerView(row);
-
-        mStatusBar.onUpdateRowStates();
-
-        // move dnd view to end
-        verify(mStackScroller).changeViewPosition(any(FooterView.class), eq(-1 /* end */));
-        verify(mStackScroller).changeViewPosition(any(DndSuppressingNotificationsView.class),
-                eq(-2 /* end */));
-    }
-
-    @Test
-    public void updateEmptyShade_nonNotificationsDndOff() {
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
-        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
-        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
-
-        mStatusBar.updateEmptyShadeView();
-        verify(mNotificationPanelView).showDndView(false);
-        verify(mNotificationPanelView).showEmptyShadeView(true);
-    }
-
-    @Test
-    public void updateEmptyShade_noNotificationsDndOn() {
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
-        when(mNotificationData.getActiveNotifications()).thenReturn(new ArrayList<>());
-        assertEquals(0, mEntryManager.getNotificationData().getActiveNotifications().size());
-        when(mZenController.areNotificationsHiddenInShade()).thenReturn(true);
-
-        mStatusBar.updateEmptyShadeView();
-        verify(mNotificationPanelView).showDndView(true);
-        verify(mNotificationPanelView).showEmptyShadeView(false);
-    }
-
-    @Test
-    public void updateEmptyShade_yesNotificationsDndOff() {
-        mStatusBar.setBarStateForTest(StatusBarState.SHADE);
-        ArrayList<Entry> entries = new ArrayList<>();
-        entries.add(mock(Entry.class));
-        when(mNotificationData.getActiveNotifications()).thenReturn(entries);
-        assertEquals(1, mEntryManager.getNotificationData().getActiveNotifications().size());
-        when(mZenController.areNotificationsHiddenInShade()).thenReturn(false);
-
-        mStatusBar.updateEmptyShadeView();
-        verify(mNotificationPanelView).showDndView(false);
-        verify(mNotificationPanelView).showEmptyShadeView(false);
-    }
-
-    @Test
     public void testSetState_changesIsFullScreenUserSwitcherState() {
         mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
         assertFalse(mStatusBar.isFullScreenUserSwitcherState());
@@ -779,7 +721,6 @@
                 DozeScrimController dozeScrimController,
                 NotificationShelf notificationShelf,
                 NotificationLockscreenUserManager notificationLockscreenUserManager,
-                ZenModeController zenController,
                 CommandQueue commandQueue) {
             mStatusBarKeyguardViewManager = man;
             mUnlockMethodCache = unlock;
@@ -808,7 +749,6 @@
             mDozeScrimController = dozeScrimController;
             mNotificationShelf = notificationShelf;
             mLockscreenUserManager = notificationLockscreenUserManager;
-            mZenController = zenController;
             mCommandQueue = commandQueue;
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
index 3d17ec4..eeb4209 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayoutTest.java
@@ -18,7 +18,6 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.reset;
@@ -35,7 +34,6 @@
 import com.android.systemui.R;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.TestableDependency;
-import com.android.systemui.statusbar.DndSuppressingNotificationsView;
 import com.android.systemui.statusbar.EmptyShadeView;
 import com.android.systemui.statusbar.FooterView;
 import com.android.systemui.statusbar.NotificationBlockingHelperManager;
@@ -71,7 +69,6 @@
     @Mock private NotificationGroupManager mGroupManager;
     @Mock private ExpandHelper mExpandHelper;
     @Mock private EmptyShadeView mEmptyShadeView;
-    @Mock private DndSuppressingNotificationsView mDndView;
 
     @Before
     @UiThreadTest
@@ -89,7 +86,6 @@
         mStackScroller.setHeadsUpManager(mHeadsUpManager);
         mStackScroller.setGroupManager(mGroupManager);
         mStackScroller.setEmptyShadeView(mEmptyShadeView);
-        mStackScroller.setDndView(mDndView);
 
         // Stub out functionality that isn't necessary to test.
         doNothing().when(mBar)
@@ -124,6 +120,40 @@
     }
 
     @Test
+    public void updateEmptyView_dndSuppressing() {
+        when(mEmptyShadeView.willBeGone()).thenReturn(true);
+        when(mBar.areNotificationsHidden()).thenReturn(true);
+
+        mStackScroller.updateEmptyShadeView(true);
+
+        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
+    }
+
+    @Test
+    public void updateEmptyView_dndNotSuppressing() {
+        mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        when(mEmptyShadeView.willBeGone()).thenReturn(true);
+        when(mBar.areNotificationsHidden()).thenReturn(false);
+
+        mStackScroller.updateEmptyShadeView(true);
+
+        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
+    }
+
+    @Test
+    public void updateEmptyView_noNotificationsToDndSuppressing() {
+        mStackScroller.setEmptyShadeView(mEmptyShadeView);
+        when(mEmptyShadeView.willBeGone()).thenReturn(true);
+        when(mBar.areNotificationsHidden()).thenReturn(false);
+        mStackScroller.updateEmptyShadeView(true);
+        verify(mEmptyShadeView).setText(R.string.empty_shade_text);
+
+        when(mBar.areNotificationsHidden()).thenReturn(true);
+        mStackScroller.updateEmptyShadeView(true);
+        verify(mEmptyShadeView).setText(R.string.dnd_suppressing_shade_text);
+    }
+
+    @Test
     @UiThreadTest
     public void testSetExpandedHeight_blockingHelperManagerReceivedCallbacks() {
         mStackScroller.setExpandedHeight(0f);
@@ -143,7 +173,7 @@
 
         mStackScroller.updateFooterView(true, false);
 
-        verify(view).performVisibilityAnimation(eq(true), any());
+        verify(view).setVisibility(View.VISIBLE);
         verify(view).performSecondaryVisibilityAnimation(false);
     }
 
@@ -156,7 +186,7 @@
 
         mStackScroller.updateFooterView(true, true);
 
-        verify(view).performVisibilityAnimation(eq(true), any());
+        verify(view).setVisibility(View.VISIBLE);
         verify(view).performSecondaryVisibilityAnimation(true);
     }
 }
diff --git a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
index 90baea0..cc7304a 100644
--- a/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
+++ b/services/backup/java/com/android/server/backup/internal/PerformBackupTask.java
@@ -629,6 +629,8 @@
             mFullBackupTask.unregisterTask();
             switch (mStatus) {
                 case BackupTransport.TRANSPORT_OK:
+                case BackupTransport.TRANSPORT_QUOTA_EXCEEDED:
+                case BackupTransport.TRANSPORT_PACKAGE_REJECTED:
                     BackupObserverUtils.sendBackupFinished(mObserver,
                             BackupManager.SUCCESS);
                     break;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 99944625..72f9d74 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -132,6 +132,7 @@
 import com.android.internal.net.VpnConfig;
 import com.android.internal.net.VpnInfo;
 import com.android.internal.net.VpnProfile;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.DumpUtils;
 import com.android.internal.util.IndentingPrintWriter;
@@ -1992,13 +1993,6 @@
         return ret;
     }
 
-    private boolean argsContain(String[] args, String target) {
-        for (String arg : args) {
-            if (target.equals(arg)) return true;
-        }
-        return false;
-    }
-
     private void dumpNetworkDiagnostics(IndentingPrintWriter pw) {
         final List<NetworkDiagnostics> netDiags = new ArrayList<NetworkDiagnostics>();
         final long DIAG_TIME_MS = 5000;
@@ -2027,10 +2021,10 @@
         if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
         if (asProto) return;
 
-        if (argsContain(args, DIAG_ARG)) {
+        if (ArrayUtils.contains(args, DIAG_ARG)) {
             dumpNetworkDiagnostics(pw);
             return;
-        } else if (argsContain(args, TETHERING_ARG)) {
+        } else if (ArrayUtils.contains(args, TETHERING_ARG)) {
             mTethering.dump(fd, pw, args);
             return;
         }
@@ -2098,7 +2092,7 @@
         pw.println();
         mMultipathPolicyTracker.dump(pw);
 
-        if (argsContain(args, SHORT_ARG) == false) {
+        if (ArrayUtils.contains(args, SHORT_ARG) == false) {
             pw.println();
             synchronized (mValidationLogs) {
                 pw.println("mValidationLogs (most recent first):");
diff --git a/services/core/java/com/android/server/TextServicesManagerService.java b/services/core/java/com/android/server/TextServicesManagerService.java
index 58d5340..f24d8cd 100644
--- a/services/core/java/com/android/server/TextServicesManagerService.java
+++ b/services/core/java/com/android/server/TextServicesManagerService.java
@@ -397,10 +397,7 @@
                     final String packageName = sci.getPackageName();
                     final int change = isPackageDisappearing(packageName);
                     if (DBG) Slog.d(TAG, "Changing package name: " + packageName);
-                    if (// Package disappearing
-                            change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE
-                                    // Package modified
-                                    || isPackageModified(packageName)) {
+                    if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
                         SpellCheckerInfo availSci =
                                 findAvailSystemSpellCheckerLocked(packageName, tsd);
                         // Set the spell checker settings if different than before
diff --git a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
index f427819..ac74598 100644
--- a/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
+++ b/services/core/java/com/android/server/connectivity/IpConnectivityMetrics.java
@@ -20,6 +20,7 @@
 import android.net.ConnectivityMetricsEvent;
 import android.net.IIpConnectivityMetrics;
 import android.net.INetdEventCallback;
+import android.net.ip.IpClient;
 import android.net.metrics.ApfProgramEvent;
 import android.net.metrics.IpConnectivityLog;
 import android.os.Binder;
@@ -269,10 +270,12 @@
         // Dump the rolling buffer of metrics event and pretty print events using a human readable
         // format. Also print network dns/connect statistics and default network event time series.
         static final String CMD_LIST = "list";
-        // By default any other argument will fall into the default case which is remapped to the
-        // "list" command. This includes most notably bug reports collected by dumpsys.cpp with
-        // the "-a" argument.
-        static final String CMD_DEFAULT = CMD_LIST;
+        // Dump all IpClient logs ("ipclient").
+        static final String CMD_IPCLIENT = IpClient.DUMP_ARG;
+        // By default any other argument will fall into the default case which is the equivalent
+        // of calling both the "list" and "ipclient" commands. This includes most notably bug
+        // reports collected by dumpsys.cpp with the "-a" argument.
+        static final String CMD_DEFAULT = "";
 
         @Override
         public int logEvent(ConnectivityMetricsEvent event) {
@@ -292,9 +295,20 @@
                 case CMD_PROTO:
                     cmdListAsProto(pw);
                     return;
-                case CMD_LIST: // fallthrough
+                case CMD_IPCLIENT: {
+                    final String[] ipclientArgs = ((args != null) && (args.length > 1))
+                            ? Arrays.copyOfRange(args, 1, args.length)
+                            : null;
+                    IpClient.dumpAllLogs(pw, ipclientArgs);
+                    return;
+                }
+                case CMD_LIST:
+                    cmdList(pw);
+                    return;
                 default:
                     cmdList(pw);
+                    pw.println("");
+                    IpClient.dumpAllLogs(pw, null);
                     return;
             }
         }
diff --git a/services/core/java/com/android/server/pm/InstantAppResolver.java b/services/core/java/com/android/server/pm/InstantAppResolver.java
index dbf0940..d0a3757 100644
--- a/services/core/java/com/android/server/pm/InstantAppResolver.java
+++ b/services/core/java/com/android/server/pm/InstantAppResolver.java
@@ -16,6 +16,8 @@
 
 package com.android.server.pm;
 
+import static android.content.Intent.FLAG_ACTIVITY_MATCH_EXTERNAL;
+
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_ONE;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_INSTANT_APP_RESOLUTION_PHASE_TWO;
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN;
@@ -366,6 +368,7 @@
         final Intent failureIntent = new Intent(origIntent);
         boolean requiresSecondPhase = false;
         failureIntent.setFlags(failureIntent.getFlags() | Intent.FLAG_IGNORE_EPHEMERAL);
+        failureIntent.setFlags(failureIntent.getFlags() & ~Intent.FLAG_ACTIVITY_MATCH_EXTERNAL);
         failureIntent.setLaunchToken(token);
         ArrayList<AuxiliaryResolveInfo.AuxiliaryFilter> filters = null;
         boolean isWebIntent = origIntent.isWebIntent();
@@ -408,6 +411,10 @@
         if (filters != null && !filters.isEmpty()) {
             return new AuxiliaryResolveInfo(token, requiresSecondPhase, failureIntent, filters);
         }
+        // if the match external flag is set, return an empty resolve info
+        if ((origIntent.getFlags() & FLAG_ACTIVITY_MATCH_EXTERNAL) != 0) {
+            return new AuxiliaryResolveInfo(token, false, failureIntent, null /* filters */);
+        }
         // Hash or filter mis-match; no instant apps for this domain.
         return null;
     }
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index f7a0215..fa934fe 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -17,7 +17,6 @@
 package com.android.server.pm;
 
 import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
-import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_DEX_METADATA;
 import static android.content.pm.PackageManager.INSTALL_FAILED_CONTAINER_ERROR;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
 import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
@@ -74,6 +73,7 @@
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.RevocableFileDescriptor;
+import android.os.SystemProperties;
 import android.os.UserHandle;
 import android.os.storage.StorageManager;
 import android.system.ErrnoException;
@@ -111,9 +111,9 @@
 import java.io.FileFilter;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.security.cert.CertificateException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -154,6 +154,8 @@
     private static final String ATTR_NAME = "name";
     private static final String ATTR_INSTALL_REASON = "installRason";
 
+    private static final String PROPERTY_NAME_INHERIT_NATIVE = "pi.inherit_native_on_dont_kill";
+
     // TODO: enforce INSTALL_ALLOW_TEST
     // TODO: enforce INSTALL_ALLOW_DOWNGRADE
 
@@ -255,6 +257,8 @@
     @GuardedBy("mLock")
     private final List<String> mResolvedInstructionSets = new ArrayList<>();
     @GuardedBy("mLock")
+    private final List<String> mResolvedNativeLibPaths = new ArrayList<>();
+    @GuardedBy("mLock")
     private File mInheritedFilesBase;
 
     private static final FileFilter sAddedFilter = new FileFilter() {
@@ -971,6 +975,26 @@
                         final File oatDir = new File(toDir, "oat");
                         createOatDirs(mResolvedInstructionSets, oatDir);
                     }
+                    // pre-create lib dirs for linking if necessary
+                    if (!mResolvedNativeLibPaths.isEmpty()) {
+                        for (String libPath : mResolvedNativeLibPaths) {
+                            // "/lib/arm64" -> ["lib", "arm64"]
+                            final int splitIndex = libPath.lastIndexOf('/');
+                            if (splitIndex < 0 || splitIndex >= libPath.length() - 1) {
+                                Slog.e(TAG, "Skipping native library creation for linking due to "
+                                        + "invalid path: " + libPath);
+                                continue;
+                            }
+                            final String libDirPath = libPath.substring(1, splitIndex);
+                            final File libDir = new File(toDir, libDirPath);
+                            if (!libDir.exists()) {
+                                NativeLibraryHelper.createNativeLibrarySubdir(libDir);
+                            }
+                            final String archDirPath = libPath.substring(splitIndex + 1);
+                            NativeLibraryHelper.createNativeLibrarySubdir(
+                                    new File(libDir, archDirPath));
+                        }
+                    }
                     linkFiles(fromFiles, toDir, mInheritedFilesBase);
                 } else {
                     // TODO: this should delegate to DCS so the system process
@@ -988,7 +1012,7 @@
         computeProgressLocked(true);
 
         // Unpack native libraries
-        extractNativeLibraries(mResolvedStageDir, params.abiOverride);
+        extractNativeLibraries(mResolvedStageDir, params.abiOverride, mayInheritNativeLibs());
 
         // We've reached point of no return; call into PMS to install the stage.
         // Regardless of success or failure we always destroy session.
@@ -1028,6 +1052,17 @@
     }
 
     /**
+     * Returns true if the session should attempt to inherit any existing native libraries already
+     * extracted at the current install location. This is necessary to prevent double loading of
+     * native libraries already loaded by the running app.
+     */
+    private boolean mayInheritNativeLibs() {
+        return SystemProperties.getBoolean(PROPERTY_NAME_INHERIT_NATIVE, true) &&
+                params.mode == SessionParams.MODE_INHERIT_EXISTING &&
+                (params.installFlags & PackageManager.DONT_KILL_APP) != 0;
+    }
+
+    /**
      * Validate install by confirming that all application packages are have
      * consistent package name, version code, and signing certificates.
      * <p>
@@ -1249,6 +1284,38 @@
                     }
                 }
             }
+
+            // Inherit native libraries for DONT_KILL sessions.
+            if (mayInheritNativeLibs() && removeSplitList.isEmpty()) {
+                File[] libDirs = new File[]{
+                        new File(packageInstallDir, NativeLibraryHelper.LIB_DIR_NAME),
+                        new File(packageInstallDir, NativeLibraryHelper.LIB64_DIR_NAME)};
+                for (File libDir : libDirs) {
+                    if (!libDir.exists() || !libDir.isDirectory()) {
+                        continue;
+                    }
+                    final List<File> libDirsToInherit = new LinkedList<>();
+                    for (File archSubDir : libDir.listFiles()) {
+                        if (!archSubDir.isDirectory()) {
+                            continue;
+                        }
+                        String relLibPath;
+                        try {
+                            relLibPath = getRelativePath(archSubDir, packageInstallDir);
+                        } catch (IOException e) {
+                            Slog.e(TAG, "Skipping linking of native library directory!", e);
+                            // shouldn't be possible, but let's avoid inheriting these to be safe
+                            libDirsToInherit.clear();
+                            break;
+                        }
+                        if (!mResolvedNativeLibPaths.contains(relLibPath)) {
+                            mResolvedNativeLibPaths.add(relLibPath);
+                        }
+                        libDirsToInherit.addAll(Arrays.asList(archSubDir.listFiles()));
+                    }
+                    mResolvedInheritedFiles.addAll(libDirsToInherit);
+                }
+            }
         }
     }
 
@@ -1374,11 +1441,13 @@
         Slog.d(TAG, "Copied " + fromFiles.size() + " files into " + toDir);
     }
 
-    private static void extractNativeLibraries(File packageDir, String abiOverride)
+    private static void extractNativeLibraries(File packageDir, String abiOverride, boolean inherit)
             throws PackageManagerException {
-        // Always start from a clean slate
         final File libDir = new File(packageDir, NativeLibraryHelper.LIB_DIR_NAME);
-        NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true);
+        if (!inherit) {
+            // Start from a clean slate
+            NativeLibraryHelper.removeNativeBinariesFromDirLI(libDir, true);
+        }
 
         NativeLibraryHelper.Handle handle = null;
         try {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 681b0c9..af5521d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -16403,22 +16403,6 @@
         }
     }
 
-    @Override
-    public List<String> getPreviousCodePaths(String packageName) {
-        final int callingUid = Binder.getCallingUid();
-        final List<String> result = new ArrayList<>();
-        if (getInstantAppPackageName(callingUid) != null) {
-            return result;
-        }
-        final PackageSetting ps = mSettings.mPackages.get(packageName);
-        if (ps != null
-                && ps.oldCodePaths != null
-                && !filterAppAccessLPr(ps, callingUid, UserHandle.getUserId(callingUid))) {
-            result.addAll(ps.oldCodePaths);
-        }
-        return result;
-    }
-
     private void replaceNonSystemPackageLIF(PackageParser.Package deletedPackage,
             PackageParser.Package pkg, final @ParseFlags int parseFlags,
             final @ScanFlags int scanFlags, UserHandle user, int[] allUsers,
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 898ecf3..f8bf9c4 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -844,7 +844,12 @@
         }
         // If what we are scanning is a system (and possibly privileged) package,
         // then make it so, regardless of whether it was previously installed only
-        // in the data partition.
+        // in the data partition. Reset first.
+        pkgSetting.pkgFlags &= ~ApplicationInfo.FLAG_SYSTEM;
+        pkgSetting.pkgPrivateFlags &= ~(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
+                | ApplicationInfo.PRIVATE_FLAG_OEM
+                | ApplicationInfo.PRIVATE_FLAG_VENDOR
+                | ApplicationInfo.PRIVATE_FLAG_PRODUCT);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java
index d6999dd..63ae09a 100644
--- a/services/net/java/android/net/ip/IpClient.java
+++ b/services/net/java/android/net/ip/IpClient.java
@@ -54,6 +54,7 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.R;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.IState;
 import com.android.internal.util.Preconditions;
@@ -74,6 +75,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
@@ -100,6 +102,36 @@
     private static final Class[] sMessageClasses = { IpClient.class, DhcpClient.class };
     private static final SparseArray<String> sWhatToString =
             MessageUtils.findMessageNames(sMessageClasses);
+    // Two static concurrent hashmaps of interface name to logging classes.
+    // One holds StateMachine logs and the other connectivity packet logs.
+    private static final ConcurrentHashMap<String, SharedLog> sSmLogs = new ConcurrentHashMap<>();
+    private static final ConcurrentHashMap<String, LocalLog> sPktLogs = new ConcurrentHashMap<>();
+
+    // If |args| is non-empty, assume it's a list of interface names for which
+    // we should print IpClient logs (filter out all others).
+    public static void dumpAllLogs(PrintWriter writer, String[] args) {
+        for (String ifname : sSmLogs.keySet()) {
+            if (!ArrayUtils.isEmpty(args) && !ArrayUtils.contains(args, ifname)) continue;
+
+            writer.println(String.format("--- BEGIN %s ---", ifname));
+
+            final SharedLog smLog = sSmLogs.get(ifname);
+            if (smLog != null) {
+                writer.println("State machine log:");
+                smLog.dump(null, writer, null);
+            }
+
+            writer.println("");
+
+            final LocalLog pktLog = sPktLogs.get(ifname);
+            if (pktLog != null) {
+                writer.println("Connectivity packet log:");
+                pktLog.readOnlyLocalLog().dump(null, writer, null);
+            }
+
+            writer.println(String.format("--- END %s ---", ifname));
+        }
+    }
 
     /**
      * Callbacks for handling IpClient events.
@@ -680,8 +712,10 @@
         mShutdownLatch = new CountDownLatch(1);
         mNwService = deps.getNMS();
 
-        mLog = new SharedLog(MAX_LOG_RECORDS, mTag);
-        mConnectivityPacketLog = new LocalLog(MAX_PACKET_RECORDS);
+        sSmLogs.putIfAbsent(mInterfaceName, new SharedLog(MAX_LOG_RECORDS, mTag));
+        mLog = sSmLogs.get(mInterfaceName);
+        sPktLogs.putIfAbsent(mInterfaceName, new LocalLog(MAX_PACKET_RECORDS));
+        mConnectivityPacketLog = sPktLogs.get(mInterfaceName);
         mMsgStateLogger = new MessageHandlingLogger();
 
         // TODO: Consider creating, constructing, and passing in some kind of
diff --git a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
index 949c504..b1dad5a 100644
--- a/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
+++ b/services/robotests/src/com/android/server/backup/PerformBackupTaskTest.java
@@ -419,7 +419,7 @@
         runTask(task);
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
     }
 
     @Test
@@ -467,8 +467,7 @@
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.SUCCESS);
         verify(mObserver).onResult(PACKAGE_2, BackupManager.ERROR_TRANSPORT_PACKAGE_REJECTED);
-        // TODO: Should we return the status of the last?
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
     }
 
     @Test
@@ -488,7 +487,7 @@
         runTask(task);
 
         verify(mObserver).onResult(PACKAGE_1, BackupManager.ERROR_TRANSPORT_QUOTA_EXCEEDED);
-        verify(mObserver).backupFinished(BackupManager.ERROR_TRANSPORT_ABORTED);
+        verify(mObserver).backupFinished(BackupManager.SUCCESS);
         verify(agentMock.agent).onQuotaExceeded(anyLong(), anyLong());
     }