Merge "Can't use dagger to inject DockManager."
diff --git a/Android.bp b/Android.bp
index 4c07fcf..8a3f76c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -318,6 +318,7 @@
         "core/java/android/service/vr/IVrListener.aidl",
         "core/java/android/service/vr/IVrManager.aidl",
         "core/java/android/service/vr/IVrStateCallbacks.aidl",
+        "core/java/android/service/watchdog/IExplicitHealthCheckService.aidl",
         "core/java/android/print/ILayoutResultCallback.aidl",
         "core/java/android/print/IPrinterDiscoveryObserver.aidl",
         "core/java/android/print/IPrintDocumentAdapter.aidl",
@@ -475,7 +476,10 @@
         "media/java/android/media/IMediaHTTPConnection.aidl",
         "media/java/android/media/IMediaHTTPService.aidl",
         "media/java/android/media/IMediaResourceMonitor.aidl",
+        "media/java/android/media/IMediaRoute2Callback.aidl",
+        "media/java/android/media/IMediaRoute2Provider.aidl",
         "media/java/android/media/IMediaRouterClient.aidl",
+        "media/java/android/media/IMediaRouter2ManagerClient.aidl",
         "media/java/android/media/IMediaRouterService.aidl",
         "media/java/android/media/IMediaScannerListener.aidl",
         "media/java/android/media/IMediaScannerService.aidl",
@@ -1626,6 +1630,7 @@
         ":openjdk_java_files",
         ":non_openjdk_java_files",
         ":opt-telephony-common-srcs",
+        "core/java/**/*.java",
     ],
     arg_files: [
         "core/res/AndroidManifest.xml",
diff --git a/api/current.txt b/api/current.txt
index 8192762..5664d4f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11384,6 +11384,7 @@
   public class PackageInstaller {
     method public void abandonSession(int);
     method public int createSession(@NonNull android.content.pm.PackageInstaller.SessionParams) throws java.io.IOException;
+    method @Nullable public android.content.pm.PackageInstaller.SessionInfo getActiveStagedSession();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getAllSessions();
     method @NonNull public java.util.List<android.content.pm.PackageInstaller.SessionInfo> getMySessions();
     method @Nullable public android.content.pm.PackageInstaller.SessionInfo getSessionInfo(int);
@@ -11468,6 +11469,7 @@
     method @NonNull public String getStagedSessionErrorMessage();
     method @NonNull public android.os.UserHandle getUser();
     method public boolean isActive();
+    method public boolean isCommitted();
     method public boolean isMultiPackage();
     method public boolean isSealed();
     method public boolean isStaged();
diff --git a/api/system-current.txt b/api/system-current.txt
index 4b6c537..a4cf10d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1740,7 +1740,7 @@
   }
 
   public class ShortcutManager {
-    method @NonNull public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
+    method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_APP_PREDICTIONS) public java.util.List<android.content.pm.ShortcutManager.ShareShortcutInfo> getShareTargets(@NonNull android.content.IntentFilter);
     method public boolean hasShareTargets(@NonNull String);
   }
 
@@ -4216,7 +4216,7 @@
     method @Nullable public String getDomains();
     method @Nullable public java.net.InetAddress getGateway();
     method @Nullable public android.net.LinkAddress getIpAddress();
-    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String);
+    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
     method public void setDomains(@Nullable String);
     method public void setGateway(@Nullable java.net.InetAddress);
     method public void setIpAddress(@Nullable android.net.LinkAddress);
@@ -4436,7 +4436,7 @@
   }
 
   public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
-    method public static String getProbeName(int);
+    method @NonNull public static String getProbeName(int);
     field public static final int DNS_FAILURE = 0; // 0x0
     field public static final int DNS_SUCCESS = 1; // 0x1
     field public static final int PROBE_DNS = 0; // 0x0
@@ -6322,8 +6322,8 @@
     ctor public AttentionService();
     method public final void disableSelf();
     method @Nullable public final android.os.IBinder onBind(@NonNull android.content.Intent);
-    method public abstract void onCancelAttentionCheck(int);
-    method public abstract void onCheckAttention(int, @NonNull android.service.attention.AttentionService.AttentionCallback);
+    method public abstract void onCancelAttentionCheck(@NonNull android.service.attention.AttentionService.AttentionCallback);
+    method public abstract void onCheckAttention(@NonNull android.service.attention.AttentionService.AttentionCallback);
     field public static final int ATTENTION_FAILURE_CAMERA_PERMISSION_ABSENT = 6; // 0x6
     field public static final int ATTENTION_FAILURE_CANCELLED = 3; // 0x3
     field public static final int ATTENTION_FAILURE_PREEMPTED = 4; // 0x4
@@ -6335,8 +6335,8 @@
   }
 
   public static final class AttentionService.AttentionCallback {
-    method public void onFailure(int, int);
-    method public void onSuccess(int, int, long);
+    method public void onFailure(int);
+    method public void onSuccess(int, long);
   }
 
 }
@@ -6895,6 +6895,22 @@
 
 }
 
+package android.service.watchdog {
+
+  public abstract class ExplicitHealthCheckService extends android.app.Service {
+    ctor public ExplicitHealthCheckService();
+    method public final void notifyHealthCheckPassed(@NonNull String);
+    method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
+    method public abstract void onCancelHealthCheck(@NonNull String);
+    method @NonNull public abstract java.util.List<java.lang.String> onGetRequestedPackages();
+    method @NonNull public abstract java.util.List<java.lang.String> onGetSupportedPackages();
+    method public abstract void onRequestHealthCheck(@NonNull String);
+    field public static final String BIND_PERMISSION = "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+    field public static final String SERVICE_INTERFACE = "android.service.watchdog.ExplicitHealthCheckService";
+  }
+
+}
+
 package android.telecom {
 
   @Deprecated public class AudioState implements android.os.Parcelable {
diff --git a/api/test-current.txt b/api/test-current.txt
index 6532cf8..9817a97 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1316,7 +1316,7 @@
     method @Nullable public String getDomains();
     method @Nullable public java.net.InetAddress getGateway();
     method @Nullable public android.net.LinkAddress getIpAddress();
-    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(String);
+    method @NonNull public java.util.List<android.net.RouteInfo> getRoutes(@Nullable String);
     method public void setDomains(@Nullable String);
     method public void setGateway(@Nullable java.net.InetAddress);
     method public void setIpAddress(@Nullable android.net.LinkAddress);
@@ -1535,7 +1535,7 @@
   }
 
   public final class ValidationProbeEvent implements android.net.metrics.IpConnectivityLog.Event {
-    method public static String getProbeName(int);
+    method @NonNull public static String getProbeName(int);
     field public static final int DNS_FAILURE = 0; // 0x0
     field public static final int DNS_SUCCESS = 1; // 0x1
     field public static final int PROBE_DNS = 0; // 0x0
@@ -2150,9 +2150,9 @@
     method @RequiresPermission(android.Manifest.permission.CLEAR_APP_USER_DATA) public static long getContributedMediaSize(android.content.Context, String, android.os.UserHandle) throws java.io.IOException;
     method @NonNull public static java.io.File getVolumePath(@NonNull String) throws java.io.FileNotFoundException;
     method @NonNull public static java.util.Collection<java.io.File> getVolumeScanPaths(@NonNull String) throws java.io.FileNotFoundException;
-    field public static final String EXTRA_ORIGINATED_FROM_SHELL = "android.intent.extra.originated_from_shell";
-    field public static final String SCAN_FILE_CALL = "scan_file";
-    field public static final String SCAN_VOLUME_CALL = "scan_volume";
+    method public static android.net.Uri scanFile(android.content.Context, java.io.File);
+    method public static android.net.Uri scanFileFromShell(android.content.Context, java.io.File);
+    method public static void scanVolume(android.content.Context, java.io.File);
   }
 
   public final class Settings {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index d6ea7e6..c2b81e4 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -2433,6 +2433,8 @@
     optional float latency_mean_micros = 3;
     // Standard deviation
     optional float latency_stdev_micros = 4;
+    // Number of touch events (input_event) in this report
+    optional int32 count = 5;
 }
 
 /**
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 79cdb77..95bdc36 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -678,11 +678,6 @@
 Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
 Lcom/android/ims/internal/uce/uceservice/IUceService$Stub;-><init>()V
 Lcom/android/internal/app/AlertActivity;-><init>()V
-Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController;
-Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;
-Lcom/android/internal/app/AlertActivity;->setupAlert()V
-Lcom/android/internal/app/AssistUtils;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName;
 Lcom/android/internal/app/ChooserActivity;-><init>()V
 Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V
 Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -710,42 +705,13 @@
 Lcom/android/internal/app/IBatteryStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/app/IBatteryStats$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IBatteryStats;
 Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService;
-Lcom/android/internal/app/IntentForwarderActivity;->TAG:Ljava/lang/String;
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
 Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
-Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;-><init>(Ljava/util/Locale;Z)V
-Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->compare(Lcom/android/internal/app/LocaleStore$LocaleInfo;Lcom/android/internal/app/LocaleStore$LocaleInfo;)I
-Lcom/android/internal/app/LocaleHelper;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
-Lcom/android/internal/app/LocaleHelper;->getDisplayName(Ljava/util/Locale;Ljava/util/Locale;Z)Ljava/lang/String;
-Lcom/android/internal/app/LocaleHelper;->normalizeForSearch(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;
-Lcom/android/internal/app/LocalePicker$LocaleInfo;->getLocale()Ljava/util/Locale;
-Lcom/android/internal/app/LocalePicker;->getLocales()Landroid/os/LocaleList;
-Lcom/android/internal/app/LocalePicker;->updateLocale(Ljava/util/Locale;)V
-Lcom/android/internal/app/LocalePicker;->updateLocales(Landroid/os/LocaleList;)V
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameInUiLanguage()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameNative()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getId()Ljava/lang/String;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getLocale()Ljava/util/Locale;
-Lcom/android/internal/app/LocaleStore$LocaleInfo;->getParent()Ljava/util/Locale;
-Lcom/android/internal/app/LocaleStore;->fillCache(Landroid/content/Context;)V
-Lcom/android/internal/app/LocaleStore;->getLevelLocales(Landroid/content/Context;Ljava/util/Set;Lcom/android/internal/app/LocaleStore$LocaleInfo;Z)Ljava/util/Set;
-Lcom/android/internal/app/LocaleStore;->getLocaleInfo(Ljava/util/Locale;)Lcom/android/internal/app/LocaleStore$LocaleInfo;
-Lcom/android/internal/app/NetInitiatedActivity;->handleNIVerify(Landroid/content/Intent;)V
 Lcom/android/internal/app/ResolverActivity;-><init>()V
-Lcom/android/internal/app/ResolverActivity;->mAdapter:Lcom/android/internal/app/ResolverActivity$ResolveListAdapter;
-Lcom/android/internal/app/ResolverActivity;->mPm:Landroid/content/pm/PackageManager;
-Lcom/android/internal/app/ResolverActivity;->onCreate(Landroid/os/Bundle;Landroid/content/Intent;Ljava/lang/CharSequence;[Landroid/content/Intent;Ljava/util/List;Z)V
-Lcom/android/internal/app/WindowDecorActionBar$TabImpl;->mCallback:Landroid/app/ActionBar$TabListener;
-Lcom/android/internal/app/WindowDecorActionBar;->mTabScrollView:Lcom/android/internal/widget/ScrollingTabContainerView;
-Lcom/android/internal/app/WindowDecorActionBar;->setShowHideAnimationEnabled(Z)V
 Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
 Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
 Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
 Lcom/android/internal/content/PackageMonitor;-><init>()V
-Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V
-Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor;
-Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor;
-Lcom/android/internal/http/HttpDateTime;->parse(Ljava/lang/String;)J
 Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;-><init>()V
 Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorId:Ljava/lang/String;
 Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorIdEncoding:I
@@ -764,48 +730,11 @@
 Lcom/android/internal/logging/MetricsLogger;-><init>()V
 Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
 Lcom/android/internal/net/VpnConfig;-><init>()V
-Lcom/android/internal/os/AndroidPrintStream;-><init>(ILjava/lang/String;)V
 Lcom/android/internal/os/BaseCommand;-><init>()V
-Lcom/android/internal/os/BaseCommand;->mArgs:Landroid/os/ShellCommand;
 Lcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType;
-Lcom/android/internal/os/BinderInternal;->getContextObject()Landroid/os/IBinder;
-Lcom/android/internal/os/BinderInternal;->handleGc()V
-Lcom/android/internal/os/ClassLoaderFactory;->createClassloaderNamespace(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;)Ljava/lang/String;
 Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->name:Ljava/lang/String;
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_stime:I
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_uptime:J
-Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_utime:I
-Lcom/android/internal/os/ProcessCpuTracker;-><init>(Z)V
-Lcom/android/internal/os/ProcessCpuTracker;->countWorkingStats()I
-Lcom/android/internal/os/ProcessCpuTracker;->getWorkingStats(I)Lcom/android/internal/os/ProcessCpuTracker$Stats;
-Lcom/android/internal/os/ProcessCpuTracker;->update()V
-Lcom/android/internal/os/RuntimeInit;->commonInit()V
-Lcom/android/internal/os/RuntimeInit;->getApplicationObject()Landroid/os/IBinder;
-Lcom/android/internal/os/RuntimeInit;->initialized:Z
-Lcom/android/internal/os/RuntimeInit;->main([Ljava/lang/String;)V
-Lcom/android/internal/os/RuntimeInit;->mApplicationObject:Landroid/os/IBinder;
-Lcom/android/internal/os/ZygoteConnection;->closeSocket()V
-Lcom/android/internal/os/ZygoteConnection;->mSocket:Landroid/net/LocalSocket;
-Lcom/android/internal/os/ZygoteConnection;->mSocketOutStream:Ljava/io/DataOutputStream;
-Lcom/android/internal/os/ZygoteConnection;->peer:Landroid/net/Credentials;
-Lcom/android/internal/os/ZygoteInit;->main([Ljava/lang/String;)V
-Lcom/android/internal/os/ZygoteInit;->mResources:Landroid/content/res/Resources;
-Lcom/android/internal/os/ZygoteSecurityException;-><init>(Ljava/lang/String;)V
-Lcom/android/internal/policy/DecorView;->mLastBottomInset:I
-Lcom/android/internal/policy/DecorView;->mLastLeftInset:I
-Lcom/android/internal/policy/DecorView;->mLastRightInset:I
-Lcom/android/internal/policy/DecorView;->mWindow:Lcom/android/internal/policy/PhoneWindow;
 Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
 Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->mContext:Landroid/content/Context;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->mView:Landroid/view/View;
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyDown(ILandroid/view/KeyEvent;)Z
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyUp(ILandroid/view/KeyEvent;)Z
-Lcom/android/internal/policy/PhoneFallbackEventHandler;->startCallActivity()V
-Lcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/policy/PhoneWindow;->mTitle:Ljava/lang/CharSequence;
 Lcom/android/internal/preference/YesNoPreference;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
 Lcom/android/internal/R$anim;->fade_in:I
 Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I
@@ -1556,202 +1485,15 @@
 Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap;
 Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
 Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
-Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I
-Lcom/android/internal/util/ArrayUtils;->contains([II)Z
-Lcom/android/internal/util/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z
-Lcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I
-Lcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
-Lcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
-Lcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
-Lcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/BitwiseInputStream;-><init>([B)V
-Lcom/android/internal/util/BitwiseInputStream;->available()I
-Lcom/android/internal/util/BitwiseInputStream;->read(I)I
-Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B
-Lcom/android/internal/util/BitwiseInputStream;->skip(I)V
-Lcom/android/internal/util/BitwiseOutputStream;-><init>(I)V
-Lcom/android/internal/util/BitwiseOutputStream;->toByteArray()[B
-Lcom/android/internal/util/BitwiseOutputStream;->write(II)V
-Lcom/android/internal/util/BitwiseOutputStream;->writeByteArray(I[B)V
-Lcom/android/internal/util/CharSequences;->compareToIgnoreCase(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
-Lcom/android/internal/util/CharSequences;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
-Lcom/android/internal/util/FastMath;->round(F)I
-Lcom/android/internal/util/FastXmlSerializer;-><init>()V
-Lcom/android/internal/util/GrowingArrayUtils;->append([III)[I
-Lcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
-Lcom/android/internal/util/HexDump;->hexStringToByteArray(Ljava/lang/String;)[B
-Lcom/android/internal/util/HexDump;->toHexString(I)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([B)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([BII)Ljava/lang/String;
-Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
-Lcom/android/internal/util/IState;->getName()Ljava/lang/String;
 Lcom/android/internal/util/MemInfoReader;-><init>()V
-Lcom/android/internal/util/MemInfoReader;->getCachedSize()J
-Lcom/android/internal/util/MemInfoReader;->getFreeSize()J
-Lcom/android/internal/util/MemInfoReader;->getRawInfo()[J
-Lcom/android/internal/util/MemInfoReader;->getTotalSize()J
-Lcom/android/internal/util/MemInfoReader;->readMemInfo()V
-Lcom/android/internal/util/Preconditions;->checkArgument(Z)V
-Lcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V
-Lcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I
-Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
-Lcom/android/internal/util/Preconditions;->checkState(Z)V
-Lcom/android/internal/util/Preconditions;->checkState(ZLjava/lang/String;)V
-Lcom/android/internal/util/State;-><init>()V
-Lcom/android/internal/util/State;->enter()V
-Lcom/android/internal/util/State;->exit()V
-Lcom/android/internal/util/State;->getName()Ljava/lang/String;
-Lcom/android/internal/util/State;->processMessage(Landroid/os/Message;)Z
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;)V
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Handler;)V
-Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Looper;)V
-Lcom/android/internal/util/StateMachine;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
-Lcom/android/internal/util/StateMachine;->obtainMessage(III)Landroid/os/Message;
-Lcom/android/internal/util/StateMachine;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message;
-Lcom/android/internal/util/StateMachine;->sendMessage(I)V
-Lcom/android/internal/util/StateMachine;->sendMessage(II)V
-Lcom/android/internal/util/StateMachine;->sendMessage(IIILjava/lang/Object;)V
-Lcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V
-Lcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V
-Lcom/android/internal/view/ActionBarPolicy;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/ActionBarPolicy;->get(Landroid/content/Context;)Lcom/android/internal/view/ActionBarPolicy;
-Lcom/android/internal/view/ActionBarPolicy;->getEmbeddedMenuWidthLimit()I
-Lcom/android/internal/view/ActionBarPolicy;->getMaxActionButtons()I
-Lcom/android/internal/view/ActionBarPolicy;->getStackedTabMaxWidth()I
-Lcom/android/internal/view/ActionBarPolicy;->getTabContainerHeight()I
-Lcom/android/internal/view/ActionBarPolicy;->hasEmbeddedTabs()Z
-Lcom/android/internal/view/ActionBarPolicy;->mContext:Landroid/content/Context;
-Lcom/android/internal/view/ActionBarPolicy;->showsOverflowMenuButton()Z
 Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
 Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
-Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->dispose()V
-Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->getInstance()Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;
-Lcom/android/internal/view/menu/ActionMenu;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/menu/ActionMenuItem;-><init>(Landroid/content/Context;IIIILjava/lang/CharSequence;)V
-Lcom/android/internal/view/menu/ContextMenuBuilder;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/view/menu/IconMenuItemView;->getTextAppropriateLayoutParams()Lcom/android/internal/view/menu/IconMenuView$LayoutParams;
-Lcom/android/internal/view/menu/IconMenuItemView;->setIconMenuView(Lcom/android/internal/view/menu/IconMenuView;)V
-Lcom/android/internal/view/menu/IconMenuItemView;->setItemInvoker(Lcom/android/internal/view/menu/MenuBuilder$ItemInvoker;)V
-Lcom/android/internal/view/menu/IconMenuView$SavedState;-><init>(Landroid/os/Parcel;)V
-Lcom/android/internal/view/menu/IconMenuView;->createMoreItemView()Lcom/android/internal/view/menu/IconMenuItemView;
-Lcom/android/internal/view/menu/IconMenuView;->getNumActualItemsShown()I
-Lcom/android/internal/view/menu/IconMenuView;->mItemBackground:Landroid/graphics/drawable/Drawable;
-Lcom/android/internal/view/menu/IconMenuView;->mMaxItems:I
-Lcom/android/internal/view/menu/IconMenuView;->mMenu:Lcom/android/internal/view/menu/MenuBuilder;
-Lcom/android/internal/view/menu/MenuDialogHelper;-><init>(Lcom/android/internal/view/menu/MenuBuilder;)V
-Lcom/android/internal/view/menu/MenuDialogHelper;->dismiss()V
-Lcom/android/internal/view/menu/MenuDialogHelper;->show(Landroid/os/IBinder;)V
-Lcom/android/internal/view/WindowManagerPolicyThread;->getLooper()Landroid/os/Looper;
-Lcom/android/internal/widget/AbsActionBarView;->dismissPopupMenus()V
-Lcom/android/internal/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/ActionBarOverlayLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V
-Lcom/android/internal/widget/EditableInputConnection;-><init>(Landroid/widget/TextView;)V
 Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
 Lcom/android/internal/widget/IRemoteViewsFactory$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/IRemoteViewsFactory;
-Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->setDefaultTouchRecepient(Landroid/view/View;)V
-Lcom/android/internal/widget/LockPatternChecker;->checkPassword(Lcom/android/internal/widget/LockPatternUtils;Ljava/lang/String;ILcom/android/internal/widget/LockPatternChecker$OnCheckCallback;)Landroid/os/AsyncTask;
-Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;-><init>(I)V
-Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->getTimeoutMs()I
-Lcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
-Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;I)Z
-Lcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I
-Lcom/android/internal/widget/LockPatternUtils;->getDevicePolicyManager()Landroid/app/admin/DevicePolicyManager;
-Lcom/android/internal/widget/LockPatternUtils;->getKeyguardStoredPasswordQuality(I)I
-Lcom/android/internal/widget/LockPatternUtils;->getLockSettings()Lcom/android/internal/widget/ILockSettings;
-Lcom/android/internal/widget/LockPatternUtils;->getOwnerInfo(I)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->getPowerButtonInstantlyLocks(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->getString(Ljava/lang/String;I)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->isDeviceEncryptionEnabled()Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->isTactileFeedbackEnabled()Z
-Lcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z
-Lcom/android/internal/widget/LockPatternUtils;->mContentResolver:Landroid/content/ContentResolver;
-Lcom/android/internal/widget/LockPatternUtils;->mContext:Landroid/content/Context;
-Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[B
-Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
-Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
-Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
-Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
-Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V
-Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfoEnabled(ZI)V
-Lcom/android/internal/widget/LockPatternUtils;->setString(Ljava/lang/String;Ljava/lang/String;I)V
-Lcom/android/internal/widget/LockPatternView$Cell;->column:I
-Lcom/android/internal/widget/LockPatternView$Cell;->row:I
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Animate:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Correct:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$DisplayMode;->Wrong:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcel;)V
-Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcelable;Ljava/lang/String;IZZZ)V
-Lcom/android/internal/widget/LockPatternView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/LockPatternView;->clearPattern()V
-Lcom/android/internal/widget/LockPatternView;->disableInput()V
-Lcom/android/internal/widget/LockPatternView;->enableInput()V
-Lcom/android/internal/widget/LockPatternView;->getCellStates()[[Lcom/android/internal/widget/LockPatternView$CellState;
-Lcom/android/internal/widget/LockPatternView;->mInStealthMode:Z
-Lcom/android/internal/widget/LockPatternView;->mPaint:Landroid/graphics/Paint;
-Lcom/android/internal/widget/LockPatternView;->mPathPaint:Landroid/graphics/Paint;
-Lcom/android/internal/widget/LockPatternView;->mPattern:Ljava/util/ArrayList;
-Lcom/android/internal/widget/LockPatternView;->mPatternDisplayMode:Lcom/android/internal/widget/LockPatternView$DisplayMode;
-Lcom/android/internal/widget/LockPatternView;->mPatternInProgress:Z
-Lcom/android/internal/widget/LockPatternView;->mSquareHeight:F
-Lcom/android/internal/widget/LockPatternView;->mSquareWidth:F
-Lcom/android/internal/widget/LockPatternView;->notifyPatternDetected()V
-Lcom/android/internal/widget/LockPatternView;->setDisplayMode(Lcom/android/internal/widget/LockPatternView$DisplayMode;)V
-Lcom/android/internal/widget/LockPatternView;->setInStealthMode(Z)V
-Lcom/android/internal/widget/LockPatternView;->setOnPatternListener(Lcom/android/internal/widget/LockPatternView$OnPatternListener;)V
-Lcom/android/internal/widget/LockPatternView;->setTactileFeedbackEnabled(Z)V
 Lcom/android/internal/widget/PointerLocationView$PointerState;-><init>()V
-Lcom/android/internal/widget/PointerLocationView$PointerState;->mCurDown:Z
-Lcom/android/internal/widget/PointerLocationView;->mCurDown:Z
-Lcom/android/internal/widget/PointerLocationView;->mCurNumPointers:I
-Lcom/android/internal/widget/PointerLocationView;->mMaxNumPointers:I
-Lcom/android/internal/widget/PointerLocationView;->mPointers:Ljava/util/ArrayList;
-Lcom/android/internal/widget/PointerLocationView;->mPrintCoords:Z
-Lcom/android/internal/widget/PreferenceImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
-Lcom/android/internal/widget/RecyclerView$RecycledViewPool$ScrapData;->mScrapHeap:Ljava/util/ArrayList;
-Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I
-Lcom/android/internal/widget/SlidingTab$Slider;->tab:Landroid/widget/ImageView;
-Lcom/android/internal/widget/SlidingTab$Slider;->text:Landroid/widget/TextView;
-Lcom/android/internal/widget/SlidingTab;->mAnimationDoneListener:Landroid/view/animation/Animation$AnimationListener;
-Lcom/android/internal/widget/SlidingTab;->mLeftSlider:Lcom/android/internal/widget/SlidingTab$Slider;
-Lcom/android/internal/widget/SlidingTab;->mRightSlider:Lcom/android/internal/widget/SlidingTab$Slider;
-Lcom/android/internal/widget/SlidingTab;->onAnimationDone()V
-Lcom/android/internal/widget/SlidingTab;->resetView()V
-Lcom/android/internal/widget/SlidingTab;->setHoldAfterTrigger(ZZ)V
-Lcom/android/internal/widget/SlidingTab;->setLeftHintText(I)V
-Lcom/android/internal/widget/SlidingTab;->setLeftTabResources(IIII)V
-Lcom/android/internal/widget/SlidingTab;->setOnTriggerListener(Lcom/android/internal/widget/SlidingTab$OnTriggerListener;)V
-Lcom/android/internal/widget/SlidingTab;->setRightHintText(I)V
-Lcom/android/internal/widget/SlidingTab;->setRightTabResources(IIII)V
-Lcom/android/internal/widget/TextViewInputDisabler;-><init>(Landroid/widget/TextView;)V
-Lcom/android/internal/widget/TextViewInputDisabler;->setInputEnabled(Z)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrolled(IFI)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrollStateChanged(I)V
-Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageSelected(I)V
-Lcom/android/internal/widget/ViewPager;->getCurrentItem()I
 Lcom/android/server/net/BaseNetworkObserver;-><init>()V
-Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V
-Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V
-Lcom/android/server/net/NetlinkTracker;->getLinkProperties()Landroid/net/LinkProperties;
 Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V
-Lcom/android/server/ResettableTimeout;->mLock:Landroid/os/ConditionVariable;
-Lcom/android/server/ResettableTimeout;->mOffAt:J
-Lcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
-Lcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet;
-Lcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet;
-Lcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet;
-Lcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet;
-Lcom/google/android/collect/Sets;->newSortedSet()Ljava/util/SortedSet;
 Lcom/google/android/gles_jni/EGLImpl;-><init>()V
 Lcom/google/android/gles_jni/GLImpl;-><init>()V
 Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList;
@@ -2033,17 +1775,7 @@
 Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
 Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z
 Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->ACRONYM:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->FLICKR:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->FORMAT:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->GOOGLE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->HTML:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->LINK:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->MUSIC:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->PHOTO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->SMILEY:Lcom/google/android/util/AbstractMessageParser$Token$Type;
 Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type;
-Lcom/google/android/util/AbstractMessageParser$Token$Type;->YOUTUBE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
 Lgov/nist/core/Debug;->printStackTrace(Ljava/lang/Exception;)V
 Lgov/nist/core/GenericObject;-><init>()V
 Lgov/nist/core/GenericObject;->dbgPrint()V
diff --git a/core/java/android/attention/AttentionManagerInternal.java b/core/java/android/attention/AttentionManagerInternal.java
index ac19504..fa3d3b8 100644
--- a/core/java/android/attention/AttentionManagerInternal.java
+++ b/core/java/android/attention/AttentionManagerInternal.java
@@ -30,25 +30,21 @@
     /**
      * Checks whether user attention is at the screen and calls in the provided callback.
      *
-     * @param requestCode   a code associated with the attention check request; this code would be
-     *                      used to call back in {@link AttentionCallbackInternal#onSuccess} and
-     *                      {@link AttentionCallbackInternal#onFailure}
      * @param timeoutMillis a budget for the attention check; if it takes longer - {@link
      *                      AttentionCallbackInternal#onFailure} would be called with the {@link
      *                      android.service.attention.AttentionService#ATTENTION_FAILURE_TIMED_OUT}
      *                      code
      * @param callback      a callback for when the attention check has completed
-     * @return {@code true} if the attention check should succeed; {@false} otherwise.
+     * @return {@code true} if the attention check should succeed.
      */
-    public abstract boolean checkAttention(int requestCode,
-            long timeoutMillis, AttentionCallbackInternal callback);
+    public abstract boolean checkAttention(long timeoutMillis, AttentionCallbackInternal callback);
 
     /**
      * Cancels the specified attention check in case it's no longer needed.
      *
-     * @param requestCode a code provided during {@link #checkAttention}
+     * @param callback a callback that was used in {@link #checkAttention}
      */
-    public abstract void cancelAttentionCheck(int requestCode);
+    public abstract void cancelAttentionCheck(AttentionCallbackInternal callback);
 
     /**
      * Disables the dependants.
@@ -62,19 +58,17 @@
         /**
          * Provides the result of the attention check, if the check was successful.
          *
-         * @param requestCode a code provided in {@link #checkAttention}
          * @param result      an int with the result of the check
          * @param timestamp   a {@code SystemClock.uptimeMillis()} timestamp associated with the
          *                    attention check
          */
-        public abstract void onSuccess(int requestCode, int result, long timestamp);
+        public abstract void onSuccess(int result, long timestamp);
 
         /**
          * Provides the explanation for why the attention check had failed.
          *
-         * @param requestCode a code provided in {@link #checkAttention}
          * @param error       an int with the reason for failure
          */
-        public abstract void onFailure(int requestCode, int error);
+        public abstract void onFailure(int error);
     }
 }
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 032e5ac..d87171e 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3115,21 +3115,14 @@
      * <p>
      * The path to the file is contained in {@link Intent#getData()}.
      *
-     * @deprecated Starting in the {@link android.os.Build.VERSION_CODES#Q}
-     *             release, shared storage paths are sandboxed per application,
-     *             and this broadcast cannot correctly translate those sandboxed
-     *             paths. Callers will need to instead migrate to using
-     *             {@link MediaScannerConnection}.
+     * @deprecated Callers should migrate to inserting items directly into
+     *             {@link MediaStore}, where they will be automatically scanned
+     *             after each mutation.
      */
     @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
     @Deprecated
     public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
 
-    /** @hide */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    @Deprecated
-    public static final String ACTION_MEDIA_SCANNER_SCAN_VOLUME = "android.intent.action.MEDIA_SCANNER_SCAN_VOLUME";
-
    /**
      * Broadcast Action:  The "Media Button" was pressed.  Includes a single
      * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3edd17a..1e6cea3 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -497,6 +497,36 @@
     }
 
     /**
+     * Returns an active staged session, or {@code null} if there is none.
+     *
+     * <p>Staged session is active iff:
+     * <ul>
+     *     <li>It is committed.
+     *     <li>It is not applied.
+     *     <li>It is not failed.
+     * </ul>
+     *
+     * <p>In case of a multi-apk session, parent session will be returned.
+     */
+    public @Nullable SessionInfo getActiveStagedSession() {
+        final List<SessionInfo> stagedSessions = getStagedSessions();
+        for (SessionInfo s : stagedSessions) {
+            if (s.isStagedSessionApplied() || s.isStagedSessionFailed()) {
+                // Finalized session.
+                continue;
+            }
+            if (s.getParentSessionId() != SessionInfo.INVALID_ID) {
+                // Child session.
+                continue;
+            }
+            if (s.isCommitted()) {
+                return s;
+            }
+        }
+        return null;
+    }
+
+    /**
      * Uninstall the given package, removing it completely from the device. This
      * method is available to:
      * <ul>
@@ -1770,6 +1800,9 @@
         private String mStagedSessionErrorMessage;
 
         /** {@hide} */
+        public boolean isCommitted;
+
+        /** {@hide} */
         @UnsupportedAppUsage
         public SessionInfo() {
         }
@@ -1809,6 +1842,7 @@
             isStagedSessionFailed = source.readBoolean();
             mStagedSessionErrorCode = source.readInt();
             mStagedSessionErrorMessage = source.readString();
+            isCommitted = source.readBoolean();
         }
 
         /**
@@ -2181,6 +2215,13 @@
             mStagedSessionErrorMessage = errorMessage;
         }
 
+        /**
+         * Whenever this session was committed.
+         */
+        public boolean isCommitted() {
+            return isCommitted;
+        }
+
         @Override
         public int describeContents() {
             return 0;
@@ -2218,6 +2259,7 @@
             dest.writeBoolean(isStagedSessionFailed);
             dest.writeInt(mStagedSessionErrorCode);
             dest.writeString(mStagedSessionErrorMessage);
+            dest.writeBoolean(isCommitted);
         }
 
         public static final Parcelable.Creator<SessionInfo>
diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java
index df67117..f851799 100644
--- a/core/java/android/content/pm/ShortcutManager.java
+++ b/core/java/android/content/pm/ShortcutManager.java
@@ -15,8 +15,10 @@
  */
 package android.content.pm;
 
+import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.TestApi;
@@ -565,6 +567,7 @@
      */
     @NonNull
     @SystemApi
+    @RequiresPermission(Manifest.permission.MANAGE_APP_PREDICTIONS)
     public List<ShareShortcutInfo> getShareTargets(@NonNull IntentFilter filter) {
         try {
             return mService.getShareTargets(mContext.getPackageName(), filter,
diff --git a/core/java/android/hardware/display/NightDisplayListener.java b/core/java/android/hardware/display/NightDisplayListener.java
index 468f833..3638572 100644
--- a/core/java/android/hardware/display/NightDisplayListener.java
+++ b/core/java/android/hardware/display/NightDisplayListener.java
@@ -35,119 +35,137 @@
 public class NightDisplayListener {
 
     private final Context mContext;
-    private final int mUserId;
     private final ColorDisplayManager mManager;
+    private final Handler mHandler;
+    private final ContentObserver mContentObserver;
+    private final int mUserId;
 
-    private ContentObserver mContentObserver;
     private Callback mCallback;
 
     public NightDisplayListener(@NonNull Context context) {
-        this(context, ActivityManager.getCurrentUser());
+        this(context, ActivityManager.getCurrentUser(), new Handler(Looper.getMainLooper()));
     }
 
-    public NightDisplayListener(@NonNull Context context, @UserIdInt int userId) {
+    public NightDisplayListener(@NonNull Context context, @NonNull Handler handler) {
+        this(context, ActivityManager.getCurrentUser(), handler);
+    }
+
+    public NightDisplayListener(@NonNull Context context, @UserIdInt int userId,
+            @NonNull Handler handler) {
         mContext = context.getApplicationContext();
-        mUserId = userId;
         mManager = mContext.getSystemService(ColorDisplayManager.class);
+        mUserId = userId;
+
+        mHandler = handler;
+        mContentObserver = new ContentObserver(mHandler) {
+            @Override
+            public void onChange(boolean selfChange, Uri uri) {
+                super.onChange(selfChange, uri);
+                final String setting = uri == null ? null : uri.getLastPathSegment();
+                if (setting != null && mCallback != null) {
+                    switch (setting) {
+                        case Secure.NIGHT_DISPLAY_ACTIVATED:
+                            mCallback.onActivated(mManager.isNightDisplayActivated());
+                            break;
+                        case Secure.NIGHT_DISPLAY_AUTO_MODE:
+                            mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
+                            break;
+                        case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
+                            mCallback.onCustomStartTimeChanged(
+                                    mManager.getNightDisplayCustomStartTime());
+                            break;
+                        case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
+                            mCallback.onCustomEndTimeChanged(
+                                    mManager.getNightDisplayCustomEndTime());
+                            break;
+                        case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
+                            mCallback.onColorTemperatureChanged(
+                                    mManager.getNightDisplayColorTemperature());
+                            break;
+                    }
+                }
+            }
+        };
     }
 
     /**
      * Register a callback to be invoked whenever the Night display settings are changed.
      */
     public void setCallback(Callback callback) {
+        if (Looper.myLooper() != mHandler.getLooper()) {
+            mHandler.post(() -> setCallbackInternal(callback));
+        }
+        setCallbackInternal(callback);
+    }
+
+    private void setCallbackInternal(Callback newCallback) {
         final Callback oldCallback = mCallback;
-        if (oldCallback != callback) {
-            mCallback = callback;
-
-            if (mContentObserver == null) {
-                mContentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
-                    @Override
-                    public void onChange(boolean selfChange, Uri uri) {
-                        super.onChange(selfChange, uri);
-                        onSettingChanged(uri);
-                    }
-                };
-            }
-
-            if (callback == null) {
-                // Stop listening for changes now that there IS NOT a callback.
+        if (oldCallback != newCallback) {
+            mCallback = newCallback;
+            if (mCallback == null) {
                 mContext.getContentResolver().unregisterContentObserver(mContentObserver);
             } else if (oldCallback == null) {
-                // Start listening for changes now that there IS a callback.
                 final ContentResolver cr = mContext.getContentResolver();
                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_ACTIVATED),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
                 cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_AUTO_MODE),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
-                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
+                cr.registerContentObserver(
+                        Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_START_TIME),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
-                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
+                cr.registerContentObserver(
+                        Secure.getUriFor(Secure.NIGHT_DISPLAY_CUSTOM_END_TIME),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
-                cr.registerContentObserver(Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
+                cr.registerContentObserver(
+                        Secure.getUriFor(Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE),
                         false /* notifyForDescendants */, mContentObserver, mUserId);
             }
         }
     }
 
-    private void onSettingChanged(Uri uri) {
-        final String setting = uri == null ? null : uri.getLastPathSegment();
-        if (setting == null || mCallback == null) {
-            return;
-        }
-
-        switch (setting) {
-            case Secure.NIGHT_DISPLAY_ACTIVATED:
-                mCallback.onActivated(mManager.isNightDisplayActivated());
-                break;
-            case Secure.NIGHT_DISPLAY_AUTO_MODE:
-                mCallback.onAutoModeChanged(mManager.getNightDisplayAutoMode());
-                break;
-            case Secure.NIGHT_DISPLAY_CUSTOM_START_TIME:
-                mCallback.onCustomStartTimeChanged(mManager.getNightDisplayCustomStartTime());
-                break;
-            case Secure.NIGHT_DISPLAY_CUSTOM_END_TIME:
-                mCallback.onCustomEndTimeChanged(mManager.getNightDisplayCustomEndTime());
-                break;
-            case Secure.NIGHT_DISPLAY_COLOR_TEMPERATURE:
-                mCallback.onColorTemperatureChanged(mManager.getNightDisplayColorTemperature());
-                break;
-        }
-    }
-
     /**
      * Callback invoked whenever the Night display settings are changed.
      */
     public interface Callback {
+
         /**
          * Callback invoked when the activated state changes.
          *
          * @param activated {@code true} if Night display is activated
          */
-        default void onActivated(boolean activated) {}
+        default void onActivated(boolean activated) {
+        }
+
         /**
          * Callback invoked when the auto mode changes.
          *
          * @param autoMode the auto mode to use
          */
-        default void onAutoModeChanged(int autoMode) {}
+        default void onAutoModeChanged(int autoMode) {
+        }
+
         /**
          * Callback invoked when the time to automatically activate Night display changes.
          *
          * @param startTime the local time to automatically activate Night display
          */
-        default void onCustomStartTimeChanged(LocalTime startTime) {}
+        default void onCustomStartTimeChanged(LocalTime startTime) {
+        }
+
         /**
          * Callback invoked when the time to automatically deactivate Night display changes.
          *
          * @param endTime the local time to automatically deactivate Night display
          */
-        default void onCustomEndTimeChanged(LocalTime endTime) {}
+        default void onCustomEndTimeChanged(LocalTime endTime) {
+        }
 
         /**
          * Callback invoked when the color temperature changes.
          *
          * @param colorTemperature the color temperature to tint the screen
          */
-        default void onColorTemperatureChanged(int colorTemperature) {}
+        default void onColorTemperatureChanged(int colorTemperature) {
+        }
     }
 }
diff --git a/core/java/android/net/StaticIpConfiguration.java b/core/java/android/net/StaticIpConfiguration.java
index e253105..565f36f 100644
--- a/core/java/android/net/StaticIpConfiguration.java
+++ b/core/java/android/net/StaticIpConfiguration.java
@@ -134,7 +134,7 @@
      * route to the gateway as well. This configuration is arguably invalid, but it used to work
      * in K and earlier, and other OSes appear to accept it.
      */
-    public @NonNull List<RouteInfo> getRoutes(String iface) {
+    public @NonNull List<RouteInfo> getRoutes(@Nullable String iface) {
         List<RouteInfo> routes = new ArrayList<RouteInfo>(3);
         if (ipAddress != null) {
             RouteInfo connectedRoute = new RouteInfo(ipAddress, null, iface);
diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java
index 45b665d..c9d7b1b 100644
--- a/core/java/android/net/metrics/ValidationProbeEvent.java
+++ b/core/java/android/net/metrics/ValidationProbeEvent.java
@@ -153,11 +153,14 @@
         return (probeType & 0xff) | (firstValidation ? FIRST_VALIDATION : REVALIDATION);
     }
 
-    public static String getProbeName(int probeType) {
+    /**
+     * Get the name of a probe specified by its probe type.
+     */
+    public static @NonNull String getProbeName(int probeType) {
         return Decoder.constants.get(probeType & 0xff, "PROBE_???");
     }
 
-    private static String getValidationStage(int probeType) {
+    private static @NonNull String getValidationStage(int probeType) {
         return Decoder.constants.get(probeType & 0xff00, "UNKNOWN");
     }
 
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 6a01e56..7cc7ccd 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -30,6 +30,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
+import android.os.storage.IStorageManager;
 import android.provider.Settings;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
@@ -38,6 +39,8 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.internal.content.PackageHelper;
+
 import libcore.io.Streams;
 
 import java.io.ByteArrayInputStream;
@@ -854,6 +857,21 @@
     /** {@hide} */
     public static void rebootPromptAndWipeUserData(Context context, String reason)
             throws IOException {
+        boolean checkpointing = false;
+
+        // If we are running in checkpointing mode, we should not prompt a wipe.
+        // Checkpointing may save us. If it doesn't, we will wind up here again.
+        try {
+            IStorageManager storageManager = PackageHelper.getStorageManager();
+            if (storageManager.needsCheckpoint()) {
+                Log.i(TAG, "Rescue Party requested wipe. Aborting update instead.");
+                storageManager.abortChanges("rescueparty", false);
+            }
+            return;
+        } catch (RemoteException e) {
+            Log.i(TAG, "Failed to handle with checkpointing. Continuing with wipe.");
+        }
+
         String reasonArg = null;
         if (!TextUtils.isEmpty(reason)) {
             reasonArg = "--reason=" + sanitizeArg(reason);
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl
index 25f67f8..9db4111 100644
--- a/core/java/android/os/storage/IStorageManager.aidl
+++ b/core/java/android/os/storage/IStorageManager.aidl
@@ -193,4 +193,6 @@
     void commitChanges() = 83;
     boolean supportsCheckpoint() = 84;
     void startCheckpoint(int numTries) = 85;
+    boolean needsCheckpoint() = 86;
+    void abortChanges(in String message, boolean retry) = 87;
 }
diff --git a/core/java/android/provider/DeviceConfig.java b/core/java/android/provider/DeviceConfig.java
index 4322a59..728d77e 100644
--- a/core/java/android/provider/DeviceConfig.java
+++ b/core/java/android/provider/DeviceConfig.java
@@ -27,6 +27,8 @@
 import android.annotation.TestApi;
 import android.app.ActivityThread;
 import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.provider.Settings.ResetMode;
@@ -37,6 +39,7 @@
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.util.Preconditions;
 
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -257,6 +260,14 @@
     public static final String NAMESPACE_TEXTCLASSIFIER = "textclassifier";
 
     /**
+     * List of namespaces which can be read without READ_DEVICE_CONFIG permission
+     *
+     * @hide
+     */
+    @NonNull
+    private static final List<String> PUBLIC_NAMESPACES =
+            Arrays.asList(NAMESPACE_TEXTCLASSIFIER, NAMESPACE_RUNTIME);
+    /**
      * Privacy related properties definitions.
      *
      * @hide
@@ -527,6 +538,8 @@
             @NonNull String namespace,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnPropertyChangedListener onPropertyChangedListener) {
+        enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(),
+                namespace);
         synchronized (sLock) {
             Pair<String, Executor> oldNamespace = sSingleListeners.get(onPropertyChangedListener);
             if (oldNamespace == null) {
@@ -566,6 +579,8 @@
             @NonNull String namespace,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnPropertiesChangedListener onPropertiesChangedListener) {
+        enforceReadPermission(ActivityThread.currentApplication().getApplicationContext(),
+                namespace);
         synchronized (sLock) {
             Pair<String, Executor> oldNamespace = sListeners.get(onPropertiesChangedListener);
             if (oldNamespace == null) {
@@ -667,7 +682,7 @@
     }
 
     /**
-     * Decrement the count used to represent th enumber of listeners subscribed to the given
+     * Decrement the count used to represent the number of listeners subscribed to the given
      * namespace. If this is the final decrement call (i.e. decrementing from 1 to 0) for the given
      * namespace, the ContentObserver that had been tracking it will be removed.
      *
@@ -696,7 +711,14 @@
         // pathSegments(0) is "config"
         final String namespace = pathSegments.get(1);
         final String name = pathSegments.get(2);
-        final String value = getProperty(namespace, name);
+        final String value;
+        try {
+            value = getProperty(namespace, name);
+        } catch (SecurityException e) {
+            // Silently failing to not crash binder or listener threads.
+            Log.e(TAG, "OnPropertyChangedListener update failed: permission violation.");
+            return;
+        }
         synchronized (sLock) {
             // OnPropertiesChangedListeners
             for (int i = 0; i < sListeners.size(); i++) {
@@ -730,6 +752,22 @@
         }
     }
 
+
+    /**
+     * Enforces READ_DEVICE_CONFIG permission if namespace is not one of public namespaces.
+     * @hide
+     */
+    public static void enforceReadPermission(Context context, String namespace) {
+        if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
+                != PackageManager.PERMISSION_GRANTED) {
+            if (!PUBLIC_NAMESPACES.contains(namespace)) {
+                throw new SecurityException("Permission denial: reading from settings requires:"
+                        + READ_DEVICE_CONFIG);
+            }
+        }
+    }
+
+
     /**
      * Interface for monitoring single property changes.
      * <p>
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index dc5fdc0..7feeeee 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -115,9 +115,9 @@
      */
     public static final String VOLUME_EXTERNAL = "external";
 
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_FILE_CALL = "scan_file";
-    /** {@hide} */ @TestApi
+    /** {@hide} */
     public static final String SCAN_VOLUME_CALL = "scan_volume";
 
     /**
@@ -126,7 +126,6 @@
      *
      * {@hide}
      */
-    @TestApi
     public static final String EXTRA_ORIGINATED_FROM_SHELL =
             "android.intent.extra.originated_from_shell";
 
@@ -3539,12 +3538,32 @@
     }
 
     /** @hide */
+    @TestApi
     public static Uri scanFile(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, false);
+    }
+
+    /** @hide */
+    @TestApi
+    public static Uri scanFileFromShell(Context context, File file) {
+        return scan(context, SCAN_FILE_CALL, file, true);
+    }
+
+    /** @hide */
+    @TestApi
+    public static void scanVolume(Context context, File file) {
+        scan(context, SCAN_VOLUME_CALL, file, false);
+    }
+
+    /** @hide */
+    private static Uri scan(Context context, String method, File file,
+            boolean originatedFromShell) {
         final ContentResolver resolver = context.getContentResolver();
         try (ContentProviderClient client = resolver.acquireContentProviderClient(AUTHORITY)) {
             final Bundle in = new Bundle();
             in.putParcelable(Intent.EXTRA_STREAM, Uri.fromFile(file));
-            final Bundle out = client.call(SCAN_FILE_CALL, null, in);
+            in.putBoolean(EXTRA_ORIGINATED_FROM_SHELL, originatedFromShell);
+            final Bundle out = client.call(method, null, in);
             return out.getParcelable(Intent.EXTRA_STREAM);
         } catch (RemoteException e) {
             throw e.rethrowAsRuntimeException();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 53c7eda..702dc74 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8045,17 +8045,6 @@
                 BOOLEAN_VALIDATOR;
 
         /**
-         * Whether the swipe up gesture to switch apps should be enabled.
-         *
-         * @hide
-         */
-        public static final String SWIPE_UP_TO_SWITCH_APPS_ENABLED =
-                "swipe_up_to_switch_apps_enabled";
-
-        private static final Validator SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR =
-                BOOLEAN_VALIDATOR;
-
-        /**
          * Whether or not the smart camera lift trigger that launches the camera when the user moves
          * the phone into a position for taking photos should be enabled.
          *
@@ -8739,7 +8728,6 @@
             DISPLAY_WHITE_BALANCE_ENABLED,
             SYNC_PARENT_SOUNDS,
             CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
-            SWIPE_UP_TO_SWITCH_APPS_ENABLED,
             CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
             SYSTEM_NAVIGATION_KEYS_ENABLED,
             QS_TILES,
@@ -8902,8 +8890,6 @@
             VALIDATORS.put(SYNC_PARENT_SOUNDS, SYNC_PARENT_SOUNDS_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED,
                     CAMERA_DOUBLE_TWIST_TO_FLIP_ENABLED_VALIDATOR);
-            VALIDATORS.put(SWIPE_UP_TO_SWITCH_APPS_ENABLED,
-                    SWIPE_UP_TO_SWITCH_APPS_ENABLED_VALIDATOR);
             VALIDATORS.put(CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED,
                     CAMERA_DOUBLE_TAP_POWER_GESTURE_DISABLED_VALIDATOR);
             VALIDATORS.put(SYSTEM_NAVIGATION_KEYS_ENABLED,
diff --git a/core/java/android/service/attention/AttentionService.java b/core/java/android/service/attention/AttentionService.java
index 84f440f..6172ce5 100644
--- a/core/java/android/service/attention/AttentionService.java
+++ b/core/java/android/service/attention/AttentionService.java
@@ -40,7 +40,7 @@
  * The system's default AttentionService implementation is configured in
  * {@code config_AttentionComponent}. If this config has no value, a stub is returned.
  *
- * See: {@link AttentionManagerService}.
+ * See: {@link com.android.server.attention.AttentionManagerService}.
  *
  * <pre>
  * {@literal
@@ -109,15 +109,16 @@
 
         /** {@inheritDoc} */
         @Override
-        public void checkAttention(int requestCode, IAttentionCallback callback) {
+        public void checkAttention(IAttentionCallback callback) {
             Preconditions.checkNotNull(callback);
-            AttentionService.this.onCheckAttention(requestCode, new AttentionCallback(callback));
+            AttentionService.this.onCheckAttention(new AttentionCallback(callback));
         }
 
         /** {@inheritDoc} */
         @Override
-        public void cancelAttentionCheck(int requestCode) {
-            AttentionService.this.onCancelAttentionCheck(requestCode);
+        public void cancelAttentionCheck(IAttentionCallback callback) {
+            Preconditions.checkNotNull(callback);
+            AttentionService.this.onCancelAttentionCheck(new AttentionCallback(callback));
         }
     };
 
@@ -146,35 +147,43 @@
     /**
      * Checks the user attention and calls into the provided callback.
      *
-     * @param requestCode an identifier that could be used to cancel the request
-     * @param callback    the callback to return the result to
+     * @param callback the callback to return the result to
      */
-    public abstract void onCheckAttention(int requestCode, @NonNull AttentionCallback callback);
+    public abstract void onCheckAttention(@NonNull AttentionCallback callback);
 
-    /** Cancels the attention check for a given request code. */
-    public abstract void onCancelAttentionCheck(int requestCode);
+    /**
+     * Cancels pending work for a given callback.
+     *
+     * Implementation must call back with a failure code of {@link #ATTENTION_FAILURE_CANCELLED}.
+     */
+    public abstract void onCancelAttentionCheck(@NonNull AttentionCallback callback);
 
     /** Callbacks for AttentionService results. */
     public static final class AttentionCallback {
-        private final IAttentionCallback mCallback;
+        @NonNull private final IAttentionCallback mCallback;
 
-        private AttentionCallback(IAttentionCallback callback) {
+        private AttentionCallback(@NonNull IAttentionCallback callback) {
             mCallback = callback;
         }
 
-        /** Returns the result. */
-        public void onSuccess(int requestCode, @AttentionSuccessCodes int result, long timestamp) {
+        /**
+         * Signals a success and provides the result code.
+         *
+         * @param timestamp of when the attention signal was computed; system throttles the requests
+         *                  so this is useful to know how fresh the result is.
+         */
+        public void onSuccess(@AttentionSuccessCodes int result, long timestamp) {
             try {
-                mCallback.onSuccess(requestCode, result, timestamp);
+                mCallback.onSuccess(result, timestamp);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
         }
 
-        /** Signals a failure. */
-        public void onFailure(int requestCode, @AttentionFailureCodes int error) {
+        /** Signals a failure and provides the error code. */
+        public void onFailure(@AttentionFailureCodes int error) {
             try {
-                mCallback.onFailure(requestCode, error);
+                mCallback.onFailure(error);
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
diff --git a/core/java/android/service/attention/IAttentionCallback.aidl b/core/java/android/service/attention/IAttentionCallback.aidl
index 0e8a1e7..f65b9c0 100644
--- a/core/java/android/service/attention/IAttentionCallback.aidl
+++ b/core/java/android/service/attention/IAttentionCallback.aidl
@@ -22,6 +22,6 @@
  * @hide
  */
 oneway interface IAttentionCallback {
-    void onSuccess(int requestCode, int result, long timestamp);
-    void onFailure(int requestCode, int error);
+    void onSuccess(int result, long timestamp);
+    void onFailure(int error);
 }
diff --git a/core/java/android/service/attention/IAttentionService.aidl b/core/java/android/service/attention/IAttentionService.aidl
index c3b6f48..99e7997 100644
--- a/core/java/android/service/attention/IAttentionService.aidl
+++ b/core/java/android/service/attention/IAttentionService.aidl
@@ -24,6 +24,6 @@
  * @hide
  */
 oneway interface IAttentionService {
-    void checkAttention(int requestCode, IAttentionCallback callback);
-    void cancelAttentionCheck(int requestCode);
+    void checkAttention(IAttentionCallback callback);
+    void cancelAttentionCheck(IAttentionCallback callback);
 }
\ No newline at end of file
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index a1932b8..b81725d 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -234,7 +234,7 @@
     public final void adjustNotification(@NonNull Adjustment adjustment) {
         if (!isBound()) return;
         try {
-            getNotificationInterface().applyAdjustmentFromAssistant(mWrapper, adjustment);
+            getNotificationInterface().applyEnqueuedAdjustmentFromAssistant(mWrapper, adjustment);
         } catch (android.os.RemoteException ex) {
             Log.v(TAG, "Unable to contact notification manager", ex);
             throw ex.rethrowFromSystemServer();
diff --git a/core/java/android/service/watchdog/ExplicitHealthCheckService.java b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
new file mode 100644
index 0000000..015fba1
--- /dev/null
+++ b/core/java/android/service/watchdog/ExplicitHealthCheckService.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.watchdog;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A service to provide packages supporting explicit health checks and route checks to these
+ * packages on behalf of the package watchdog.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with the
+ * {@link android.Manifest.permission#BIND_EXPLICIT_HEALTH_CHECK_SERVICE} permission,
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. In adddition,
+ * your implementation must live in {@link PackageManger#SYSTEM_SHARED_LIBRARY_SERVICES}.
+ * For example:</p>
+ * <pre>
+ *     &lt;service android:name=".FooExplicitHealthCheckService"
+ *             android:exported="true"
+ *             android:priority="100"
+ *             android:permission="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"&gt;
+ *         &lt;intent-filter&gt;
+ *             &lt;action android:name="android.service.watchdog.ExplicitHealthCheckService" /&gt;
+ *         &lt;/intent-filter&gt;
+ *     &lt;/service&gt;
+ * </pre>
+ * @hide
+ */
+@SystemApi
+public abstract class ExplicitHealthCheckService extends Service {
+
+    private static final String TAG = "ExplicitHealthCheckService";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_SUPPORTED_PACKAGES =
+            "android.service.watchdog.extra.supported_packages";
+
+    /**
+     * {@link Bundle} key for a {@link List} of {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_REQUESTED_PACKAGES =
+            "android.service.watchdog.extra.requested_packages";
+
+    /**
+     * {@link Bundle} key for a {@link String} value.
+     *
+     * {@hide}
+     */
+    public static final String EXTRA_HEALTH_CHECK_PASSED_PACKAGE =
+            "android.service.watchdog.extra.health_check_passed_package";
+
+    /**
+     * The Intent action that a service must respond to. Add it to the intent filter of the service
+     * in its manifest.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE =
+            "android.service.watchdog.ExplicitHealthCheckService";
+
+    /**
+     * The permission that a service must require to ensure that only Android system can bind to it.
+     * If this permission is not enforced in the AndroidManifest of the service, the system will
+     * skip that service.
+     */
+    public static final String BIND_PERMISSION =
+            "android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE";
+
+    private final ExplicitHealthCheckServiceWrapper mWrapper =
+            new ExplicitHealthCheckServiceWrapper();
+
+    /**
+     * Called when the system requests an explicit health check for {@code packageName}.
+     *
+     * <p> When {@code packageName} passes the check, implementors should call
+     * {@link #notifyHealthCheckPassed} to inform the system.
+     *
+     * <p> It could take many hours before a {@code packageName} passes a check and implementors
+     * should never drop requests unless {@link onCancel} is called or the service dies.
+     *
+     * <p> Requests should not be queued and additional calls while expecting a result for
+     * {@code packageName} should have no effect.
+     */
+    public abstract void onRequestHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system cancels the explicit health check request for {@code packageName}.
+     * Should do nothing if there are is no active request for {@code packageName}.
+     */
+    public abstract void onCancelHealthCheck(@NonNull String packageName);
+
+    /**
+     * Called when the system requests for all the packages supporting explicit health checks. The
+     * system may request an explicit health check for any of these packages with
+     * {@link #onRequestHealthCheck}.
+     *
+     * @return all packages supporting explicit health checks
+     */
+    @NonNull public abstract List<String> onGetSupportedPackages();
+
+    /**
+     * Called when the system requests for all the packages that it has currently requested
+     * an explicit health check for.
+     *
+     * @return all packages expecting an explicit health check result
+     */
+    @NonNull public abstract List<String> onGetRequestedPackages();
+
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
+    @Nullable private RemoteCallback mCallback;
+
+    @Override
+    @NonNull
+    public final IBinder onBind(@NonNull Intent intent) {
+        return mWrapper;
+    }
+
+    /**
+     * Implementors should call this to notify the system when explicit health check passes
+     * for {@code packageName};
+     */
+    public final void notifyHealthCheckPassed(@NonNull String packageName) {
+        mHandler.post(() -> {
+            if (mCallback != null) {
+                Objects.requireNonNull(packageName,
+                        "Package passing explicit health check must be non-null");
+                Bundle bundle = new Bundle();
+                bundle.putString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE, packageName);
+                mCallback.sendResult(bundle);
+            } else {
+                Log.wtf(TAG, "System missed explicit health check result for " + packageName);
+            }
+        });
+    }
+
+    private class ExplicitHealthCheckServiceWrapper extends IExplicitHealthCheckService.Stub {
+        @Override
+        public void setCallback(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> {
+                mCallback = callback;
+            });
+        }
+
+        @Override
+        public void request(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onRequestHealthCheck(packageName));
+        }
+
+        @Override
+        public void cancel(String packageName) throws RemoteException {
+            mHandler.post(() -> ExplicitHealthCheckService.this.onCancelHealthCheck(packageName));
+        }
+
+        @Override
+        public void getSupportedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_SUPPORTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetSupportedPackages()));
+        }
+
+        @Override
+        public void getRequestedPackages(RemoteCallback callback) throws RemoteException {
+            mHandler.post(() -> sendPackages(callback, EXTRA_REQUESTED_PACKAGES,
+                    ExplicitHealthCheckService.this.onGetRequestedPackages()));
+        }
+
+        private void sendPackages(RemoteCallback callback, String key, List<String> packages) {
+            Objects.requireNonNull(packages,
+                    "Supported and requested package list must be non-null");
+            Bundle bundle = new Bundle();
+            bundle.putStringArrayList(key, new ArrayList<>(packages));
+            callback.sendResult(bundle);
+        }
+    }
+}
diff --git a/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
new file mode 100644
index 0000000..78c0328d
--- /dev/null
+++ b/core/java/android/service/watchdog/IExplicitHealthCheckService.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.watchdog;
+
+import android.os.RemoteCallback;
+
+/**
+ * @hide
+ */
+oneway interface IExplicitHealthCheckService
+{
+    void setCallback(in @nullable RemoteCallback callback);
+    void request(String packageName);
+    void cancel(String packageName);
+    void getSupportedPackages(in RemoteCallback callback);
+    void getRequestedPackages(in RemoteCallback callback);
+}
diff --git a/core/java/com/android/internal/app/AlertActivity.java b/core/java/com/android/internal/app/AlertActivity.java
index 999a908..0b08099 100644
--- a/core/java/com/android/internal/app/AlertActivity.java
+++ b/core/java/com/android/internal/app/AlertActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.DialogInterface;
@@ -38,11 +39,13 @@
      * 
      * @see #mAlertParams
      */
+    @UnsupportedAppUsage
     protected AlertController mAlert;
 
     /**
      * The parameters for the alert.
      */
+    @UnsupportedAppUsage
     protected AlertController.AlertParams mAlertParams;
 
     @Override
@@ -90,6 +93,7 @@
      * @see #mAlert
      * @see #mAlertParams
      */
+    @UnsupportedAppUsage
     protected void setupAlert() {
         mAlert.installContent(mAlertParams);
     }
diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java
index d0102a7..efcdb9a 100644
--- a/core/java/com/android/internal/app/AssistUtils.java
+++ b/core/java/com/android/internal/app/AssistUtils.java
@@ -17,6 +17,7 @@
 package com.android.internal.app;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
@@ -42,6 +43,7 @@
     private final Context mContext;
     private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
 
+    @UnsupportedAppUsage
     public AssistUtils(Context context) {
         mContext = context;
         mVoiceInteractionManagerService = IVoiceInteractionManagerService.Stub.asInterface(
@@ -168,6 +170,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public ComponentName getAssistComponentForUser(int userId) {
         final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
                 Settings.Secure.ASSISTANT, userId);
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 54fff9b..4f5678a 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -24,6 +24,7 @@
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.prediction.AppPredictionContext;
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java
index 64f0010..3811fe4 100644
--- a/core/java/com/android/internal/app/IntentForwarderActivity.java
+++ b/core/java/com/android/internal/app/IntentForwarderActivity.java
@@ -20,6 +20,7 @@
 
 import android.annotation.Nullable;
 import android.annotation.StringRes;
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityTaskManager;
 import android.app.ActivityThread;
@@ -54,6 +55,7 @@
  * be passed in and out of a managed profile.
  */
 public class IntentForwarderActivity extends Activity  {
+    @UnsupportedAppUsage
     public static String TAG = "IntentForwarderActivity";
 
     public static String FORWARD_INTENT_TO_PARENT
diff --git a/core/java/com/android/internal/app/LocaleHelper.java b/core/java/com/android/internal/app/LocaleHelper.java
index 0a230a9..aef4dbf 100644
--- a/core/java/com/android/internal/app/LocaleHelper.java
+++ b/core/java/com/android/internal/app/LocaleHelper.java
@@ -17,6 +17,7 @@
 package com.android.internal.app;
 
 import android.annotation.IntRange;
+import android.annotation.UnsupportedAppUsage;
 import android.icu.text.ListFormatter;
 import android.icu.util.ULocale;
 import android.os.LocaleList;
@@ -84,6 +85,7 @@
      * @param locale the locale that might be used for certain operations (i.e. case conversion)
      * @return the string normalized for search
      */
+    @UnsupportedAppUsage
     public static String normalizeForSearch(String str, Locale locale) {
         // TODO: tbd if it needs to be smarter (real normalization, remove accents, etc.)
         // If needed we might use case folding and ICU/CLDR's collation-based loose searching.
@@ -109,6 +111,7 @@
      * @param sentenceCase true if the result should be sentence-cased
      * @return the localized name of the locale.
      */
+    @UnsupportedAppUsage
     public static String getDisplayName(Locale locale, Locale displayLocale, boolean sentenceCase) {
         final ULocale displayULocale = ULocale.forLocale(displayLocale);
         String result = shouldUseDialectName(locale)
@@ -135,6 +138,7 @@
      * @param displayLocale the locale in which to display the name.
      * @return the localized country name.
      */
+    @UnsupportedAppUsage
     public static String getDisplayCountry(Locale locale, Locale displayLocale) {
         final String languageTag = locale.toLanguageTag();
         final ULocale uDisplayLocale = ULocale.forLocale(displayLocale);
@@ -226,6 +230,7 @@
          *
          * @param sortLocale the locale to be used for sorting.
          */
+        @UnsupportedAppUsage
         public LocaleInfoComparator(Locale sortLocale, boolean countryMode) {
             mCollator = Collator.getInstance(sortLocale);
             mCountryMode = countryMode;
@@ -253,6 +258,7 @@
          * @return  a negative integer, zero, or a positive integer as the first
          *          argument is less than, equal to, or greater than the second.
          */
+        @UnsupportedAppUsage
         @Override
         public int compare(LocaleStore.LocaleInfo lhs, LocaleStore.LocaleInfo rhs) {
             // We don't care about the various suggestion types, just "suggested" (!= 0)
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index c8c2fcf..7517424 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.IActivityManager;
 import android.app.ListFragment;
@@ -70,6 +71,7 @@
             return label;
         }
 
+        @UnsupportedAppUsage
         public Locale getLocale() {
             return locale;
         }
@@ -251,6 +253,7 @@
      *
      * @see #updateLocales(LocaleList)
      */
+    @UnsupportedAppUsage
     public static void updateLocale(Locale locale) {
         updateLocales(new LocaleList(locale));
     }
@@ -260,6 +263,7 @@
      * Note that the system looks halted for a while during the Locale migration,
      * so the caller need to take care of it.
      */
+    @UnsupportedAppUsage
     public static void updateLocales(LocaleList locales) {
         try {
             final IActivityManager am = ActivityManager.getService();
@@ -281,6 +285,7 @@
      *
      * @return The locale list.
      */
+    @UnsupportedAppUsage
     public static LocaleList getLocales() {
         try {
             return ActivityManager.getService()
diff --git a/core/java/com/android/internal/app/LocaleStore.java b/core/java/com/android/internal/app/LocaleStore.java
index 1d997f5..c11089b 100644
--- a/core/java/com/android/internal/app/LocaleStore.java
+++ b/core/java/com/android/internal/app/LocaleStore.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.os.LocaleList;
 import android.provider.Settings;
@@ -81,14 +82,17 @@
             return mId;
         }
 
+        @UnsupportedAppUsage
         public Locale getLocale() {
             return mLocale;
         }
 
+        @UnsupportedAppUsage
         public Locale getParent() {
             return mParent;
         }
 
+        @UnsupportedAppUsage
         public String getId() {
             return mId;
         }
@@ -115,6 +119,7 @@
             return (mSuggestionFlags & suggestionMask) == suggestionMask;
         }
 
+        @UnsupportedAppUsage
         public String getFullNameNative() {
             if (mFullNameNative == null) {
                 mFullNameNative =
@@ -140,6 +145,7 @@
          * For instance German will show as "Deutsch" in the list, but we will also search for
          * "allemand" if the system UI is in French.
          */
+        @UnsupportedAppUsage
         public String getFullNameInUiLanguage() {
             // We don't cache the UI name because the default locale keeps changing
             return LocaleHelper.getDisplayName(mLocale, true /* sentence case */);
@@ -254,6 +260,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public static void fillCache(Context context) {
         if (sFullyInitialized) {
             return;
@@ -340,6 +347,7 @@
      * Example: if the parent is "ar", then the region list will contain all Arabic locales.
      * (this is not language based, but language-script, so that it works for zh-Hant and so on.
      */
+    @UnsupportedAppUsage
     public static Set<LocaleInfo> getLevelLocales(Context context, Set<String> ignorables,
             LocaleInfo parent, boolean translatedOnly) {
         fillCache(context);
@@ -365,6 +373,7 @@
         return result;
     }
 
+    @UnsupportedAppUsage
     public static LocaleInfo getLocaleInfo(Locale locale) {
         String id = locale.toLanguageTag();
         LocaleInfo result;
diff --git a/core/java/com/android/internal/app/NetInitiatedActivity.java b/core/java/com/android/internal/app/NetInitiatedActivity.java
index d3bae16..9a802a9 100644
--- a/core/java/com/android/internal/app/NetInitiatedActivity.java
+++ b/core/java/com/android/internal/app/NetInitiatedActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.app;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.AlertDialog;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -141,6 +142,7 @@
         locationManager.sendNiResponse(notificationId, response);
     }
 
+    @UnsupportedAppUsage
     private void handleNIVerify(Intent intent) {
         int notifId = intent.getIntExtra(GpsNetInitiatedHandler.NI_INTENT_KEY_NOTIF_ID, -1);
         notificationId = notifId;
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 21152ae..84a1bed 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -21,6 +21,7 @@
 import android.annotation.Nullable;
 import android.annotation.StringRes;
 import android.annotation.UiThread;
+import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityTaskManager;
@@ -99,6 +100,7 @@
     // Temporary flag for new chooser delegate behavior.
     boolean mEnableChooserDelegate = true;
 
+    @UnsupportedAppUsage
     protected ResolveListAdapter mAdapter;
     private boolean mSafeForwardingMode;
     protected AbsListView mAdapterView;
@@ -121,6 +123,7 @@
     // Whether or not this activity supports choosing a default handler for the intent.
     private boolean mSupportsAlwaysUseOption;
     protected ResolverDrawerLayout mResolverDrawerLayout;
+    @UnsupportedAppUsage
     protected PackageManager mPm;
     protected int mLaunchedFromUid;
 
@@ -257,6 +260,7 @@
      * Compatibility version for other bundled services that use this overload without
      * a default title resource
      */
+    @UnsupportedAppUsage
     protected void onCreate(Bundle savedInstanceState, Intent intent,
             CharSequence title, Intent[] initialIntents,
             List<ResolveInfo> rList, boolean supportsAlwaysUseOption) {
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index 119f30d..e71ee66 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -84,6 +84,7 @@
     private ActionBarContextView mContextView;
     private ActionBarContainer mSplitView;
     private View mContentView;
+    @UnsupportedAppUsage
     private ScrollingTabContainerView mTabScrollView;
 
     private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
@@ -331,6 +332,7 @@
      *
      * @param enabled true to animate, false to not animate.
      */
+    @UnsupportedAppUsage
     public void setShowHideAnimationEnabled(boolean enabled) {
         mShowHideAnimationEnabled = enabled;
         if (!enabled && mCurrentShowAnim != null) {
@@ -1147,6 +1149,7 @@
      * @hide
      */
     public class TabImpl extends ActionBar.Tab {
+        @UnsupportedAppUsage
         private ActionBar.TabListener mCallback;
         private Object mTag;
         private Drawable mIcon;
diff --git a/core/java/com/android/internal/database/SortCursor.java b/core/java/com/android/internal/database/SortCursor.java
index 0025512..7fe809e 100644
--- a/core/java/com/android/internal/database/SortCursor.java
+++ b/core/java/com/android/internal/database/SortCursor.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.database;
 
+import android.annotation.UnsupportedAppUsage;
 import android.database.AbstractCursor;
 import android.database.Cursor;
 import android.database.DataSetObserver;
@@ -28,7 +29,9 @@
 public class SortCursor extends AbstractCursor
 {
     private static final String TAG = "SortCursor";
+    @UnsupportedAppUsage
     private Cursor mCursor; // updated in onMove
+    @UnsupportedAppUsage
     private Cursor[] mCursors;
     private int [] mSortColumns;
     private final int ROWCACHESIZE = 64;
@@ -52,6 +55,7 @@
         }
     };
     
+    @UnsupportedAppUsage
     public SortCursor(Cursor[] cursors, String sortcolumn)
     {
         mCursors = cursors;
diff --git a/core/java/com/android/internal/http/HttpDateTime.java b/core/java/com/android/internal/http/HttpDateTime.java
index 8ebd4aa..f7706e3 100644
--- a/core/java/com/android/internal/http/HttpDateTime.java
+++ b/core/java/com/android/internal/http/HttpDateTime.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.http;
 
+import android.annotation.UnsupportedAppUsage;
 import android.text.format.Time;
 
 import java.util.Calendar;
@@ -82,6 +83,7 @@
         int second;
     }
 
+    @UnsupportedAppUsage
     public static long parse(String timeString)
             throws IllegalArgumentException {
 
diff --git a/core/java/com/android/internal/os/AndroidPrintStream.java b/core/java/com/android/internal/os/AndroidPrintStream.java
index 7f4807a..fe23411 100644
--- a/core/java/com/android/internal/os/AndroidPrintStream.java
+++ b/core/java/com/android/internal/os/AndroidPrintStream.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.Log;
 
 /**
@@ -34,6 +35,7 @@
      * @param priority from {@link android.util.Log}
      * @param tag to log
      */
+    @UnsupportedAppUsage
     public AndroidPrintStream(int priority, String tag) {
         if (tag == null) {
             throw new NullPointerException("tag");
diff --git a/core/java/com/android/internal/os/BaseCommand.java b/core/java/com/android/internal/os/BaseCommand.java
index 05ec9e9..278f406 100644
--- a/core/java/com/android/internal/os/BaseCommand.java
+++ b/core/java/com/android/internal/os/BaseCommand.java
@@ -17,12 +17,14 @@
 
 package com.android.internal.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.ShellCommand;
 
 import java.io.PrintStream;
 
 public abstract class BaseCommand {
 
+    @UnsupportedAppUsage
     final protected ShellCommand mArgs = new ShellCommand() {
         @Override public int onCommand(String cmd) {
             return 0;
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index aa4846f..4901e1f 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -17,6 +17,7 @@
 package com.android.internal.os;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.IBinder;
@@ -157,6 +158,7 @@
      * an implementation of IServiceManager, which you can use to find
      * other services.
      */
+    @UnsupportedAppUsage
     public static final native IBinder getContextObject();
 
     /**
@@ -168,6 +170,7 @@
 
     public static final native void setMaxThreads(int numThreads);
 
+    @UnsupportedAppUsage
     static native final void handleGc();
 
     public static void forceGc(String reason) {
diff --git a/core/java/com/android/internal/os/ClassLoaderFactory.java b/core/java/com/android/internal/os/ClassLoaderFactory.java
index 99a1a19..d323498 100644
--- a/core/java/com/android/internal/os/ClassLoaderFactory.java
+++ b/core/java/com/android/internal/os/ClassLoaderFactory.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Trace;
 
 import dalvik.system.DelegateLastClassLoader;
@@ -132,6 +133,7 @@
         return classLoader;
     }
 
+    @UnsupportedAppUsage
     private static native String createClassloaderNamespace(ClassLoader classLoader,
                                                             int targetSdkVersion,
                                                             String librarySearchPath,
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 4b878c7..6179918 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -18,6 +18,7 @@
 
 import static android.os.Process.*;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.FileUtils;
 import android.os.Process;
 import android.os.StrictMode;
@@ -191,6 +192,7 @@
         public boolean interesting;
 
         public String baseName;
+        @UnsupportedAppUsage
         public String name;
         public int nameWidth;
 
@@ -206,6 +208,7 @@
         /**
          * Time in milliseconds.
          */
+        @UnsupportedAppUsage
         public long rel_uptime;
 
         /**
@@ -221,11 +224,13 @@
         /**
          * Time in milliseconds.
          */
+        @UnsupportedAppUsage
         public int rel_utime;
 
         /**
          * Time in milliseconds.
          */
+        @UnsupportedAppUsage
         public int rel_stime;
 
         public long base_minfaults;
@@ -286,6 +291,7 @@
     };
 
 
+    @UnsupportedAppUsage
     public ProcessCpuTracker(boolean includeThreads) {
         mIncludeThreads = includeThreads;
         long jiffyHz = Os.sysconf(OsConstants._SC_CLK_TCK);
@@ -305,6 +311,7 @@
         update();
     }
 
+    @UnsupportedAppUsage
     public void update() {
         if (DEBUG) Slog.v(TAG, "Update: " + this);
 
@@ -707,11 +714,13 @@
         return statses;
     }
 
+    @UnsupportedAppUsage
     final public int countWorkingStats() {
         buildWorkingProcs();
         return mWorkingProcs.size();
     }
 
+    @UnsupportedAppUsage
     final public Stats getWorkingStats(int index) {
         return mWorkingProcs.get(index);
     }
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index e37e650..eac150d 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.ActivityThread;
 import android.app.ApplicationErrorReport;
@@ -48,8 +49,10 @@
     final static boolean DEBUG = false;
 
     /** true if commonInit() has been called */
+    @UnsupportedAppUsage
     private static boolean initialized;
 
+    @UnsupportedAppUsage
     private static IBinder mApplicationObject;
 
     private static volatile boolean mCrashing = false;
@@ -186,6 +189,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     protected static final void commonInit() {
         if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
 
@@ -315,6 +319,7 @@
         return new MethodAndArgsCaller(m, argv);
     }
 
+    @UnsupportedAppUsage
     public static final void main(String[] argv) {
         enableDdms();
         if (argv.length == 2 && argv[1].equals("application")) {
@@ -402,6 +407,7 @@
         mApplicationObject = app;
     }
 
+    @UnsupportedAppUsage
     public static final IBinder getApplicationObject() {
         return mApplicationObject;
     }
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 87adce7..922c721 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,6 +26,7 @@
 import static com.android.internal.os.ZygoteConnectionConstants.CONNECTION_TIMEOUT_MILLIS;
 import static com.android.internal.os.ZygoteConnectionConstants.WRAPPED_PID_TIMEOUT_MILLIS;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.pm.ApplicationInfo;
 import android.metrics.LogMaker;
 import android.net.Credentials;
@@ -69,9 +70,12 @@
      * that it closes when the child process terminates. In other cases,
      * it is closed in the peer.
      */
+    @UnsupportedAppUsage
     private final LocalSocket mSocket;
+    @UnsupportedAppUsage
     private final DataOutputStream mSocketOutStream;
     private final BufferedReader mSocketReader;
+    @UnsupportedAppUsage
     private final Credentials peer;
     private final String abiList;
     private boolean isEof;
@@ -522,6 +526,7 @@
     /**
      * Closes socket associated with this connection.
      */
+    @UnsupportedAppUsage
     void closeSocket() {
         try {
             mSocket.close();
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 07b82d0..dd18060 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,6 +19,7 @@
 import static android.system.OsConstants.S_IRWXG;
 import static android.system.OsConstants.S_IRWXO;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.os.Build;
@@ -102,6 +103,7 @@
     /**
      * Used to pre-load resources.
      */
+    @UnsupportedAppUsage
     private static Resources mResources;
 
     /**
@@ -777,6 +779,7 @@
         return result;
     }
 
+    @UnsupportedAppUsage
     public static void main(String argv[]) {
         ZygoteServer zygoteServer = null;
 
diff --git a/core/java/com/android/internal/os/ZygoteSecurityException.java b/core/java/com/android/internal/os/ZygoteSecurityException.java
index 13b4759..7e50cb8 100644
--- a/core/java/com/android/internal/os/ZygoteSecurityException.java
+++ b/core/java/com/android/internal/os/ZygoteSecurityException.java
@@ -16,10 +16,13 @@
 
 package com.android.internal.os;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * Exception thrown when a security policy is violated.
  */
 class ZygoteSecurityException extends RuntimeException {
+    @UnsupportedAppUsage
     ZygoteSecurityException(String message) {
         super(message);
     }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index b3cfa49..ca5db94 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -46,6 +46,7 @@
 import android.animation.ObjectAnimator;
 import android.annotation.Nullable;
 import android.annotation.TestApi;
+import android.annotation.UnsupportedAppUsage;
 import android.app.WindowConfiguration;
 import android.content.Context;
 import android.content.res.Configuration;
@@ -210,8 +211,11 @@
     private final BackgroundFallback mBackgroundFallback = new BackgroundFallback();
 
     private int mLastTopInset = 0;
+    @UnsupportedAppUsage
     private int mLastBottomInset = 0;
+    @UnsupportedAppUsage
     private int mLastRightInset = 0;
+    @UnsupportedAppUsage
     private int mLastLeftInset = 0;
     private boolean mLastHasTopStableInset = false;
     private boolean mLastHasBottomStableInset = false;
@@ -222,6 +226,7 @@
 
     private int mRootScrollY = 0;
 
+    @UnsupportedAppUsage
     private PhoneWindow mWindow;
 
     ViewGroup mContentRoot;
diff --git a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
index d8ee4dd..791c2d7 100644
--- a/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
+++ b/core/java/com/android/internal/policy/PhoneFallbackEventHandler.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.policy;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.KeyguardManager;
 import android.app.SearchManager;
 import android.content.ActivityNotFoundException;
@@ -41,7 +42,9 @@
     private static String TAG = "PhoneFallbackEventHandler";
     private static final boolean DEBUG = false;
 
+    @UnsupportedAppUsage
     Context mContext;
+    @UnsupportedAppUsage
     View mView;
 
     AudioManager mAudioManager;
@@ -50,6 +53,7 @@
     TelephonyManager mTelephonyManager;
     MediaSessionManager mMediaSessionManager;
 
+    @UnsupportedAppUsage
     public PhoneFallbackEventHandler(Context context) {
         mContext = context;
     }
@@ -74,6 +78,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     boolean onKeyDown(int keyCode, KeyEvent event) {
         /* ****************************************************************************
          * HOW TO DECIDE WHERE YOUR KEY HANDLING GOES.
@@ -207,6 +212,7 @@
                 && (getKeyguardManager().inKeyguardRestrictedInputMode() || dispatcher == null);
     }
 
+    @UnsupportedAppUsage
     boolean onKeyUp(int keyCode, KeyEvent event) {
         if (DEBUG) {
             Log.d(TAG, "up " + keyCode);
@@ -270,6 +276,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     void startCallActivity() {
         sendCloseSystemWindows();
         Intent intent = new Intent(Intent.ACTION_CALL_BUTTON);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 69efb2b..890ee86 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -34,6 +34,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND;
 
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityManager;
 import android.app.KeyguardManager;
 import android.app.SearchManager;
@@ -246,6 +247,7 @@
     private boolean mForcedStatusBarColor = false;
     private boolean mForcedNavigationBarColor = false;
 
+    @UnsupportedAppUsage
     private CharSequence mTitle = null;
 
     private int mTitleColor = 0;
@@ -309,6 +311,7 @@
 
     static final RotationWatcher sRotationWatcher = new RotationWatcher();
 
+    @UnsupportedAppUsage
     public PhoneWindow(Context context) {
         super(context);
         mLayoutInflater = LayoutInflater.from(context);
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index ff5b996..3303374 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArraySet;
 
 import dalvik.system.VMRuntime;
@@ -55,6 +56,7 @@
         return (char[])VMRuntime.getRuntime().newUnpaddedArray(char.class, minLen);
     }
 
+    @UnsupportedAppUsage
     public static int[] newUnpaddedIntArray(int minLen) {
         return (int[])VMRuntime.getRuntime().newUnpaddedArray(int.class, minLen);
     }
@@ -75,6 +77,7 @@
         return (Object[])VMRuntime.getRuntime().newUnpaddedArray(Object.class, minLen);
     }
 
+    @UnsupportedAppUsage
     @SuppressWarnings("unchecked")
     public static <T> T[] newUnpaddedArray(Class<T> clazz, int minLen) {
         return (T[])VMRuntime.getRuntime().newUnpaddedArray(clazz, minLen);
@@ -112,6 +115,7 @@
      * it will return the same empty array every time to avoid reallocation,
      * although this is not guaranteed.
      */
+    @UnsupportedAppUsage
     @SuppressWarnings("unchecked")
     public static <T> T[] emptyArray(Class<T> kind) {
         if (kind == Object.class) {
@@ -148,6 +152,7 @@
     /**
      * Checks if given array is null or has zero elements.
      */
+    @UnsupportedAppUsage
     public static <T> boolean isEmpty(@Nullable T[] array) {
         return array == null || array.length == 0;
     }
@@ -200,6 +205,7 @@
      * @param value the value to check for
      * @return true if the value is present in the array
      */
+    @UnsupportedAppUsage
     public static <T> boolean contains(@Nullable T[] array, T value) {
         return indexOf(array, value) != -1;
     }
@@ -208,6 +214,7 @@
      * Return first index of {@code value} in {@code array}, or {@code -1} if
      * not found.
      */
+    @UnsupportedAppUsage
     public static <T> int indexOf(@Nullable T[] array, T value) {
         if (array == null) return -1;
         for (int i = 0; i < array.length; i++) {
@@ -242,6 +249,7 @@
         return false;
     }
 
+    @UnsupportedAppUsage
     public static boolean contains(@Nullable int[] array, int value) {
         if (array == null) return false;
         for (int element : array) {
@@ -333,6 +341,7 @@
      * Adds value to given array if not already present, providing set-like
      * behavior.
      */
+    @UnsupportedAppUsage
     @SuppressWarnings("unchecked")
     public static @NonNull <T> T[] appendElement(Class<T> kind, @Nullable T[] array, T element) {
         return appendElement(kind, array, element, false);
@@ -362,6 +371,7 @@
     /**
      * Removes value from given array if present, providing set-like behavior.
      */
+    @UnsupportedAppUsage
     @SuppressWarnings("unchecked")
     public static @Nullable <T> T[] removeElement(Class<T> kind, @Nullable T[] array, T element) {
         if (array != null) {
@@ -408,6 +418,7 @@
      * Adds value to given array if not already present, providing set-like
      * behavior.
      */
+    @UnsupportedAppUsage
     public static @NonNull int[] appendInt(@Nullable int[] cur, int val) {
         return appendInt(cur, val, false);
     }
diff --git a/core/java/com/android/internal/util/BitwiseInputStream.java b/core/java/com/android/internal/util/BitwiseInputStream.java
index 86f74f3..6ff67e9 100644
--- a/core/java/com/android/internal/util/BitwiseInputStream.java
+++ b/core/java/com/android/internal/util/BitwiseInputStream.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * An object that provides bitwise incremental read access to a byte array.
  *
@@ -49,6 +51,7 @@
      *
      * @param buf a byte array containing data
      */
+    @UnsupportedAppUsage
     public BitwiseInputStream(byte buf[]) {
         mBuf = buf;
         mEnd = buf.length << 3;
@@ -58,6 +61,7 @@
     /**
      * Return the number of bit still available for reading.
      */
+    @UnsupportedAppUsage
     public int available() {
         return mEnd - mPos;
     }
@@ -71,6 +75,7 @@
      * @param bits the amount of data to read (gte 0, lte 8)
      * @return byte of read data (possibly partially filled, from lsb)
      */
+    @UnsupportedAppUsage
     public int read(int bits) throws AccessException {
         int index = mPos >>> 3;
         int offset = 16 - (mPos & 0x07) - bits;  // &7==%8
@@ -92,6 +97,7 @@
      * @param bits the amount of data to read
      * @return newly allocated byte array of read data
      */
+    @UnsupportedAppUsage
     public byte[] readByteArray(int bits) throws AccessException {
         int bytes = (bits >>> 3) + ((bits & 0x07) > 0 ? 1 : 0);  // &7==%8
         byte[] arr = new byte[bytes];
@@ -107,6 +113,7 @@
      *
      * @param bits the amount by which to increment the position
      */
+    @UnsupportedAppUsage
     public void skip(int bits) throws AccessException {
         if ((mPos + bits) > mEnd) {
             throw new AccessException("illegal skip " +
diff --git a/core/java/com/android/internal/util/BitwiseOutputStream.java b/core/java/com/android/internal/util/BitwiseOutputStream.java
index ddecbed..cdd6f17 100644
--- a/core/java/com/android/internal/util/BitwiseOutputStream.java
+++ b/core/java/com/android/internal/util/BitwiseOutputStream.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * An object that provides bitwise incremental write access to a byte array.
  *
@@ -49,6 +51,7 @@
      *
      * @param startingLength initial internal byte array length in bytes
      */
+    @UnsupportedAppUsage
     public BitwiseOutputStream(int startingLength) {
         mBuf = new byte[startingLength];
         mEnd = startingLength << 3;
@@ -60,6 +63,7 @@
      *
      * @return newly allocated byte array
      */
+    @UnsupportedAppUsage
     public byte[] toByteArray() {
         int len = (mPos >>> 3) + ((mPos & 0x07) > 0 ? 1 : 0);  // &7==%8
         byte[] newBuf = new byte[len];
@@ -89,6 +93,7 @@
      * @param bits the amount of data to write (gte 0, lte 8)
      * @param data to write, will be masked to expose only bits param from lsb
      */
+    @UnsupportedAppUsage
     public void write(int bits, int data) throws AccessException {
         if ((bits < 0) || (bits > 8)) {
             throw new AccessException("illegal write (" + bits + " bits)");
@@ -109,6 +114,7 @@
      * @param bits the amount of data to write
      * @param arr the byte array containing data to be written
      */
+    @UnsupportedAppUsage
     public void writeByteArray(int bits, byte[] arr) throws AccessException {
         for (int i = 0; i < arr.length; i++) {
             int increment = Math.min(8, bits - (i << 3));
diff --git a/core/java/com/android/internal/util/CharSequences.java b/core/java/com/android/internal/util/CharSequences.java
index fdaa4bc..6b6c43c 100644
--- a/core/java/com/android/internal/util/CharSequences.java
+++ b/core/java/com/android/internal/util/CharSequences.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * {@link CharSequence} utility methods.
  */
@@ -93,6 +95,7 @@
     /**
      * Compares two character sequences for equality.
      */
+    @UnsupportedAppUsage
     public static boolean equals(CharSequence a, CharSequence b) {
         if (a.length() != b.length()) {
             return false;
@@ -114,6 +117,7 @@
      * @param another The other CharSequence.
      * @return See {@link Comparable#compareTo}.
      */
+    @UnsupportedAppUsage
     public static int compareToIgnoreCase(CharSequence me, CharSequence another) {
         // Code adapted from String#compareTo
         int myLen = me.length(), anotherLen = another.length();
diff --git a/core/java/com/android/internal/util/FastMath.java b/core/java/com/android/internal/util/FastMath.java
index 88a17e6..35efe70 100644
--- a/core/java/com/android/internal/util/FastMath.java
+++ b/core/java/com/android/internal/util/FastMath.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * Fast and loose math routines.
  */
@@ -26,6 +28,7 @@
      * thought it may return slightly different results. It does not try to
      * handle (in any meaningful way) NaN or infinities.
      */
+    @UnsupportedAppUsage
     public static int round(float value) {
         long lx = (long) (value * (65536 * 256f));
         return (int) ((lx + 0x800000) >> 24);
diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java
index b85b84f..9f76aeb 100644
--- a/core/java/com/android/internal/util/FastXmlSerializer.java
+++ b/core/java/com/android/internal/util/FastXmlSerializer.java
@@ -18,6 +18,7 @@
 
 import org.xmlpull.v1.XmlSerializer;
 
+import android.annotation.UnsupportedAppUsage;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
@@ -69,6 +70,7 @@
     private int mNesting = 0;
     private boolean mLineStart = true;
 
+    @UnsupportedAppUsage
     public FastXmlSerializer() {
         this(DEFAULT_BUFFER_LEN);
     }
diff --git a/core/java/com/android/internal/util/GrowingArrayUtils.java b/core/java/com/android/internal/util/GrowingArrayUtils.java
index 968d920..9f56366 100644
--- a/core/java/com/android/internal/util/GrowingArrayUtils.java
+++ b/core/java/com/android/internal/util/GrowingArrayUtils.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
+
 /**
  * A helper class that aims to provide comparable growth performance to ArrayList, but on primitive
  * arrays. Common array operations are implemented for efficient use in dynamic containers.
@@ -37,6 +39,7 @@
      * @return the array to which the element was appended. This may be different than the given
      *         array.
      */
+    @UnsupportedAppUsage
     public static <T> T[] append(T[] array, int currentSize, T element) {
         assert currentSize <= array.length;
 
@@ -54,6 +57,7 @@
     /**
      * Primitive int version of {@link #append(Object[], int, Object)}.
      */
+    @UnsupportedAppUsage
     public static int[] append(int[] array, int currentSize, int element) {
         assert currentSize <= array.length;
 
diff --git a/core/java/com/android/internal/util/HexDump.java b/core/java/com/android/internal/util/HexDump.java
index af00400..6ffc928 100644
--- a/core/java/com/android/internal/util/HexDump.java
+++ b/core/java/com/android/internal/util/HexDump.java
@@ -17,6 +17,7 @@
 package com.android.internal.util;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 
 public class HexDump
 {
@@ -100,16 +101,19 @@
         return toHexString(toByteArray(b));
     }
 
+    @UnsupportedAppUsage
     public static String toHexString(byte[] array)
     {
         return toHexString(array, 0, array.length, true);
     }
 
+    @UnsupportedAppUsage
     public static String toHexString(byte[] array, boolean upperCase)
     {
         return toHexString(array, 0, array.length, upperCase);
     }
 
+    @UnsupportedAppUsage
     public static String toHexString(byte[] array, int offset, int length)
     {
         return toHexString(array, offset, length, true);
@@ -131,6 +135,7 @@
         return new String(buf);
     }
 
+    @UnsupportedAppUsage
     public static String toHexString(int i)
     {
         return toHexString(toByteArray(i));
@@ -164,6 +169,7 @@
         throw new RuntimeException ("Invalid hex char '" + c + "'");
     }
 
+    @UnsupportedAppUsage
     public static byte[] hexStringToByteArray(String hexString)
     {
         int length = hexString.length();
diff --git a/core/java/com/android/internal/util/IState.java b/core/java/com/android/internal/util/IState.java
index 056f8e9..eb66e2c 100644
--- a/core/java/com/android/internal/util/IState.java
+++ b/core/java/com/android/internal/util/IState.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Message;
 
 /**
@@ -67,5 +68,6 @@
      *
      * @return name of state.
      */
+    @UnsupportedAppUsage
     String getName();
 }
diff --git a/core/java/com/android/internal/util/MemInfoReader.java b/core/java/com/android/internal/util/MemInfoReader.java
index 8d71666..630916e 100644
--- a/core/java/com/android/internal/util/MemInfoReader.java
+++ b/core/java/com/android/internal/util/MemInfoReader.java
@@ -16,12 +16,14 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Debug;
 import android.os.StrictMode;
 
 public final class MemInfoReader {
     final long[] mInfos = new long[Debug.MEMINFO_COUNT];
 
+    @UnsupportedAppUsage
     public void readMemInfo() {
         // Permit disk reads here, as /proc/meminfo isn't really "on
         // disk" and should be fast.  TODO: make BlockGuard ignore
@@ -37,6 +39,7 @@
     /**
      * Total amount of RAM available to the kernel.
      */
+    @UnsupportedAppUsage
     public long getTotalSize() {
         return mInfos[Debug.MEMINFO_TOTAL] * 1024;
     }
@@ -44,6 +47,7 @@
     /**
      * Amount of RAM that is not being used for anything.
      */
+    @UnsupportedAppUsage
     public long getFreeSize() {
         return mInfos[Debug.MEMINFO_FREE] * 1024;
     }
@@ -52,6 +56,7 @@
      * Amount of RAM that the kernel is being used for caches, not counting caches
      * that are mapped in to processes.
      */
+    @UnsupportedAppUsage
     public long getCachedSize() {
         return getCachedSizeKb() * 1024;
     }
@@ -107,6 +112,7 @@
         return mInfos[Debug.MEMINFO_ZRAM_TOTAL];
     }
 
+    @UnsupportedAppUsage
     public long[] getRawInfo() {
         return mInfos;
     }
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index 2c6a0e0..731b93c 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -18,6 +18,7 @@
 
 import android.annotation.IntRange;
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.text.TextUtils;
 
 import java.util.Collection;
@@ -28,6 +29,7 @@
  */
 public class Preconditions {
 
+    @UnsupportedAppUsage
     public static void checkArgument(boolean expression) {
         if (!expression) {
             throw new IllegalArgumentException();
@@ -42,6 +44,7 @@
      *     be converted to a string using {@link String#valueOf(Object)}
      * @throws IllegalArgumentException if {@code expression} is false
      */
+    @UnsupportedAppUsage
     public static void checkArgument(boolean expression, final Object errorMessage) {
         if (!expression) {
             throw new IllegalArgumentException(String.valueOf(errorMessage));
@@ -106,6 +109,7 @@
      * @return the non-null reference that was validated
      * @throws NullPointerException if {@code reference} is null
      */
+    @UnsupportedAppUsage
     public static @NonNull <T> T checkNotNull(final T reference) {
         if (reference == null) {
             throw new NullPointerException();
@@ -123,6 +127,7 @@
      * @return the non-null reference that was validated
      * @throws NullPointerException if {@code reference} is null
      */
+    @UnsupportedAppUsage
     public static @NonNull <T> T checkNotNull(final T reference, final Object errorMessage) {
         if (reference == null) {
             throw new NullPointerException(String.valueOf(errorMessage));
@@ -158,6 +163,7 @@
      * @param message exception message
      * @throws IllegalStateException if {@code expression} is false
      */
+    @UnsupportedAppUsage
     public static void checkState(final boolean expression, String message) {
         if (!expression) {
             throw new IllegalStateException(message);
@@ -171,6 +177,7 @@
      * @param expression a boolean expression
      * @throws IllegalStateException if {@code expression} is false
      */
+    @UnsupportedAppUsage
     public static void checkState(final boolean expression) {
         checkState(expression, null);
     }
@@ -368,6 +375,7 @@
      *
      * @throws IllegalArgumentException if {@code value} was not within the range
      */
+    @UnsupportedAppUsage
     public static int checkArgumentInRange(int value, int lower, int upper,
             String valueName) {
         if (value < lower) {
diff --git a/core/java/com/android/internal/util/State.java b/core/java/com/android/internal/util/State.java
index 3eadff5..3c61e03 100644
--- a/core/java/com/android/internal/util/State.java
+++ b/core/java/com/android/internal/util/State.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.util;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Message;
 
 /**
@@ -28,12 +29,14 @@
     /**
      * Constructor
      */
+    @UnsupportedAppUsage
     protected State() {
     }
 
     /* (non-Javadoc)
      * @see com.android.internal.util.IState#enter()
      */
+    @UnsupportedAppUsage
     @Override
     public void enter() {
     }
@@ -41,6 +44,7 @@
     /* (non-Javadoc)
      * @see com.android.internal.util.IState#exit()
      */
+    @UnsupportedAppUsage
     @Override
     public void exit() {
     }
@@ -48,6 +52,7 @@
     /* (non-Javadoc)
      * @see com.android.internal.util.IState#processMessage(android.os.Message)
      */
+    @UnsupportedAppUsage
     @Override
     public boolean processMessage(Message msg) {
         return false;
@@ -65,6 +70,7 @@
      *
      * @see com.android.internal.util.IState#processMessage(android.os.Message)
      */
+    @UnsupportedAppUsage
     @Override
     public String getName() {
         String name = getClass().getName();
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 7398e95..dacdae6 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -1301,6 +1301,7 @@
      *
      * @param name of the state machine
      */
+    @UnsupportedAppUsage
     protected StateMachine(String name) {
         mSmThread = new HandlerThread(name);
         mSmThread.start();
@@ -1314,6 +1315,7 @@
      *
      * @param name of the state machine
      */
+    @UnsupportedAppUsage
     protected StateMachine(String name, Looper looper) {
         initStateMachine(name, looper);
     }
@@ -1323,6 +1325,7 @@
      *
      * @param name of the state machine
      */
+    @UnsupportedAppUsage
     protected StateMachine(String name, Handler handler) {
         initStateMachine(name, handler.getLooper());
     }
@@ -1678,6 +1681,7 @@
      * @param arg2  is assigned to Message.arg2
      * @return  A Message object from the global pool
      */
+    @UnsupportedAppUsage
     public final Message obtainMessage(int what, int arg1, int arg2) {
         return Message.obtain(mSmHandler, what, arg1, arg2);
     }
@@ -1697,6 +1701,7 @@
      * @param obj is assigned to Message.obj
      * @return  A Message object from the global pool
      */
+    @UnsupportedAppUsage
     public final Message obtainMessage(int what, int arg1, int arg2, Object obj) {
         return Message.obtain(mSmHandler, what, arg1, arg2, obj);
     }
@@ -1706,6 +1711,7 @@
      *
      * Message is ignored if state machine has quit.
      */
+    @UnsupportedAppUsage
     public void sendMessage(int what) {
         // mSmHandler can be null if the state machine has quit.
         SmHandler smh = mSmHandler;
@@ -1719,6 +1725,7 @@
      *
      * Message is ignored if state machine has quit.
      */
+    @UnsupportedAppUsage
     public void sendMessage(int what, Object obj) {
         // mSmHandler can be null if the state machine has quit.
         SmHandler smh = mSmHandler;
@@ -1732,6 +1739,7 @@
      *
      * Message is ignored if state machine has quit.
      */
+    @UnsupportedAppUsage
     public void sendMessage(int what, int arg1) {
         // mSmHandler can be null if the state machine has quit.
         SmHandler smh = mSmHandler;
@@ -1758,6 +1766,7 @@
      *
      * Message is ignored if state machine has quit.
      */
+    @UnsupportedAppUsage
     public void sendMessage(int what, int arg1, int arg2, Object obj) {
         // mSmHandler can be null if the state machine has quit.
         SmHandler smh = mSmHandler;
@@ -1771,6 +1780,7 @@
      *
      * Message is ignored if state machine has quit.
      */
+    @UnsupportedAppUsage
     public void sendMessage(Message msg) {
         // mSmHandler can be null if the state machine has quit.
         SmHandler smh = mSmHandler;
@@ -2074,6 +2084,7 @@
      * @param pw
      * @param args
      */
+    @UnsupportedAppUsage
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(getName() + ":");
         pw.println(" total records=" + getLogRecCount());
diff --git a/core/java/com/android/internal/view/ActionBarPolicy.java b/core/java/com/android/internal/view/ActionBarPolicy.java
index 755faf3..d18c35e 100644
--- a/core/java/com/android/internal/view/ActionBarPolicy.java
+++ b/core/java/com/android/internal/view/ActionBarPolicy.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.R;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -29,12 +30,15 @@
  * about how the action bar should lay out and behave on the current device.
  */
 public class ActionBarPolicy {
+    @UnsupportedAppUsage
     private Context mContext;
 
+    @UnsupportedAppUsage
     public static ActionBarPolicy get(Context context) {
         return new ActionBarPolicy(context);
     }
 
+    @UnsupportedAppUsage
     private ActionBarPolicy(Context context) {
         mContext = context;
     }
@@ -44,6 +48,7 @@
      * bar/action mode. This will be used to determine how many showAsAction="ifRoom" items can fit.
      * "always" items can override this.
      */
+    @UnsupportedAppUsage
     public int getMaxActionButtons() {
         final Configuration config = mContext.getResources().getConfiguration();
         final int width = config.screenWidthDp;
@@ -62,14 +67,17 @@
             return 2;
         }
     }
+    @UnsupportedAppUsage
     public boolean showsOverflowMenuButton() {
         return true;
     }
 
+    @UnsupportedAppUsage
     public int getEmbeddedMenuWidthLimit() {
         return mContext.getResources().getDisplayMetrics().widthPixels / 2;
     }
 
+    @UnsupportedAppUsage
     public boolean hasEmbeddedTabs() {
         final int targetSdk = mContext.getApplicationInfo().targetSdkVersion;
         if (targetSdk >= Build.VERSION_CODES.JELLY_BEAN) {
@@ -85,6 +93,7 @@
                 width >= 480 || (width >= 640 && height >= 480);
     }
 
+    @UnsupportedAppUsage
     public int getTabContainerHeight() {
         TypedArray a = mContext.obtainStyledAttributes(null, R.styleable.ActionBar,
                 com.android.internal.R.attr.actionBarStyle, 0);
@@ -106,6 +115,7 @@
                 Build.VERSION_CODES.ICE_CREAM_SANDWICH;
     }
 
+    @UnsupportedAppUsage
     public int getStackedTabMaxWidth() {
         return mContext.getResources().getDimensionPixelSize(
                 R.dimen.action_bar_stacked_tab_max_width);
diff --git a/core/java/com/android/internal/view/InputConnectionWrapper.java b/core/java/com/android/internal/view/InputConnectionWrapper.java
index 3bd3072..0c057ea 100644
--- a/core/java/com/android/internal/view/InputConnectionWrapper.java
+++ b/core/java/com/android/internal/view/InputConnectionWrapper.java
@@ -19,6 +19,7 @@
 import android.annotation.AnyThread;
 import android.annotation.BinderThread;
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.inputmethodservice.AbstractInputMethodService;
 import android.os.Bundle;
 import android.os.Handler;
@@ -78,6 +79,7 @@
          * sequence number is set to a new integer.  We use a sequence number so that replies that
          * occur after a timeout has expired are not interpreted as replies to a later request.
          */
+        @UnsupportedAppUsage
         @AnyThread
         private static InputContextCallback getInstance() {
             synchronized (InputContextCallback.class) {
@@ -102,6 +104,7 @@
         /**
          * Makes the given InputContextCallback available for use in the future.
          */
+        @UnsupportedAppUsage
         @AnyThread
         private void dispose() {
             synchronized (InputContextCallback.class) {
diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
index c8c38bb..b009a2d 100644
--- a/core/java/com/android/internal/view/WindowManagerPolicyThread.java
+++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.view;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Looper;
 
 /**
@@ -35,6 +36,7 @@
         return mThread;
     }
 
+    @UnsupportedAppUsage
     public static Looper getLooper() {
         return mLooper;
     }
diff --git a/core/java/com/android/internal/view/menu/ActionMenu.java b/core/java/com/android/internal/view/menu/ActionMenu.java
index c657b87..977c1f6 100644
--- a/core/java/com/android/internal/view/menu/ActionMenu.java
+++ b/core/java/com/android/internal/view/menu/ActionMenu.java
@@ -19,6 +19,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -39,6 +40,7 @@
     
     private ArrayList<ActionMenuItem> mItems;
 
+    @UnsupportedAppUsage
     public ActionMenu(Context context) {
         mContext = context;
         mItems = new ArrayList<ActionMenuItem>();
diff --git a/core/java/com/android/internal/view/menu/ActionMenuItem.java b/core/java/com/android/internal/view/menu/ActionMenuItem.java
index b807a42..ed253d5 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuItem.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuItem.java
@@ -17,6 +17,7 @@
 package com.android.internal.view.menu;
 
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.ColorStateList;
@@ -69,6 +70,7 @@
     private static final int HIDDEN         = 0x00000008;
     private static final int ENABLED        = 0x00000010;
 
+    @UnsupportedAppUsage
     public ActionMenuItem(Context context, int group, int id, int categoryOrder, int ordering,
             CharSequence title) {
         mContext = context;
diff --git a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
index 82f061c..3d3aceb 100644
--- a/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/ContextMenuBuilder.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.view.menu;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
 import android.os.IBinder;
@@ -39,6 +40,7 @@
  */
 public class ContextMenuBuilder extends MenuBuilder implements ContextMenu {
     
+    @UnsupportedAppUsage
     public ContextMenuBuilder(Context context) {
         super(context);
     }
diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java
index 6c8f330..3d888d3 100644
--- a/core/java/com/android/internal/view/menu/IconMenuItemView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.view.menu.MenuBuilder.ItemInvoker;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Rect;
@@ -213,6 +214,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void setItemInvoker(ItemInvoker itemInvoker) {
         mItemInvoker = itemInvoker;
     }
@@ -232,6 +234,7 @@
         }
     }
     
+    @UnsupportedAppUsage
     void setIconMenuView(IconMenuView iconMenuView) {
         mIconMenuView = iconMenuView;
     }
@@ -267,6 +270,7 @@
      * @return layout params appropriate for this view.  If layout params already exist, it will
      *         augment them to be appropriate to the current text size.
      */
+    @UnsupportedAppUsage
     IconMenuView.LayoutParams getTextAppropriateLayoutParams() {
         IconMenuView.LayoutParams lp = (IconMenuView.LayoutParams) getLayoutParams();
         if (lp == null) {
diff --git a/core/java/com/android/internal/view/menu/IconMenuView.java b/core/java/com/android/internal/view/menu/IconMenuView.java
index dab43eb..6f26434 100644
--- a/core/java/com/android/internal/view/menu/IconMenuView.java
+++ b/core/java/com/android/internal/view/menu/IconMenuView.java
@@ -18,6 +18,7 @@
 
 import com.android.internal.view.menu.MenuBuilder.ItemInvoker;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -51,6 +52,7 @@
 public final class IconMenuView extends ViewGroup implements ItemInvoker, MenuView, Runnable {
     private static final int ITEM_CAPTION_CYCLE_DELAY = 1000;
 
+    @UnsupportedAppUsage
     private MenuBuilder mMenu;
     
     /** Height of each row */
@@ -58,6 +60,7 @@
     /** Maximum number of rows to be shown */ 
     private int mMaxRows;
     /** Maximum number of items to show in the icon menu. */
+    @UnsupportedAppUsage
     private int mMaxItems;
     /** Maximum number of items per row */
     private int mMaxItemsPerRow;
@@ -82,6 +85,7 @@
     private Drawable mMoreIcon;
 
     /** Background of each item (should contain the selected and focused states) */
+    @UnsupportedAppUsage
     private Drawable mItemBackground;
 
     /** Default animations for this menu */
@@ -288,6 +292,7 @@
      * have a MenuItemData backing it.
      * @return The IconMenuItemView for the 'More' button
      */
+    @UnsupportedAppUsage
     IconMenuItemView createMoreItemView() {
         Context context = getContext();
         LayoutInflater inflater = LayoutInflater.from(context);
@@ -494,6 +499,7 @@
      *         {@link MenuView.ItemView} implementation--eg: excludes More
      *         item).
      */
+    @UnsupportedAppUsage
     int getNumActualItemsShown() {
         return mNumActualItemsShown;
     }
@@ -717,6 +723,7 @@
         /**
          * Constructor called from {@link #CREATOR}
          */
+        @UnsupportedAppUsage
         private SavedState(Parcel in) {
             super(in);
             focusedPosition = in.readInt();
diff --git a/core/java/com/android/internal/view/menu/MenuDialogHelper.java b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
index ecab29f..88d0a03 100644
--- a/core/java/com/android/internal/view/menu/MenuDialogHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuDialogHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.view.menu;
 
+import android.annotation.UnsupportedAppUsage;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
@@ -36,6 +37,7 @@
     ListMenuPresenter mPresenter;
     private MenuPresenter.Callback mPresenterCallback;
     
+    @UnsupportedAppUsage
     public MenuDialogHelper(MenuBuilder menu) {
         mMenu = menu;
     }
@@ -45,6 +47,7 @@
      * 
      * @param windowToken Optional token to assign to the window.
      */
+    @UnsupportedAppUsage
     public void show(IBinder windowToken) {
         // Many references to mMenu, create local reference
         final MenuBuilder menu = mMenu;
@@ -132,6 +135,7 @@
      * 
      * @see Dialog#dismiss()
      */
+    @UnsupportedAppUsage
     @Override
     public void dismiss() {
         if (mDialog != null) {
diff --git a/core/java/com/android/internal/widget/AbsActionBarView.java b/core/java/com/android/internal/widget/AbsActionBarView.java
index 582c4f1..9ccee7f 100644
--- a/core/java/com/android/internal/widget/AbsActionBarView.java
+++ b/core/java/com/android/internal/widget/AbsActionBarView.java
@@ -27,6 +27,7 @@
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -294,6 +295,7 @@
         return isOverflowReserved() && getVisibility() == VISIBLE;
     }
 
+    @UnsupportedAppUsage
     public void dismissPopupMenus() {
         if (mActionMenuPresenter != null) {
             mActionMenuPresenter.dismissPopupMenus();
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 693b194..78ed53f 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -21,6 +21,7 @@
 import android.widget.ActionMenuView;
 import com.android.internal.view.menu.MenuBuilder;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.drawable.Drawable;
@@ -58,6 +59,7 @@
         this(context, null);
     }
     
+    @UnsupportedAppUsage
     public ActionBarContextView(Context context, AttributeSet attrs) {
         this(context, attrs, com.android.internal.R.attr.actionModeStyle);
     }
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index ba0ff01..e9e3cda 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -18,6 +18,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -168,6 +169,7 @@
         init(context);
     }
 
+    @UnsupportedAppUsage
     public ActionBarOverlayLayout(Context context, AttributeSet attrs) {
         super(context, attrs);
         init(context);
@@ -671,6 +673,7 @@
         return finalY > mActionBarTop.getHeight();
     }
 
+    @UnsupportedAppUsage
     @Override
     public void setWindowCallback(Window.Callback cb) {
         pullChildren();
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 78688ed..2b648e9 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.Bundle;
 import android.text.Editable;
 import android.text.method.KeyListener;
@@ -39,6 +40,7 @@
     // A negative value means that this connection has been finished by the InputMethodManager.
     private int mBatchEditNesting;
 
+    @UnsupportedAppUsage
     public EditableInputConnection(TextView textview) {
         super(textview, true);
         mTextView = textview;
diff --git a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
index b2001cb..cc7911d 100644
--- a/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
+++ b/core/java/com/android/internal/widget/LinearLayoutWithDefaultTouchRecepient.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.Rect;
 import android.util.AttributeSet;
@@ -36,6 +37,7 @@
     private final Rect mTempRect = new Rect();
     private View mDefaultTouchRecepient;
 
+    @UnsupportedAppUsage
     public LinearLayoutWithDefaultTouchRecepient(Context context) {
         super(context);
     }
@@ -44,6 +46,7 @@
         super(context, attrs);
     }
 
+    @UnsupportedAppUsage
     public void setDefaultTouchRecepient(View defaultTouchRecepient) {
         mDefaultTouchRecepient = defaultTouchRecepient;
     }
diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java
index bda3b57..09bc28c 100644
--- a/core/java/com/android/internal/widget/LockPatternChecker.java
+++ b/core/java/com/android/internal/widget/LockPatternChecker.java
@@ -1,5 +1,6 @@
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.AsyncTask;
 
 import com.android.internal.widget.LockPatternUtils.RequestThrottledException;
@@ -245,6 +246,7 @@
      * @param callback The callback to be invoked with the check result.
      * @deprecated Pass passwords as byte[]
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static AsyncTask<?, ?, ?> checkPassword(final LockPatternUtils utils,
             final String password,
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index dd48c15..07f8ee0 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -27,6 +27,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.app.admin.DevicePolicyManager;
 import android.app.admin.PasswordMetrics;
 import android.app.trust.IStrongAuthTracker;
@@ -169,7 +170,9 @@
     public static final String SYNTHETIC_PASSWORD_ENABLED_KEY = "enable-sp";
     private static final String HISTORY_DELIMITER = ",";
 
+    @UnsupportedAppUsage
     private final Context mContext;
+    @UnsupportedAppUsage
     private final ContentResolver mContentResolver;
     private DevicePolicyManager mDevicePolicyManager;
     private ILockSettings mLockSettingsService;
@@ -213,6 +216,7 @@
 
     public static final class RequestThrottledException extends Exception {
         private int mTimeoutMs;
+        @UnsupportedAppUsage
         public RequestThrottledException(int timeoutMs) {
             mTimeoutMs = timeoutMs;
         }
@@ -221,12 +225,14 @@
          * @return The amount of time in ms before another request may
          * be executed
          */
+        @UnsupportedAppUsage
         public int getTimeoutMs() {
             return mTimeoutMs;
         }
 
     }
 
+    @UnsupportedAppUsage
     public DevicePolicyManager getDevicePolicyManager() {
         if (mDevicePolicyManager == null) {
             mDevicePolicyManager =
@@ -255,6 +261,7 @@
         return trust;
     }
 
+    @UnsupportedAppUsage
     public LockPatternUtils(Context context) {
         mContext = context;
         mContentResolver = context.getContentResolver();
@@ -263,6 +270,7 @@
         mHandler = looper != null ? new Handler(looper) : null;
     }
 
+    @UnsupportedAppUsage
     @VisibleForTesting
     public ILockSettings getLockSettings() {
         if (mLockSettingsService == null) {
@@ -317,6 +325,7 @@
         return getDevicePolicyManager().getPasswordMinimumNonLetter(null, userId);
     }
 
+    @UnsupportedAppUsage
     public void reportFailedPasswordAttempt(int userId) {
         if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
             return;
@@ -325,6 +334,7 @@
         getTrustManager().reportUnlockAttempt(false /* authenticated */, userId);
     }
 
+    @UnsupportedAppUsage
     public void reportSuccessfulPasswordAttempt(int userId) {
         if (userId == USER_FRP && frpCredentialEnabled(mContext)) {
             return;
@@ -485,6 +495,7 @@
      * @param password The password to check.
      * @return Whether the password matches the stored one.
      */
+    @UnsupportedAppUsage
     public boolean checkPassword(String password, int userId) throws RequestThrottledException {
         byte[] passwordBytes = password != null ? password.getBytes() : null;
         return checkPassword(passwordBytes, userId, null /* progressCallback */);
@@ -638,6 +649,7 @@
      * Used by device policy manager to validate the current password
      * information it has.
      */
+    @UnsupportedAppUsage
     public int getActivePasswordQuality(int userId) {
         int quality = getKeyguardStoredPasswordQuality(userId);
 
@@ -717,6 +729,7 @@
      *
      * @return true if lock screen is disabled
      */
+    @UnsupportedAppUsage
     public boolean isLockScreenDisabled(int userId) {
         if (isSecure(userId)) {
             return false;
@@ -814,16 +827,19 @@
         }
     }
 
+    @UnsupportedAppUsage
     public void setOwnerInfo(String info, int userId) {
         setString(LOCK_SCREEN_OWNER_INFO, info, userId);
         updateCryptoUserInfo(userId);
     }
 
+    @UnsupportedAppUsage
     public void setOwnerInfoEnabled(boolean enabled, int userId) {
         setBoolean(LOCK_SCREEN_OWNER_INFO_ENABLED, enabled, userId);
         updateCryptoUserInfo(userId);
     }
 
+    @UnsupportedAppUsage
     public String getOwnerInfo(int userId) {
         return getString(LOCK_SCREEN_OWNER_INFO, userId);
     }
@@ -1056,6 +1072,7 @@
      * encrypted with the default password.
      * @return true if device encryption is enabled
      */
+    @UnsupportedAppUsage
     public static boolean isDeviceEncryptionEnabled() {
         return StorageManager.isEncrypted();
     }
@@ -1081,6 +1098,7 @@
      *
      * @return stored password quality
      */
+    @UnsupportedAppUsage
     public int getKeyguardStoredPasswordQuality(int userHandle) {
         return (int) getLong(PASSWORD_TYPE_KEY, PASSWORD_QUALITY_UNSPECIFIED, userHandle);
     }
@@ -1198,6 +1216,7 @@
      * @return The pattern in string form.
      * @deprecated Use patternToByteArray instead.
      */
+    @UnsupportedAppUsage
     @Deprecated
     public static String patternToString(List<LockPatternView.Cell> pattern) {
         return new String(patternToByteArray(pattern));
@@ -1247,6 +1266,7 @@
      * @param pattern the gesture pattern.
      * @return the hash of the pattern in a byte array.
      */
+    @UnsupportedAppUsage
     public static byte[] patternToHash(List<LockPatternView.Cell> pattern) {
         if (pattern == null) {
             return null;
@@ -1344,11 +1364,13 @@
      * @param userId the user for which to report the value
      * @return Whether the lock screen is secured.
      */
+    @UnsupportedAppUsage
     public boolean isSecure(int userId) {
         int mode = getKeyguardStoredPasswordQuality(userId);
         return isLockPatternEnabled(mode, userId) || isLockPasswordEnabled(mode, userId);
     }
 
+    @UnsupportedAppUsage
     public boolean isLockPasswordEnabled(int userId) {
         return isLockPasswordEnabled(getKeyguardStoredPasswordQuality(userId), userId);
     }
@@ -1366,6 +1388,7 @@
     /**
      * @return Whether the lock pattern is enabled
      */
+    @UnsupportedAppUsage
     public boolean isLockPatternEnabled(int userId) {
         return isLockPatternEnabled(getKeyguardStoredPasswordQuality(userId), userId);
     }
@@ -1390,6 +1413,7 @@
     /**
      * @return Whether the visible pattern is enabled.
      */
+    @UnsupportedAppUsage
     public boolean isVisiblePatternEnabled(int userId) {
         return getBoolean(Settings.Secure.LOCK_PATTERN_VISIBLE, false, userId);
     }
@@ -1449,6 +1473,7 @@
     /**
      * @return Whether tactile feedback for the pattern is enabled.
      */
+    @UnsupportedAppUsage
     public boolean isTactileFeedbackEnabled() {
         return Settings.System.getIntForUser(mContentResolver,
                 Settings.System.HAPTIC_FEEDBACK_ENABLED, 1, UserHandle.USER_CURRENT) != 0;
@@ -1459,6 +1484,7 @@
      * pattern until the deadline has passed.
      * @return the chosen deadline.
      */
+    @UnsupportedAppUsage
     public long setLockoutAttemptDeadline(int userId, int timeoutMs) {
         final long deadline = SystemClock.elapsedRealtime() + timeoutMs;
         if (userId == USER_FRP) {
@@ -1511,6 +1537,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void setLong(String secureSettingKey, long value, int userHandle) {
         try {
             getLockSettings().setLong(secureSettingKey, value, userHandle);
@@ -1520,6 +1547,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private String getString(String secureSettingKey, int userHandle) {
         try {
             return getLockSettings().getString(secureSettingKey, null, userHandle);
@@ -1528,6 +1556,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void setString(String secureSettingKey, String value, int userHandle) {
         try {
             getLockSettings().setString(secureSettingKey, value, userHandle);
@@ -1541,6 +1570,7 @@
         setBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, enabled, userId);
     }
 
+    @UnsupportedAppUsage
     public boolean getPowerButtonInstantlyLocks(int userId) {
         return getBoolean(LOCKSCREEN_POWER_BUTTON_INSTANTLY_LOCKS, true, userId);
     }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 4b26990..2218267 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -78,7 +79,9 @@
 
     private boolean mDrawingProfilingStarted = false;
 
+    @UnsupportedAppUsage
     private final Paint mPaint = new Paint();
+    @UnsupportedAppUsage
     private final Paint mPathPaint = new Paint();
 
     /**
@@ -98,6 +101,7 @@
     private static final String TAG = "LockPatternView";
 
     private OnPatternListener mOnPatternListener;
+    @UnsupportedAppUsage
     private final ArrayList<Cell> mPattern = new ArrayList<Cell>(9);
 
     /**
@@ -119,16 +123,21 @@
     private long mAnimatingPeriodStart;
     private long[] mLineFadeStart = new long[9];
 
+    @UnsupportedAppUsage
     private DisplayMode mPatternDisplayMode = DisplayMode.Correct;
     private boolean mInputEnabled = true;
+    @UnsupportedAppUsage
     private boolean mInStealthMode = false;
     private boolean mEnableHapticFeedback = true;
+    @UnsupportedAppUsage
     private boolean mPatternInProgress = false;
     private boolean mFadePattern = true;
 
     private float mHitFactor = 0.6f;
 
+    @UnsupportedAppUsage
     private float mSquareWidth;
+    @UnsupportedAppUsage
     private float mSquareHeight;
 
     private final Path mCurrentPath = new Path();
@@ -153,7 +162,9 @@
      * Represents a cell in the 3 X 3 matrix of the unlock pattern view.
      */
     public static final class Cell {
+        @UnsupportedAppUsage
         final int row;
+        @UnsupportedAppUsage
         final int column;
 
         // keep # objects limited to 9
@@ -231,16 +242,19 @@
         /**
          * The pattern drawn is correct (i.e draw it in a friendly color)
          */
+        @UnsupportedAppUsage
         Correct,
 
         /**
          * Animate the pattern (for demo, and help).
          */
+        @UnsupportedAppUsage
         Animate,
 
         /**
          * The pattern is wrong (i.e draw a foreboding color)
          */
+        @UnsupportedAppUsage
         Wrong
     }
 
@@ -276,6 +290,7 @@
         this(context, null);
     }
 
+    @UnsupportedAppUsage
     public LockPatternView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
@@ -347,6 +362,7 @@
         a.recycle();
     }
 
+    @UnsupportedAppUsage
     public CellState[][] getCellStates() {
         return mCellStates;
     }
@@ -371,6 +387,7 @@
      *
      * @param inStealthMode Whether in stealth mode.
      */
+    @UnsupportedAppUsage
     public void setInStealthMode(boolean inStealthMode) {
         mInStealthMode = inStealthMode;
     }
@@ -389,6 +406,7 @@
      *
      * @param tactileFeedbackEnabled Whether tactile feedback is enabled
      */
+    @UnsupportedAppUsage
     public void setTactileFeedbackEnabled(boolean tactileFeedbackEnabled) {
         mEnableHapticFeedback = tactileFeedbackEnabled;
     }
@@ -397,6 +415,7 @@
      * Set the call back for pattern detection.
      * @param onPatternListener The call back.
      */
+    @UnsupportedAppUsage
     public void setOnPatternListener(
             OnPatternListener onPatternListener) {
         mOnPatternListener = onPatternListener;
@@ -425,6 +444,7 @@
      * in progress result to correct or wrong.
      * @param displayMode The display mode.
      */
+    @UnsupportedAppUsage
     public void setDisplayMode(DisplayMode displayMode) {
         mPatternDisplayMode = displayMode;
         if (displayMode == DisplayMode.Animate) {
@@ -564,6 +584,7 @@
         }
     }
 
+    @UnsupportedAppUsage
     private void notifyPatternDetected() {
         sendAccessEvent(R.string.lockscreen_access_pattern_detected);
         if (mOnPatternListener != null) {
@@ -581,6 +602,7 @@
     /**
      * Clear the pattern.
      */
+    @UnsupportedAppUsage
     public void clearPattern() {
         resetPattern();
     }
@@ -621,6 +643,7 @@
      * Disable input (for instance when displaying a message that will
      * timeout so user doesn't get view into messy state).
      */
+    @UnsupportedAppUsage
     public void disableInput() {
         mInputEnabled = false;
     }
@@ -628,6 +651,7 @@
     /**
      * Enable input.
      */
+    @UnsupportedAppUsage
     public void enableInput() {
         mInputEnabled = true;
     }
@@ -1308,6 +1332,7 @@
         /**
          * Constructor called from {@link LockPatternView#onSaveInstanceState()}
          */
+        @UnsupportedAppUsage
         private SavedState(Parcelable superState, String serializedPattern, int displayMode,
                 boolean inputEnabled, boolean inStealthMode, boolean tactileFeedbackEnabled) {
             super(superState);
@@ -1321,6 +1346,7 @@
         /**
          * Constructor called from {@link #CREATOR}
          */
+        @UnsupportedAppUsage
         private SavedState(Parcel in) {
             super(in);
             mSerializedPattern = in.readString();
diff --git a/core/java/com/android/internal/widget/PointerLocationView.java b/core/java/com/android/internal/widget/PointerLocationView.java
index 3205b5a..3881093 100644
--- a/core/java/com/android/internal/widget/PointerLocationView.java
+++ b/core/java/com/android/internal/widget/PointerLocationView.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -59,6 +60,7 @@
         private int mTraceCount;
         
         // True if the pointer is down.
+        @UnsupportedAppUsage
         private boolean mCurDown;
         
         // Most recent coordinates.
@@ -123,10 +125,14 @@
     private final FontMetricsInt mTextMetrics = new FontMetricsInt();
     private int mHeaderBottom;
     private int mHeaderPaddingTop = 0;
+    @UnsupportedAppUsage
     private boolean mCurDown;
+    @UnsupportedAppUsage
     private int mCurNumPointers;
+    @UnsupportedAppUsage
     private int mMaxNumPointers;
     private int mActivePointerId;
+    @UnsupportedAppUsage
     private final ArrayList<PointerState> mPointers = new ArrayList<PointerState>();
     private final PointerCoords mTempCoords = new PointerCoords();
 
@@ -139,6 +145,7 @@
 
     private final FasterStringBuilder mText = new FasterStringBuilder();
 
+    @UnsupportedAppUsage
     private boolean mPrintCoords = true;
     
     public PointerLocationView(Context c) {
diff --git a/core/java/com/android/internal/widget/PreferenceImageView.java b/core/java/com/android/internal/widget/PreferenceImageView.java
index 8730cda..02a0b8d 100644
--- a/core/java/com/android/internal/widget/PreferenceImageView.java
+++ b/core/java/com/android/internal/widget/PreferenceImageView.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.ImageView;
@@ -29,6 +30,7 @@
         this(context, null);
     }
 
+    @UnsupportedAppUsage
     public PreferenceImageView(Context context, AttributeSet attrs) {
         this(context, attrs, 0);
     }
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index 408a4e9..b66a7b4 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -20,6 +20,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.database.Observable;
@@ -4953,6 +4954,7 @@
          * constructed by {@link GapWorker} prefetch from being bound to a lower priority prefetch.
          */
         static class ScrapData {
+            @UnsupportedAppUsage
             ArrayList<ViewHolder> mScrapHeap = new ArrayList<>();
             int mMaxScrap = DEFAULT_MAX_SCRAP;
             long mCreateRunningAverageNs = 0;
diff --git a/core/java/com/android/internal/widget/ScrollBarUtils.java b/core/java/com/android/internal/widget/ScrollBarUtils.java
index 0ae9f74..982e315 100644
--- a/core/java/com/android/internal/widget/ScrollBarUtils.java
+++ b/core/java/com/android/internal/widget/ScrollBarUtils.java
@@ -16,8 +16,11 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
+
 public class ScrollBarUtils {
 
+    @UnsupportedAppUsage
     public static int getThumbLength(int size, int thickness, int extent, int range) {
         // Avoid the tiny thumb.
         final int minLength = thickness * 2;
diff --git a/core/java/com/android/internal/widget/SlidingTab.java b/core/java/com/android/internal/widget/SlidingTab.java
index 79adada..4b5d624 100644
--- a/core/java/com/android/internal/widget/SlidingTab.java
+++ b/core/java/com/android/internal/widget/SlidingTab.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -83,7 +84,9 @@
      */
     private final int mOrientation;
 
+    @UnsupportedAppUsage
     private final Slider mLeftSlider;
+    @UnsupportedAppUsage
     private final Slider mRightSlider;
     private Slider mCurrentSlider;
     private boolean mTracking;
@@ -95,6 +98,7 @@
     /**
      * Listener used to reset the view when the current animation completes.
      */
+    @UnsupportedAppUsage
     private final AnimationListener mAnimationDoneListener = new AnimationListener() {
         public void onAnimationStart(Animation animation) {
 
@@ -178,7 +182,9 @@
         private static final int STATE_PRESSED = 1;
         private static final int STATE_ACTIVE = 2;
 
+        @UnsupportedAppUsage
         private final ImageView tab;
+        @UnsupportedAppUsage
         private final TextView text;
         private final ImageView target;
         private int currentState = STATE_NORMAL;
@@ -708,6 +714,7 @@
         slider.startAnimation(trans1, trans2);
     }
 
+    @UnsupportedAppUsage
     private void onAnimationDone() {
         resetView();
         mAnimating = false;
@@ -722,6 +729,7 @@
         return mOrientation == HORIZONTAL;
     }
 
+    @UnsupportedAppUsage
     private void resetView() {
         mLeftSlider.reset(false);
         mRightSlider.reset(false);
@@ -763,6 +771,7 @@
      * @param barId the resource of the bar drawable (stateful)
      * @param tabId the resource of the
      */
+    @UnsupportedAppUsage
     public void setLeftTabResources(int iconId, int targetId, int barId, int tabId) {
         mLeftSlider.setIcon(iconId);
         mLeftSlider.setTarget(targetId);
@@ -776,6 +785,7 @@
      *
      * @param resId
      */
+    @UnsupportedAppUsage
     public void setLeftHintText(int resId) {
         if (isHorizontal()) {
             mLeftSlider.setHintText(resId);
@@ -793,6 +803,7 @@
      * @param barId the resource of the bar drawable (stateful)
      * @param tabId the resource of the
      */
+    @UnsupportedAppUsage
     public void setRightTabResources(int iconId, int targetId, int barId, int tabId) {
         mRightSlider.setIcon(iconId);
         mRightSlider.setTarget(targetId);
@@ -806,12 +817,14 @@
      *
      * @param resId
      */
+    @UnsupportedAppUsage
     public void setRightHintText(int resId) {
         if (isHorizontal()) {
             mRightSlider.setHintText(resId);
         }
     }
 
+    @UnsupportedAppUsage
     public void setHoldAfterTrigger(boolean holdLeft, boolean holdRight) {
         mHoldLeftOnTransition = holdLeft;
         mHoldRightOnTransition = holdRight;
@@ -838,6 +851,7 @@
      *
      * @param listener the OnDialTriggerListener to attach to this view
      */
+    @UnsupportedAppUsage
     public void setOnTriggerListener(OnTriggerListener listener) {
         mOnTriggerListener = listener;
     }
diff --git a/core/java/com/android/internal/widget/TextViewInputDisabler.java b/core/java/com/android/internal/widget/TextViewInputDisabler.java
index fb0b3b9..8d8f0fe 100644
--- a/core/java/com/android/internal/widget/TextViewInputDisabler.java
+++ b/core/java/com/android/internal/widget/TextViewInputDisabler.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.widget;
 
+import android.annotation.UnsupportedAppUsage;
 import android.text.InputFilter;
 import android.text.Spanned;
 import android.widget.TextView;
@@ -38,11 +39,13 @@
             }
     };
 
+    @UnsupportedAppUsage
     public TextViewInputDisabler(TextView textView) {
         mTextView = textView;
         mDefaultFilters = mTextView.getFilters();
     }
 
+    @UnsupportedAppUsage
     public void setInputEnabled(boolean enabled) {
         mTextView.setFilters(enabled ? mDefaultFilters : mNoInputFilters);
     }
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index f48b56d7..7d36b02 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -18,6 +18,7 @@
 
 import android.annotation.DrawableRes;
 import android.annotation.NonNull;
+import android.annotation.UnsupportedAppUsage;
 import android.content.Context;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
@@ -244,6 +245,7 @@
          * @param positionOffset Value from [0, 1) indicating the offset from the page at position.
          * @param positionOffsetPixels Value in pixels indicating the offset from position.
          */
+        @UnsupportedAppUsage
         public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels);
 
         /**
@@ -252,6 +254,7 @@
          *
          * @param position Position index of the new selected page.
          */
+        @UnsupportedAppUsage
         public void onPageSelected(int position);
 
         /**
@@ -264,6 +267,7 @@
          * @see com.android.internal.widget.ViewPager#SCROLL_STATE_DRAGGING
          * @see com.android.internal.widget.ViewPager#SCROLL_STATE_SETTLING
          */
+        @UnsupportedAppUsage
         public void onPageScrollStateChanged(int state);
     }
 
@@ -484,6 +488,7 @@
         setCurrentItemInternal(item, smoothScroll, false);
     }
 
+    @UnsupportedAppUsage
     public int getCurrentItem() {
         return mCurItem;
     }
diff --git a/core/java/com/android/server/ResettableTimeout.java b/core/java/com/android/server/ResettableTimeout.java
index ac5b160..64083f7 100644
--- a/core/java/com/android/server/ResettableTimeout.java
+++ b/core/java/com/android/server/ResettableTimeout.java
@@ -18,6 +18,7 @@
 
 import android.os.SystemClock;
 
+import android.annotation.UnsupportedAppUsage;
 import android.os.ConditionVariable;
 
 /**
@@ -120,9 +121,11 @@
         }
     }
 
+    @UnsupportedAppUsage
     private ConditionVariable mLock = new ConditionVariable();
 
     // turn it off at this time.
+    @UnsupportedAppUsage
     private volatile long mOffAt;
     private volatile boolean mOffCalled;
 
diff --git a/core/java/com/android/server/net/BaseNetworkObserver.java b/core/java/com/android/server/net/BaseNetworkObserver.java
index 3d9fb5c..a0740ee 100644
--- a/core/java/com/android/server/net/BaseNetworkObserver.java
+++ b/core/java/com/android/server/net/BaseNetworkObserver.java
@@ -16,6 +16,7 @@
 
 package com.android.server.net;
 
+import android.annotation.UnsupportedAppUsage;
 import android.net.INetworkManagementEventObserver;
 import android.net.LinkAddress;
 import android.net.RouteInfo;
diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java
index 5b421d9..647fb5b 100644
--- a/core/java/com/android/server/net/NetlinkTracker.java
+++ b/core/java/com/android/server/net/NetlinkTracker.java
@@ -16,6 +16,7 @@
 
 package com.android.server.net;
 
+import android.annotation.UnsupportedAppUsage;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.RouteInfo;
@@ -79,6 +80,7 @@
 
     private static final boolean DBG = false;
 
+    @UnsupportedAppUsage
     public NetlinkTracker(String iface, Callback callback) {
         TAG = "NetlinkTracker/" + iface;
         mInterfaceName = iface;
@@ -187,10 +189,12 @@
     /**
      * Returns a copy of this object's LinkProperties.
      */
+    @UnsupportedAppUsage
     public synchronized LinkProperties getLinkProperties() {
         return new LinkProperties(mLinkProperties);
     }
 
+    @UnsupportedAppUsage
     public synchronized void clearLinkProperties() {
         // Clear the repository before clearing mLinkProperties. That way, if a clear() happens
         // while interfaceDnsServerInfo() is being called, we'll end up with no DNS servers in
diff --git a/core/java/com/google/android/collect/Lists.java b/core/java/com/google/android/collect/Lists.java
index 3ea873b..8f6594a 100644
--- a/core/java/com/google/android/collect/Lists.java
+++ b/core/java/com/google/android/collect/Lists.java
@@ -57,6 +57,7 @@
      * @param elements the elements that the list should contain, in order
      * @return a newly-created {@code ArrayList} containing those elements
      */
+    @UnsupportedAppUsage
     public static <E> ArrayList<E> newArrayList(E... elements) {
         int capacity = (elements.length * 110) / 100 + 5;
         ArrayList<E> list = new ArrayList<E>(capacity);
diff --git a/core/java/com/google/android/collect/Sets.java b/core/java/com/google/android/collect/Sets.java
index dd3cab1..09b5e51 100644
--- a/core/java/com/google/android/collect/Sets.java
+++ b/core/java/com/google/android/collect/Sets.java
@@ -16,6 +16,7 @@
 
 package com.google.android.collect;
 
+import android.annotation.UnsupportedAppUsage;
 import android.util.ArraySet;
 
 import java.util.Collections;
@@ -42,6 +43,7 @@
      *
      * @return a newly-created, initially-empty {@code HashSet}
      */
+    @UnsupportedAppUsage
     public static <K> HashSet<K> newHashSet() {
         return new HashSet<K>();
     }
@@ -63,6 +65,7 @@
      * @return a newly-created {@code HashSet} containing those elements (minus
      *     duplicates)
      */
+    @UnsupportedAppUsage
     public static <E> HashSet<E> newHashSet(E... elements) {
         int capacity = elements.length * 4 / 3 + 1;
         HashSet<E> set = new HashSet<E>(capacity);
@@ -75,6 +78,7 @@
      *
      * @return a newly-created, initially-empty {@code SortedSet}.
      */
+    @UnsupportedAppUsage
     public static <E> SortedSet<E> newSortedSet() {
         return new TreeSet<E>();
     }
@@ -95,6 +99,7 @@
     /**
      * Creates a {@code ArraySet} instance.
      */
+    @UnsupportedAppUsage
     public static <E> ArraySet<E> newArraySet() {
         return new ArraySet<E>();
     }
@@ -102,6 +107,7 @@
     /**
      * Creates a {@code ArraySet} instance containing the given elements.
      */
+    @UnsupportedAppUsage
     public static <E> ArraySet<E> newArraySet(E... elements) {
         int capacity = elements.length * 4 / 3 + 1;
         ArraySet<E> set = new ArraySet<E>(capacity);
diff --git a/core/java/com/google/android/util/AbstractMessageParser.java b/core/java/com/google/android/util/AbstractMessageParser.java
index 1871682..9d12f82 100644
--- a/core/java/com/google/android/util/AbstractMessageParser.java
+++ b/core/java/com/google/android/util/AbstractMessageParser.java
@@ -16,6 +16,7 @@
 
 package com.google.android.util;
 
+import android.annotation.UnsupportedAppUsage;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -654,15 +655,25 @@
   public static abstract class Token {
     public enum Type {
 
+      @UnsupportedAppUsage
       HTML ("html"),
+      @UnsupportedAppUsage
       FORMAT ("format"),  // subtype of HTML
+      @UnsupportedAppUsage
       LINK ("l"),
+      @UnsupportedAppUsage
       SMILEY ("e"),
+      @UnsupportedAppUsage
       ACRONYM ("a"),
+      @UnsupportedAppUsage
       MUSIC ("m"),
+      @UnsupportedAppUsage
       GOOGLE_VIDEO ("v"),
+      @UnsupportedAppUsage
       YOUTUBE_VIDEO ("yt"),
+      @UnsupportedAppUsage
       PHOTO ("p"),
+      @UnsupportedAppUsage
       FLICKR ("f");
 
       //stringreps for HTML and FORMAT don't really matter
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index cb8ece7..8bfa038 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4426,6 +4426,13 @@
     <permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
         android:protectionLevel="signature" />
 
+    <!-- Must be required by an {@link android.service.watchdog.ExplicitHealthCheckService} to
+         ensure that only the system can bind to it.
+         @hide This is not a third-party API (intended for OEMs and system apps).
+    -->
+    <permission android:name="android.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE"
+        android:protectionLevel="signature|privileged" />
+
     <!-- @hide Permission that allows configuring appops.
      <p>Not for use by third-party applications. -->
     <permission android:name="android.permission.MANAGE_APPOPS"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9db75f2..dc0ec03 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3760,9 +3760,6 @@
     <!-- Package name for ManagedProvisioning which is responsible for provisioning work profiles. -->
     <string name="config_managed_provisioning_package" translatable="false">com.android.managedprovisioning</string>
 
-    <!-- Whether or not swipe up gesture is enabled by default -->
-    <bool name="config_swipe_up_gesture_default">false</bool>
-
     <!-- Whether or not swipe up gesture's opt-in setting is available on this device -->
     <bool name="config_swipe_up_gesture_setting_available">false</bool>
 
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 79bf738..bb47370 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4834,11 +4834,14 @@
     <!-- Notification shown when device owner silently deletes a package [CHAR LIMIT=NONE] -->
     <string name="package_deleted_device_owner">Deleted by your admin</string>
 
+    <!-- [CHAR LIMIT=25] String for confirmation button to enable a feature gated by the battery saver warning-->
+    <string name="confirm_battery_saver">Confirm</string>
+
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, with a "learn more" link. -->
-    <string name="battery_saver_description_with_learn_more">To extend your battery life, Battery Saver turns off some device features and restricts apps. <annotation id="url">Learn More</annotation></string>
+    <string name="battery_saver_description_with_learn_more">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life. <annotation id="url">Learn More</annotation></string>
 
     <!-- [CHAR_LIMIT=NONE] Battery saver: Feature description, without a "learn more" link. -->
-    <string name="battery_saver_description">To extend your battery life, Battery Saver turns off some device features and restricts apps.</string>
+    <string name="battery_saver_description">Battery Saver turns off or restricts background activity, some visual effects \u0026 other high-power features to extend battery life.</string>
 
     <!-- [CHAR_LIMIT=NONE] Data saver: Feature description -->
     <string name="data_saver_description">To help reduce data usage, Data Saver prevents some apps from sending or receiving data in the background. An app you’re currently using can access data, but may do so less frequently. This may mean, for example, that images don’t display until you tap them.</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7ec5b5b..ae54a6a 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3515,7 +3515,6 @@
   <java-symbol type="string" name="shortcut_restore_signature_mismatch" />
   <java-symbol type="string" name="shortcut_restore_unknown_issue" />
 
-  <java-symbol type="bool" name="config_swipe_up_gesture_default" />
   <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" />
 
   <!-- From media projection -->
diff --git a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
index fe2d41e..ceab407 100644
--- a/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
+++ b/libs/hwui/pipeline/skia/VkFunctorDrawable.cpp
@@ -65,7 +65,6 @@
     VkFunctorDrawParams params{
       .width = mImageInfo.width(),
       .height = mImageInfo.height(),
-      .is_layer = false,  // TODO(boliu): Populate is_layer.
       .color_space_ptr = mImageInfo.colorSpace(),
       .clip_left = mClip.fLeft,
       .clip_top = mClip.fTop,
diff --git a/libs/hwui/private/hwui/DrawVkInfo.h b/libs/hwui/private/hwui/DrawVkInfo.h
index fb55f5c..4ae0f5a 100644
--- a/libs/hwui/private/hwui/DrawVkInfo.h
+++ b/libs/hwui/private/hwui/DrawVkInfo.h
@@ -42,9 +42,6 @@
   int width;
   int height;
 
-  // Input: is the render target a FBO
-  bool is_layer;
-
   // Input: current transform matrix
   float transform[16];
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/media/java/android/media/IMediaRoute2Callback.aidl
similarity index 62%
rename from packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
rename to media/java/android/media/IMediaRoute2Callback.aidl
index c16cf92..f03c8ab 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
+++ b/media/java/android/media/IMediaRoute2Callback.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -11,15 +11,14 @@
  * 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
+ * limitations under the License.
  */
 
-package com.android.systemui.shared.system;
+package android.media;
 
-import android.provider.Settings;
-
-public class SettingsCompat {
-
-    public static final String SWIPE_UP_SETTING_NAME
-            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
+/**
+ * @hide
+ */
+oneway interface IMediaRoute2Callback {
+    void onRouteSelected(int uid, String routeId);
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/media/java/android/media/IMediaRoute2Provider.aidl
similarity index 62%
copy from packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
copy to media/java/android/media/IMediaRoute2Provider.aidl
index c16cf92..b97dcc5 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -11,15 +11,17 @@
  * 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
+ * limitations under the License.
  */
 
-package com.android.systemui.shared.system;
+package android.media;
 
-import android.provider.Settings;
+import android.media.IMediaRoute2Callback;
 
-public class SettingsCompat {
-
-    public static final String SWIPE_UP_SETTING_NAME
-            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
+/**
+ * {@hide}
+ */
+oneway interface IMediaRoute2Provider {
+    void setCallback(IMediaRoute2Callback callback);
+    void selectRoute(int uid, String id);
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/media/java/android/media/IMediaRouter2ManagerClient.aidl
similarity index 62%
copy from packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
copy to media/java/android/media/IMediaRouter2ManagerClient.aidl
index c16cf92..234551b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
+++ b/media/java/android/media/IMediaRouter2ManagerClient.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright 2019 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.
@@ -11,15 +11,15 @@
  * 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
+ * limitations under the License.
  */
 
-package com.android.systemui.shared.system;
+package android.media;
 
-import android.provider.Settings;
-
-public class SettingsCompat {
-
-    public static final String SWIPE_UP_SETTING_NAME
-            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
+/**
+ * {@hide}
+ */
+oneway interface IMediaRouter2ManagerClient {
+    void onRouteSelected(int uid, String routeId);
+    void onControlCategoriesChanged(int uid, in List<String> categories);
 }
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 3308fc9..59f1d0d 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -17,6 +17,7 @@
 package android.media;
 
 import android.media.IMediaRouterClient;
+import android.media.IMediaRouter2ManagerClient;
 import android.media.MediaRouterClientState;
 
 /**
@@ -29,8 +30,15 @@
     MediaRouterClientState getState(IMediaRouterClient client);
     boolean isPlaybackActive(IMediaRouterClient client);
 
+    void setControlCategories(IMediaRouterClient client, in List<String> categories);
     void setDiscoveryRequest(IMediaRouterClient client, int routeTypes, boolean activeScan);
     void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
     void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
     void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
+
+    void registerManagerAsUser(IMediaRouter2ManagerClient callback,
+            String packageName, int userId);
+    void unregisterManager(IMediaRouter2ManagerClient callback);
+    void setRemoteRoute(IMediaRouter2ManagerClient callback,
+            int uid, String routeId, boolean explicit);
 }
diff --git a/media/java/android/media/MediaRoute2ProviderService.java b/media/java/android/media/MediaRoute2ProviderService.java
new file mode 100644
index 0000000..04ddc30
--- /dev/null
+++ b/media/java/android/media/MediaRoute2ProviderService.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class MediaRoute2ProviderService extends Service {
+    private static final String TAG = "MediaRouteProviderSrv";
+
+    public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
+
+    private final Handler mHandler;
+    private ProviderStub mStub;
+    private IMediaRoute2Callback mCallback;
+
+    public MediaRoute2ProviderService() {
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            if (mStub == null) {
+                mStub = new ProviderStub();
+            }
+            return mStub;
+        }
+        return null;
+    }
+
+    /**
+     * Called when selectRoute is called on a route of the provider.
+     *
+     * @param uid The target application uid
+     * @param routeId The id of the target route
+     */
+    public abstract void onSelect(int uid, String routeId);
+
+    /**
+     * Updates provider info from selected route and appliation.
+     *
+     * TODO: When provider descriptor is defined, this should update the descriptor correctly.
+     *
+     * @param uid
+     * @param routeId
+     */
+    public void updateProvider(int uid, String routeId) {
+        if (mCallback != null) {
+            try {
+                //TODO: After publishState() is fully implemented, delete this.
+                mCallback.onRouteSelected(uid, routeId);
+            } catch (RemoteException ex) {
+                Log.d(TAG, "Failed to update provider");
+            }
+        }
+        publishState();
+    }
+
+    void setCallback(IMediaRoute2Callback callback) {
+        mCallback = callback;
+        publishState();
+    }
+
+    void publishState() {
+        //TODO: Send provider descriptor to the MediaRouterService
+    }
+
+    final class ProviderStub extends IMediaRoute2Provider.Stub {
+        ProviderStub() { }
+
+        @Override
+        public void setCallback(IMediaRoute2Callback callback) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
+                    MediaRoute2ProviderService.this, callback));
+        }
+
+        @Override
+        public void selectRoute(int uid, String id) {
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelect,
+                    MediaRoute2ProviderService.this, uid, id));
+        }
+    }
+}
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index 3444e92..5a89d8c 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -347,6 +347,17 @@
             return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
         }
 
+        void setControlCategories(List<String> categories) {
+            if (mClient != null) {
+                try {
+                    mMediaRouterService.setControlCategories(mClient,
+                            categories);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to set control categories.", ex);
+                }
+            }
+        }
+
         private void updatePresentationDisplays(int changedDisplayId) {
             final int count = mRoutes.size();
             for (int i = 0; i < count; i++) {
@@ -919,6 +930,25 @@
         return -1;
     }
 
+    //TODO: Remove @hide when it is ready.
+    //TODO: Provide pre-defined categories for app developers.
+    /**
+     * Sets control categories of the client application.
+     * Control categories can be used to filter out media routes
+     * that don't correspond with the client application.
+     * The only routes that match any of the categories will be shown on other applications.
+     *
+     * @hide
+     * @param categories Categories to set
+     */
+    public void setControlCategories(@NonNull List<String> categories) {
+        if (categories == null) {
+            throw new IllegalArgumentException("Categories must not be null");
+        }
+        sStatic.setControlCategories(categories);
+    }
+
+
     /**
      * Select the specified route to use for output of the given media types.
      * <p class="note">
diff --git a/media/java/android/media/MediaRouter2Manager.java b/media/java/android/media/MediaRouter2Manager.java
new file mode 100644
index 0000000..ac5958e
--- /dev/null
+++ b/media/java/android/media/MediaRouter2Manager.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * @hide
+ */
+public class MediaRouter2Manager {
+    private static final String TAG = "MediaRouter2Manager";
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static MediaRouter2Manager sInstance;
+
+    final String mPackageName;
+
+    private Context mContext;
+    private Client mClient;
+    private final IMediaRouterService mMediaRouterService;
+    final Handler mHandler;
+
+    @GuardedBy("sLock")
+    final ArrayList<CallbackRecord> mCallbacks = new ArrayList<>();
+
+    /**
+     * Gets an instance of media router manager that controls media route of other apps.
+     * @param context
+     * @return
+     */
+    public static MediaRouter2Manager getInstance(@NonNull Context context) {
+        if (context == null) {
+            throw new IllegalArgumentException("context must not be null");
+        }
+        synchronized (sLock) {
+            if (sInstance == null) {
+                sInstance = new MediaRouter2Manager(context);
+            }
+            return sInstance;
+        }
+    }
+
+    private MediaRouter2Manager(Context context) {
+        mContext = context.getApplicationContext();
+        mMediaRouterService = IMediaRouterService.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        mPackageName = mContext.getPackageName();
+        mHandler = new Handler(context.getMainLooper());
+    }
+
+    /**
+     * Registers a callback to listen route info.
+     *
+     * @param executor The executor that runs the callback.
+     * @param callback The callback to add.
+     */
+    public void addCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Callback callback) {
+
+        if (executor == null) {
+            throw new IllegalArgumentException("executor must not be null");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+
+        synchronized (sLock) {
+            final int index = findCallbackRecord(callback);
+            if (index >= 0) {
+                Log.w(TAG, "Ignore adding the same callback twice.");
+                return;
+            }
+            if (mCallbacks.size() == 0) {
+                Client client = new Client();
+                try {
+                    mMediaRouterService.registerManagerAsUser(client, mPackageName,
+                            UserHandle.myUserId());
+                    mClient = client;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to register media router manager.", ex);
+                }
+            }
+            mCallbacks.add(new CallbackRecord(executor, callback));
+        }
+    }
+
+    /**
+     * Removes the specified callback.
+     *
+     * @param callback The callback to remove.
+     */
+    public void removeCallback(@NonNull Callback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+
+        synchronized (sLock) {
+            final int index = findCallbackRecord(callback);
+            if (index < 0) {
+                Log.w(TAG, "Ignore removing unknown callback. " + callback);
+                return;
+            }
+            mCallbacks.remove(index);
+            if (mCallbacks.size() == 0 && mClient != null) {
+                try {
+                    mMediaRouterService.unregisterManager(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to unregister media router manager", ex);
+                }
+                mClient = null;
+            }
+        }
+    }
+
+    private int findCallbackRecord(Callback callback) {
+        final int count = mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            if (mCallbacks.get(i).mCallback == callback) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Selects media route for the specified application uid.
+     *
+     * @param uid The uid of the application that should change it's media route.
+     * @param routeId The id of the route to select
+     */
+    public void selectRoute(int uid, String routeId) {
+        if (mClient != null) {
+            try {
+                mMediaRouterService.setRemoteRoute(mClient, uid, routeId, /* explicit= */true);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to select media route", ex);
+            }
+        }
+    }
+
+    /**
+     * Unselects media route for the specified application uid.
+     *
+     * @param uid The uid of the application that should stop routing.
+     */
+    public void unselectRoute(int uid) {
+        if (mClient != null) {
+            try {
+                mMediaRouterService.setRemoteRoute(mClient, uid, null, /* explicit= */ true);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to select media route", ex);
+            }
+        }
+    }
+
+    void notifyRouteSelected(int uid, String routeId) {
+        for (CallbackRecord record : mCallbacks) {
+            record.mExecutor.execute(() -> record.mCallback.onRouteSelected(uid, routeId));
+        }
+    }
+
+    void notifyControlCategoriesChanged(int uid, List<String> categories) {
+        for (CallbackRecord record : mCallbacks) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onControlCategoriesChanged(uid, categories));
+        }
+    }
+
+    /**
+     * Interface for receiving events about media routing changes.
+     */
+    public abstract static class Callback {
+        /**
+         * Called when a route is selected for some application uid.
+         * @param uid
+         * @param routeId
+         */
+        public abstract void onRouteSelected(int uid, String routeId);
+
+        /**
+         * Called when the control categories of an application is changed.
+         * @param uid the uid of the app that changed control categories
+         * @param categories the changed categories
+         */
+        public abstract void onControlCategoriesChanged(int uid, List<String> categories);
+    }
+
+    final class CallbackRecord {
+        public final Executor mExecutor;
+        public final Callback mCallback;
+
+        CallbackRecord(Executor executor, Callback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+    }
+
+    class Client extends IMediaRouter2ManagerClient.Stub {
+        @Override
+        public void onRouteSelected(int uid, String routeId) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyRouteSelected,
+                    MediaRouter2Manager.this, uid, routeId));
+        }
+
+        @Override
+        public void onControlCategoriesChanged(int uid, List<String> categories) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifyControlCategoriesChanged,
+                    MediaRouter2Manager.this, uid, categories));
+        }
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
index 2492109..ed2eebf 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/helpers/CameraTestResultPrinter.java
@@ -40,14 +40,14 @@
     private Instrumentation mInst = null;
     private boolean mWriteToFile = true;
 
-
     public CameraTestResultPrinter(Instrumentation instrumentation, boolean writeToFile) {
         mInst = instrumentation;
         mWriteToFile = writeToFile;
 
         // Create a log directory if not exists.
         File baseDir = new File(RESULT_DIR);
-        if (!baseDir.exists() && !baseDir.mkdirs()) {
+        baseDir.mkdirs();
+        if (!baseDir.isDirectory()) {
             throw new IllegalStateException("Couldn't create directory for logs: " + baseDir);
         }
         Log.v(TAG, String.format("Saving test results under: %s", baseDir.getAbsolutePath()));
diff --git a/media/tests/MediaRouteProvider/Android.bp b/media/tests/MediaRouteProvider/Android.bp
new file mode 100644
index 0000000..da42824
--- /dev/null
+++ b/media/tests/MediaRouteProvider/Android.bp
@@ -0,0 +1,18 @@
+android_test {
+    name: "mediarouteprovider",
+
+    srcs: ["**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "mockito-target-minus-junit4",
+    ],
+
+    platform_apis: true,
+    certificate: "platform",
+}
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/AndroidManifest.xml b/media/tests/MediaRouteProvider/AndroidManifest.xml
new file mode 100644
index 0000000..489a621
--- /dev/null
+++ b/media/tests/MediaRouteProvider/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.mediarouteprovider.example">
+
+    <application android:label="@string/app_name">
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".SampleMediaRoute2ProviderService"
+            android:label="@string/app_name"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.media.MediaRoute2ProviderService" />
+            </intent-filter>
+       </service>
+    </application>
+</manifest>
diff --git a/media/tests/MediaRouteProvider/res/values/strings.xml b/media/tests/MediaRouteProvider/res/values/strings.xml
new file mode 100644
index 0000000..bb97064
--- /dev/null
+++ b/media/tests/MediaRouteProvider/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- name of the app [CHAR LIMIT=25]-->
+    <string name="app_name">SampleMediaRouteProvider</string>
+</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
new file mode 100644
index 0000000..22fbd85
--- /dev/null
+++ b/media/tests/MediaRouteProvider/src/com/android/mediarouteprovider/example/SampleMediaRoute2ProviderService.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 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.mediarouteprovider.example;
+
+import android.content.Intent;
+import android.media.MediaRoute2ProviderService;
+import android.os.IBinder;
+
+public class SampleMediaRoute2ProviderService extends MediaRoute2ProviderService {
+    @Override
+    public IBinder onBind(Intent intent) {
+        return super.onBind(intent);
+    }
+
+    @Override
+    public void onSelect(int uid, String routeId) {
+        updateProvider(uid, routeId);
+    }
+}
diff --git a/media/tests/MediaRouter/Android.bp b/media/tests/MediaRouter/Android.bp
new file mode 100644
index 0000000..611b25a
--- /dev/null
+++ b/media/tests/MediaRouter/Android.bp
@@ -0,0 +1,18 @@
+android_test {
+    name: "mediaroutertest",
+
+    srcs: ["**/*.java"],
+
+    libs: [
+        "android.test.runner",
+        "android.test.base",
+    ],
+
+    static_libs: [
+        "android-support-test",
+        "mockito-target-minus-junit4",
+    ],
+
+    platform_apis: true,
+    certificate: "platform",
+}
\ No newline at end of file
diff --git a/media/tests/MediaRouter/AndroidManifest.xml b/media/tests/MediaRouter/AndroidManifest.xml
new file mode 100644
index 0000000..a34a264
--- /dev/null
+++ b/media/tests/MediaRouter/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2019 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.mediaroutertest">
+
+    <uses-permission android:name="android.permission.CONTROL_MEDIA_ROUTE" />
+
+    <application android:label="@string/app_name">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.mediaroutertest"
+                     android:label="MediaRouter Tests"/>
+</manifest>
diff --git a/media/tests/MediaRouter/AndroidTest.xml b/media/tests/MediaRouter/AndroidTest.xml
new file mode 100644
index 0000000..1301062
--- /dev/null
+++ b/media/tests/MediaRouter/AndroidTest.xml
@@ -0,0 +1,16 @@
+<configuration description="Runs sample instrumentation test.">
+    <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="test-file-name" value="mediaroutertest.apk"/>
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
+    <option name="test-suite-tag" value="apct"/>
+    <option name="test-tag" value="MediaRouterTest"/>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+        <option name="package" value="com.android.mediaroutertest"/>
+        <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/media/tests/MediaRouter/res/values/strings.xml b/media/tests/MediaRouter/res/values/strings.xml
new file mode 100644
index 0000000..0737020
--- /dev/null
+++ b/media/tests/MediaRouter/res/values/strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <!-- name of the app [CHAR LIMIT=25]-->
+    <string name="app_name">mediaRouterTest</string>
+</resources>
\ No newline at end of file
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
new file mode 100644
index 0000000..a4bde65
--- /dev/null
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2019 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.mediaroutertest;
+
+import static org.mockito.Mockito.after;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.media.MediaRouter;
+import android.media.MediaRouter2Manager;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class MediaRouterManagerTest {
+    private static final String TAG = "MediaRouterManagerTest";
+
+    private static final int TARGET_UID = 109992;
+    private static final String ROUTE_1 = "MediaRoute1";
+
+    private static final int AWAIT_MS = 1000;
+    private static final int TIMEOUT_MS = 1000;
+
+    private Context mContext;
+    private MediaRouter2Manager mManager;
+    private MediaRouter mRouter;
+    private Executor mExecutor;
+
+    private static final List<String> TEST_CONTROL_CATEGORIES = new ArrayList();
+    private static final String CONTROL_CATEGORY_1 = "android.media.mediarouter.MEDIA1";
+    private static final String CONTROL_CATEGORY_2 = "android.media.mediarouter.MEDIA2";
+    static {
+        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_1);
+        TEST_CONTROL_CATEGORIES.add(CONTROL_CATEGORY_2);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mManager = MediaRouter2Manager.getInstance(mContext);
+        mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+        mExecutor = new ThreadPoolExecutor(
+            1, 20, 3, TimeUnit.SECONDS,
+            new SynchronousQueue<Runnable>());
+    }
+
+    @Test
+    public void transferTest() throws Exception {
+        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+
+        mManager.addCallback(mExecutor, mockCallback);
+
+        verify(mockCallback, after(AWAIT_MS).never())
+            .onRouteSelected(eq(TARGET_UID), any(String.class));
+
+        mManager.selectRoute(TARGET_UID, ROUTE_1);
+        verify(mockCallback, timeout(TIMEOUT_MS)).onRouteSelected(TARGET_UID, ROUTE_1);
+
+        mManager.removeCallback(mockCallback);
+    }
+
+    @Test
+    public void controlCategoryTest() throws Exception {
+        final int uid = android.os.Process.myUid();
+
+        MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+        mManager.addCallback(mExecutor, mockCallback);
+
+        verify(mockCallback, after(AWAIT_MS).never()).onControlCategoriesChanged(eq(uid),
+                any(List.class));
+
+        mRouter.setControlCategories(TEST_CONTROL_CATEGORIES);
+        verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
+            .onControlCategoriesChanged(uid, TEST_CONTROL_CATEGORIES);
+
+        mManager.removeCallback(mockCallback);
+    }
+
+}
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 5b3e496..42cad43 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -44,23 +44,8 @@
   int width;
   int height;
 
-  // Input: is the View rendered into an independent layer.
-  // If false, the surface is likely to hold to the full screen contents, with
-  // the scissor box set by the caller to the actual View location and size.
-  // Also the transformation matrix will contain at least a translation to the
-  // position of the View to render, plus any other transformations required as
-  // part of any ongoing View animation. View translucency (alpha) is ignored,
-  // although the framework will set is_layer to true for non-opaque cases.
-  // Can be requested via the View.setLayerType(View.LAYER_TYPE_NONE, ...)
-  // Android API method.
-  //
-  // If true, the surface is dedicated to the View and should have its size.
-  // The viewport and scissor box are set by the caller to the whole surface.
-  // Animation transformations are handled by the caller and not reflected in
-  // the provided transformation matrix. Translucency works normally.
-  // Can be requested via the View.setLayerType(View.LAYER_TYPE_HARDWARE, ...)
-  // Android API method.
-  bool is_layer;
+  // Used to be is_layer.
+  bool deprecated_0;
 
   // Input: current transformation matrix in surface pixels.
   // Uses the column-based OpenGL matrix format.
@@ -102,8 +87,7 @@
   int width;
   int height;
 
-  // Input: is the render target a FBO
-  bool is_layer;
+  bool deprecated_0;
 
   // Input: current transform matrix
   float transform[16];
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
index e43a60c..7cce61b 100644
--- a/native/webview/plat_support/draw_functor.cpp
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -65,7 +65,7 @@
       .clip_bottom = draw_gl_params.clipBottom,
       .width = draw_gl_params.width,
       .height = draw_gl_params.height,
-      .is_layer = draw_gl_params.isLayer,
+      .deprecated_0 = false,
       .transfer_function_g = gabcdef[0],
       .transfer_function_a = gabcdef[1],
       .transfer_function_b = gabcdef[2],
@@ -126,7 +126,7 @@
       .version = kAwDrawFnVersion,
       .width = draw_vk_params.width,
       .height = draw_vk_params.height,
-      .is_layer = draw_vk_params.is_layer,
+      .deprecated_0 = false,
       .secondary_command_buffer = draw_vk_params.secondary_command_buffer,
       .color_attachment_index = draw_vk_params.color_attachment_index,
       .compatible_render_pass = draw_vk_params.compatible_render_pass,
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
index 459cd40..ee29bc5 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantTest.java
@@ -182,7 +182,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C1));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -195,7 +195,7 @@
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
         ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
+        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
         assertEquals(sbn.getKey(), captor.getValue().getKey());
         assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
                 captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
@@ -210,7 +210,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C3));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -230,7 +230,7 @@
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
         ArgumentCaptor<Adjustment> captor = ArgumentCaptor.forClass(Adjustment.class);
-        verify(mNoMan, times(1)).applyAdjustmentFromAssistant(any(), captor.capture());
+        verify(mNoMan, times(1)).applyEnqueuedAdjustmentFromAssistant(any(), captor.capture());
         assertEquals(sbn.getKey(), captor.getValue().getKey());
         assertEquals(Ranking.USER_SENTIMENT_NEGATIVE,
                 captor.getValue().getSignals().getInt(Adjustment.KEY_USER_SENTIMENT));
@@ -253,7 +253,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", "group");
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -272,7 +272,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -291,7 +291,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -310,7 +310,7 @@
         sbn = generateSbn(PKG1, UID1, P1C1, "new one!", null);
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -322,7 +322,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P2C1));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
@@ -334,7 +334,7 @@
         mAssistant.setFakeRanking(generateRanking(sbn, P1C2));
         mAssistant.onNotificationPosted(sbn, mock(RankingMap.class));
 
-        verify(mNoMan, never()).applyAdjustmentFromAssistant(any(), any());
+        verify(mNoMan, never()).applyEnqueuedAdjustmentFromAssistant(any(), any());
     }
 
     @Test
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index de7202c..e374db3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -2410,12 +2410,6 @@
                 Settings.Secure.WAKE_GESTURE_ENABLED,
                 SecureSettingsProto.WAKE_GESTURE_ENABLED);
 
-        final long launcherToken = p.start(SecureSettingsProto.LAUNCHER);
-        dumpSetting(s, p,
-                Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED,
-                SecureSettingsProto.Launcher.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
-        p.end(launcherToken);
-
         final long zenToken = p.start(SecureSettingsProto.ZEN);
         dumpSetting(s, p,
                 Settings.Secure.ZEN_DURATION,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 7337cdb..4b342b3 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1074,8 +1074,7 @@
             Slog.v(LOG_TAG, "getConfigSetting(" + name + ")");
         }
 
-        // TODO(b/117663715): Ensure the caller can access the setting.
-        // enforceReadPermission(READ_DEVICE_CONFIG);
+        DeviceConfig.enforceReadPermission(getContext(), /*namespace=*/name.split("/")[0]);
 
         // Get the value.
         synchronized (mLock) {
@@ -4330,7 +4329,7 @@
                     // Migrate the swipe up setting only if it is set
                     final SettingsState secureSettings = getSecureSettingsLocked(userId);
                     final Setting swipeUpSetting = secureSettings.getSettingLocked(
-                            Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED);
+                            "swipe_up_to_switch_apps_enabled");
                     if (swipeUpSetting != null && !swipeUpSetting.isNull()) {
                         navBarMode = swipeUpSetting.getValue().equals("1")
                                 ? NAV_BAR_MODE_2BUTTON
diff --git a/packages/SystemUI/OWNERS b/packages/SystemUI/OWNERS
index e7e2c1a..c071b8b 100644
--- a/packages/SystemUI/OWNERS
+++ b/packages/SystemUI/OWNERS
@@ -21,6 +21,7 @@
 kchyn@google.com
 kozynski@google.com
 kprevas@google.com
+lynhan@google.com
 madym@google.com
 mankoff@google.com
 nbenbernou@google.com
diff --git a/packages/SystemUI/res/layout-land/volume_dialog.xml b/packages/SystemUI/res/layout-land/volume_dialog.xml
index c1e74ef..9acfbaf 100644
--- a/packages/SystemUI/res/layout-land/volume_dialog.xml
+++ b/packages/SystemUI/res/layout-land/volume_dialog.xml
@@ -15,6 +15,7 @@
   -->
 <FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:sysui="http://schemas.android.com/apk/res-auto"
     android:id="@+id/volume_dialog_container"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
@@ -116,16 +117,17 @@
             android:clipToPadding="false"
             android:translationZ="@dimen/volume_dialog_elevation"
             android:background="@drawable/rounded_bg_full">
-            <com.android.keyguard.AlphaOptimizedImageButton
+            <com.android.systemui.volume.CaptionsToggleImageButton
                 android:id="@+id/odi_captions_icon"
                 android:src="@drawable/ic_volume_odi_captions_disabled"
                 style="@style/VolumeButtons"
                 android:background="@drawable/rounded_ripple"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
-                android:tint="@color/accent_tint_color_selector"
+                android:tint="@color/caption_tint_color_selector"
                 android:layout_gravity="center"
-                android:soundEffectsEnabled="false" />
+                android:soundEffectsEnabled="false"
+                sysui:optedOut="false"/>
         </FrameLayout>
 
         <ViewStub
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 62309fd..3aba6a0 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -165,6 +165,12 @@
     <!-- Message of USB contaminant presence dialog [CHAR LIMIT=NONE] -->
     <string name="usb_contaminant_message">To protect your device from liquid or debris, the USB port is disabled and won\u2019t detect any accessories.\n\nYou\u2019ll be notified when it\u2019s safe to use the USB port again.</string>
 
+    <!-- Toast for enabling ports from USB contaminant dialog [CHAR LIMIT=NONE] -->
+    <string name="usb_port_enabled">USB port enabled to detect chargers and accessories</string>
+
+    <!-- Button text to disable contaminant detection [CHAR LIMIT=NONE] -->
+    <string name="usb_disable_contaminant_detection">Enable USB</string>
+
     <!-- Checkbox label for application compatibility mode ON (zooming app to look like it's running
          on a phone).  [CHAR LIMIT=25] -->
     <string name="compat_mode_on">Zoom to fill screen</string>
@@ -2228,6 +2234,9 @@
     <!-- Quick settings tile secondary label format combining roaming with the mobile data type. [CHAR LIMIT=NONE] -->
     <string name="mobile_data_text_format"><xliff:g name="roaming_status" example="Roaming">%1$s</xliff:g> \u2014 <xliff:g name="mobile_data_type" example="LTE">%2$s</xliff:g></string>
 
+    <!-- Quick settings tile secondary label format combining carrier name with the mobile data tye. [CHAR LIMIT=NONE] -->
+    <string name="mobile_carrier_text_format"><xliff:g id="carrier_name" example="Test">%1$s</xliff:g>, <xliff:g id="mobile_data_type" example="LTE">%2$s</xliff:g></string>
+
     <!-- Label for when wifi is off in QS detail panel [CHAR LIMIT=NONE] -->
     <string name="wifi_is_off">Wi-Fi is off</string>
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
index b363b4a..8d6f830 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/NavigationBarCompat.java
@@ -21,12 +21,8 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 
-/**
- * TODO: Remove this class
- */
 public class NavigationBarCompat extends QuickStepContract {
 
-
     @Retention(RetentionPolicy.SOURCE)
     @IntDef({HIT_TARGET_NONE, HIT_TARGET_BACK, HIT_TARGET_HOME, HIT_TARGET_OVERVIEW})
     public @interface HitTarget{}
@@ -59,4 +55,6 @@
      * Interaction type: show/hide the overview button while this service is connected to launcher
      */
     public static final int FLAG_SHOW_OVERVIEW_BUTTON = 0x4;
+
+
 }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 6d7abd0..46f4c86 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -16,7 +16,13 @@
 
 package com.android.systemui.shared.system;
 
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
+import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
+
+import android.content.Context;
 import android.content.res.Resources;
+import android.view.WindowManagerPolicyConstants;
 
 /**
  * Various shared constants between Launcher and SysUI as part of quickstep
@@ -28,6 +34,13 @@
     public static final String KEY_EXTRA_WINDOW_CORNER_RADIUS = "extra_window_corner_radius";
     public static final String KEY_EXTRA_SUPPORTS_WINDOW_CORNERS = "extra_supports_window_corners";
 
+    public static final String NAV_BAR_MODE_2BUTTON_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON_OVERLAY;
+    public static final String NAV_BAR_MODE_3BUTTON_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON_OVERLAY;
+    public static final String NAV_BAR_MODE_GESTURAL_OVERLAY =
+            WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL_OVERLAY;
+
     /**
      * Touch slopes and thresholds for quick step operations. Drag slop is the point where the
      * home button press/long press over are ignored and will start to drag when exceeded and the
@@ -49,4 +62,54 @@
     private static int convertDpToPixel(float dp) {
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
+
+    /**
+     * @return whether this nav bar mode is edge to edge
+     */
+    public static boolean isGesturalMode(int mode) {
+        return mode == NAV_BAR_MODE_GESTURAL;
+    }
+
+    /**
+     * @return whether the current nav bar mode is gestural
+     */
+    public static boolean isGesturalMode(Context context) {
+        return isGesturalMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return whether this nav bar mode is swipe up
+     */
+    public static boolean isSwipeUpMode(int mode) {
+        return mode == NAV_BAR_MODE_2BUTTON;
+    }
+
+    /**
+     * @return whether the current nav bar mode is swipe up
+     */
+    public static boolean isSwipeUpMode(Context context) {
+        return isSwipeUpMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return whether this nav bar mode is 3 button
+     */
+    public static boolean isLegacyMode(int mode) {
+        return mode == NAV_BAR_MODE_3BUTTON;
+    }
+
+    /**
+     * @return whether this nav bar mode is 3 button
+     */
+    public static boolean isLegacyMode(Context context) {
+        return isLegacyMode(getCurrentInteractionMode(context));
+    }
+
+    /**
+     * @return the current nav bar interaction mode
+     */
+    public static int getCurrentInteractionMode(Context context) {
+        return context.getResources().getInteger(
+                com.android.internal.R.integer.config_navBarInteractionMode);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
index 895f9b9..f649976 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
@@ -155,8 +155,9 @@
 
     @Singleton
     @Provides
-    public NightDisplayListener provideNightDisplayListener(Context context) {
-        return new NightDisplayListener(context);
+    public NightDisplayListener provideNightDisplayListener(Context context,
+            @Named(BG_HANDLER_NAME) Handler bgHandler) {
+        return new NightDisplayListener(context, bgHandler);
     }
 
     @Singleton
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
index 2fa87d8..8731b6b 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/PhysicsAnimationLayout.java
@@ -226,9 +226,6 @@
     protected final HashMap<DynamicAnimation.ViewProperty, Runnable> mEndActionForProperty =
             new HashMap<>();
 
-    /** Set of currently rendered transient views. */
-    private final Set<View> mTransientViews = new HashSet<>();
-
     /** The currently active animation controller. */
     private PhysicsAnimationController mController;
 
@@ -328,18 +325,6 @@
         removeView(getChildAt(index));
     }
 
-    @Override
-    public void addTransientView(View view, int index) {
-        super.addTransientView(view, index);
-        mTransientViews.add(view);
-    }
-
-    @Override
-    public void removeTransientView(View view) {
-        super.removeTransientView(view);
-        mTransientViews.remove(view);
-    }
-
     /** Immediately moves the view from wherever it currently is, to the given index. */
     public void moveViewTo(View view, int index) {
         super.removeView(view);
@@ -363,7 +348,9 @@
             // Tell the controller to animate this view out, and call the callback when it's
             // finished.
             mController.onChildRemoved(view, index, () -> {
-                // Done animating, remove the transient view.
+                // The controller says it's done with the transient view, cancel animations in case
+                // any are still running and then remove it.
+                cancelAnimationsOnView(view);
                 removeTransientView(view);
 
                 if (callback != null) {
@@ -470,13 +457,11 @@
             DynamicAnimation.ViewProperty property, View child, int index) {
         SpringAnimation newAnim = new SpringAnimation(child, property);
         newAnim.addUpdateListener((animation, value, velocity) -> {
+            final int indexOfChild = indexOfChild(child);
             final int nextAnimInChain =
-                    mController.getNextAnimationInChain(property, indexOfChild(child));
+                    mController.getNextAnimationInChain(property, indexOfChild);
 
-            // If the controller doesn't want us to chain, or if we're a transient view in the
-            // process of being removed, don't chain.
-            if (nextAnimInChain == PhysicsAnimationController.NONE
-                    || mTransientViews.contains(child)) {
+            if (nextAnimInChain == PhysicsAnimationController.NONE || indexOfChild < 0) {
                 return;
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
index c587a39..db79e4d7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CellularTile.java
@@ -25,11 +25,7 @@
 import android.content.res.Resources;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
-import android.text.SpannableString;
-import android.text.SpannableStringBuilder;
-import android.text.Spanned;
 import android.text.TextUtils;
-import android.text.style.TextAppearanceSpan;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -192,8 +188,10 @@
             state.secondaryLabel = r.getString(R.string.status_bar_airplane);
         } else if (mobileDataEnabled) {
             state.state = Tile.STATE_ACTIVE;
-            state.secondaryLabel = appendMobileDataType(getMobileDataSubscriptionName(cb),
-                    cb.dataContentDescription);
+            state.secondaryLabel = appendMobileDataType(
+                    // Only show carrier name if there are more than 1 subscription
+                    cb.multipleSubs ? cb.dataSubscriptionName : "",
+                    getMobileDataContentName(cb));
         } else {
             state.state = Tile.STATE_INACTIVE;
             state.secondaryLabel = r.getString(R.string.cell_data_off);
@@ -216,24 +214,22 @@
         if (TextUtils.isEmpty(dataType)) {
             return current;
         }
-        SpannableString type = new SpannableString(dataType);
-        SpannableStringBuilder builder = new SpannableStringBuilder(current);
-        builder.append(" ");
-        builder.append(type, new TextAppearanceSpan(mContext, R.style.TextAppearance_RATBadge),
-                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
-        return builder;
+        if (TextUtils.isEmpty(current)) {
+            return dataType;
+        }
+        return mContext.getString(R.string.mobile_carrier_text_format, current, dataType);
     }
 
-    private CharSequence getMobileDataSubscriptionName(CallbackInfo cb) {
-        if (cb.roaming && !TextUtils.isEmpty(cb.dataSubscriptionName)) {
+    private CharSequence getMobileDataContentName(CallbackInfo cb) {
+        if (cb.roaming && !TextUtils.isEmpty(cb.dataContentDescription)) {
             String roaming = mContext.getString(R.string.data_connection_roaming);
-            String dataDescription = cb.dataSubscriptionName.toString();
+            String dataDescription = cb.dataContentDescription.toString();
             return mContext.getString(R.string.mobile_data_text_format, roaming, dataDescription);
         }
         if (cb.roaming) {
             return mContext.getString(R.string.data_connection_roaming);
         }
-        return cb.dataSubscriptionName;
+        return cb.dataContentDescription;
     }
 
     @Override
@@ -254,6 +250,7 @@
         boolean activityOut;
         boolean noSim;
         boolean roaming;
+        boolean multipleSubs;
     }
 
     private final class CellSignalCallback implements SignalCallback {
@@ -272,6 +269,7 @@
             mInfo.activityIn = activityIn;
             mInfo.activityOut = activityOut;
             mInfo.roaming = roaming;
+            mInfo.multipleSubs = mController.getNumberSubscriptions() > 1;
             refreshState(mInfo);
         }
 
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 effa935..241b375 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NightDisplayTile.java
@@ -19,11 +19,12 @@
 import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_QS_MODE;
 
 import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.content.Intent;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.NightDisplayListener;
 import android.metrics.LogMaker;
+import android.os.Handler;
+import android.os.Looper;
 import android.provider.Settings;
 import android.service.quicksettings.Tile;
 import android.text.TextUtils;
@@ -66,7 +67,7 @@
     public NightDisplayTile(QSHost host) {
         super(host);
         mManager = mContext.getSystemService(ColorDisplayManager.class);
-        mListener = new NightDisplayListener(mContext, ActivityManager.getCurrentUser());
+        mListener = new NightDisplayListener(mContext, new Handler(Looper.myLooper()));
     }
 
     @Override
@@ -102,7 +103,7 @@
         }
 
         // Make a new controller for the new user.
-        mListener = new NightDisplayListener(mContext, newUserId);
+        mListener = new NightDisplayListener(mContext, newUserId, new Handler(Looper.myLooper()));
         if (mIsListening) {
             mListener.setCallback(this);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 9219594..494e6cd 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -46,7 +46,6 @@
 import android.os.PatternMatcher;
 import android.os.RemoteException;
 import android.os.UserHandle;
-import android.provider.Settings;
 import android.util.Log;
 import android.view.InputChannel;
 import android.view.MotionEvent;
@@ -60,6 +59,7 @@
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.stackdivider.Divider;
 import com.android.systemui.statusbar.phone.StatusBar;
 import com.android.systemui.statusbar.policy.CallbackController;
@@ -589,11 +589,9 @@
 
     private int getDefaultInteractionFlags() {
         // If there is no settings available use device default or get it from settings
-        final boolean defaultState = getSwipeUpDefaultValue();
-        final boolean swipeUpEnabled = getSwipeUpSettingAvailable()
-                ? getSwipeUpEnabledFromSettings(defaultState)
-                : defaultState;
-        return swipeUpEnabled ? 0 : DEFAULT_DISABLE_SWIPE_UP_STATE;
+        return QuickStepContract.isLegacyMode(mContext)
+                ? DEFAULT_DISABLE_SWIPE_UP_STATE
+                : 0;
     }
 
     private void notifyBackButtonAlphaChanged(float alpha, boolean animate) {
@@ -638,21 +636,6 @@
                 ActivityManagerWrapper.getInstance().getCurrentUserId()) != null;
     }
 
-    private boolean getSwipeUpDefaultValue() {
-        return mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_default);
-    }
-
-    private boolean getSwipeUpSettingAvailable() {
-        return mContext.getResources()
-                .getBoolean(com.android.internal.R.bool.config_swipe_up_gesture_setting_available);
-    }
-
-    private boolean getSwipeUpEnabledFromSettings(boolean defaultValue) {
-        return Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED, defaultValue ? 1 : 0) == 1;
-    }
-
     @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(TAG_OPS + " state:");
@@ -665,11 +648,8 @@
 
         pw.print("  quickStepIntent="); pw.println(mQuickStepIntent);
         pw.print("  quickStepIntentResolved="); pw.println(isEnabled());
-
-        final boolean swipeUpDefaultValue = getSwipeUpDefaultValue();
-        final boolean swipeUpEnabled = getSwipeUpEnabledFromSettings(swipeUpDefaultValue);
-        pw.print("  swipeUpSetting="); pw.println(swipeUpEnabled);
-        pw.print("  swipeUpSettingDefault="); pw.println(swipeUpDefaultValue);
+        pw.print("  navBarMode=");
+        pw.println(QuickStepContract.getCurrentInteractionMode(mContext));
     }
 
     public interface OverviewProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
index 2d54970..9cfb1aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavBarTintController.java
@@ -21,10 +21,11 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.os.Handler;
-import android.provider.Settings;
 import android.view.CompositionSamplingListener;
 import android.view.View;
 
+import com.android.systemui.shared.system.QuickStepContract;
+
 import java.io.PrintWriter;
 
 /**
@@ -166,9 +167,6 @@
 
     public static boolean isEnabled(Context context) {
         return context.getDisplayId() == DEFAULT_DISPLAY
-                && Settings.Global.getInt(context.getContentResolver(),
-                        NavigationPrototypeController.NAV_COLOR_ADAPT_ENABLE_SETTING, 0) == 1
-                && Settings.Global.getInt(context.getContentResolver(),
-                        NavigationPrototypeController.SHOW_HOME_HANDLE_SETTING, 0) == 1;
+                && QuickStepContract.isGesturalMode(context);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
index 1478a07..c77b16b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java
@@ -71,7 +71,7 @@
 
     @Override
     protected void onGestureStart(MotionEvent event) {
-        if (!QuickStepController.shouldhideBackButton(getContext())) {
+        if (!QuickStepController.shouldHideBackButton(getContext())) {
             mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */,
                     BACK_BUTTON_FADE_OUT_ALPHA);
         }
@@ -85,7 +85,7 @@
     @Override
     protected void onGestureEnd() {
         mHandler.removeCallbacks(mExecuteBackRunnable);
-        if (!QuickStepController.shouldhideBackButton(getContext())) {
+        if (!QuickStepController.shouldHideBackButton(getContext())) {
             mNavigationBarView.getBackButton().setAlpha(
                     mProxySender.getBackButtonAlpha(), true /* animate */);
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index ea30451..cbb5d54 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -201,7 +201,7 @@
         @Override
         public void onBackButtonAlphaChanged(float alpha, boolean animate) {
             final ButtonDispatcher backButton = mNavigationBarView.getBackButton();
-            if (QuickStepController.shouldhideBackButton(getContext())) {
+            if (QuickStepController.shouldHideBackButton(getContext())) {
                 // If property was changed to hide/show back button, going home will trigger
                 // launcher to to change the back button alpha to reflect property change
                 backButton.setVisibility(View.GONE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index faa2ab1..26aa617 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -38,6 +38,7 @@
 import com.android.systemui.plugins.statusbar.phone.NavBarButtonProvider;
 import com.android.systemui.recents.OverviewProxyService;
 import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.statusbar.phone.ReverseLinearLayout.ReverseRelativeLayout;
 import com.android.systemui.statusbar.policy.KeyButtonView;
 import com.android.systemui.tuner.TunerService;
@@ -136,10 +137,12 @@
     }
 
     protected String getDefaultLayout() {
-        final int defaultResource = mOverviewProxyService.shouldShowSwipeUpUI()
-                ? R.string.config_navBarLayoutQuickstep
-                : R.string.config_navBarLayout;
-        return mContext.getString(defaultResource);
+        final int defaultResource = QuickStepContract.isGesturalMode(getContext())
+                ? R.string.config_navBarLayoutHandle
+                : mOverviewProxyService.shouldShowSwipeUpUI()
+                        ? R.string.config_navBarLayoutQuickstep
+                        : R.string.config_navBarLayout;
+        return getContext().getString(defaultResource);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index e9a9606..f809b62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import static android.content.Intent.ACTION_OVERLAY_CHANGED;
 import static android.view.MotionEvent.ACTION_DOWN;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID;
 import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
@@ -41,7 +42,10 @@
 import android.annotation.IntDef;
 import android.annotation.SuppressLint;
 import android.app.StatusBarManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.pm.ParceledListSlice;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
@@ -88,6 +92,7 @@
 import com.android.systemui.shared.plugins.PluginManager;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.NavigationBarCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 import com.android.systemui.statusbar.phone.NavigationPrototypeController.GestureAction;
 import com.android.systemui.statusbar.phone.NavigationPrototypeController.OnPrototypeChangedListener;
@@ -280,6 +285,7 @@
         }
     };
 
+    // TODO(b/112934365): To be removed
     private OnPrototypeChangedListener mPrototypeListener = new OnPrototypeChangedListener() {
         @Override
         public void onGestureRemap(int[] actions) {
@@ -289,13 +295,15 @@
         @Override
         public void onBackButtonVisibilityChanged(boolean visible) {
             if (!inScreenPinning()) {
-                getBackButton().setVisibility(visible ? VISIBLE : GONE);
+                getBackButton().setVisibility(QuickStepController.shouldHideBackButton(getContext())
+                        ? GONE : VISIBLE);
             }
         }
 
         @Override
         public void onHomeButtonVisibilityChanged(boolean visible) {
-            getHomeButton().setVisibility(visible ? VISIBLE : GONE);
+            getHomeButton().setVisibility(QuickStepController.shouldHideHomeButton(getContext())
+                    ? GONE : VISIBLE);
         }
 
         @Override
@@ -319,7 +327,7 @@
 
         @Override
         public void onHomeHandleVisiblilityChanged(boolean visible) {
-            showHomeHandle(visible);
+            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
         }
 
         @Override
@@ -368,6 +376,13 @@
         }
     };
 
+    private BroadcastReceiver mOverlaysChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            showHomeHandle(QuickStepController.showHomeHandle(getContext()));
+        }
+    };
+
     public NavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
 
@@ -421,10 +436,14 @@
                 mQuickScrubAction, null /* swipeLeftEdgeAction */, null /* swipeRightEdgeAction */
         };
 
-        mPrototypeController = new NavigationPrototypeController(mContext);
+        mPrototypeController = new NavigationPrototypeController(context);
         mPrototypeController.register();
         mPrototypeController.setOnPrototypeChangedListener(mPrototypeListener);
         mColorAdaptionController = new NavBarTintController(this, getLightTransitionsController());
+
+        IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+        filter.addDataScheme("package");
+        context.registerReceiver(mOverlaysChangedReceiver, filter);
     }
 
     public NavBarTintController getColorAdaptionController() {
@@ -459,7 +478,12 @@
 
     private void updateNavigationGestures() {
         if (mGestureHelper instanceof QuickStepController) {
-            final int[] assignedMap = mPrototypeController.getGestureActionMap();
+            // TODO: Clarify this when we remove the prototype controller
+            final int[] gesturalMap = {0, 7, 1, 1, 3, 3};
+            final int[] normalMap = {0, 0, 0, 0, 0, 0};
+            final int[] assignedMap = QuickStepContract.isGesturalMode(getContext())
+                    ? gesturalMap
+                    : normalMap;
             ((QuickStepController) mGestureHelper).setGestureActions(
                     getNavigationActionFromType(assignedMap[0], mDefaultGestureMap[0]),
                     getNavigationActionFromType(assignedMap[1], mDefaultGestureMap[1]),
@@ -616,6 +640,7 @@
     }
 
     public boolean isQuickScrubEnabled() {
+        // TODO(b/112934365): Remove this sys prop flag
         return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
                 && mOverviewProxyService.isEnabled() && isOverviewEnabled()
                 && ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
@@ -762,17 +787,17 @@
 
         mBarTransitions.reapplyDarkIntensity();
 
-        boolean disableHome = ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
+        boolean disableHome = QuickStepController.shouldHideHomeButton(getContext())
+                || ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
 
         // TODO(b/113914868): investigation log for disappearing home button
         Log.i(TAG, "updateNavButtonIcons (b/113914868): home disabled=" + disableHome
                 + " mDisabledFlags=" + mDisabledFlags);
-        disableHome |= mPrototypeController.hideHomeButton();
 
         // Always disable recents when alternate car mode UI is active and for secondary displays.
         boolean disableRecent = isRecentsButtonDisabled();
 
-        boolean disableBack = QuickStepController.shouldhideBackButton(getContext())
+        boolean disableBack = QuickStepController.shouldHideBackButton(getContext())
                 || (((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0) && !useAltBack);
 
         // When screen pinning, don't hide back and home when connected service or back and
@@ -791,7 +816,7 @@
             disableBack = disableRecent = false;
         }
 
-        ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
+        ViewGroup navButtons = getCurrentView().findViewById(R.id.nav_buttons);
         if (navButtons != null) {
             LayoutTransition lt = navButtons.getLayoutTransition();
             if (lt != null) {
@@ -946,8 +971,7 @@
     }
 
     private void showHomeHandle(boolean visible) {
-        mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS,
-                visible ? getContext().getString(R.string.config_navBarLayoutHandle) : null);
+        mNavigationInflaterView.onTuningChanged(NAV_BAR_VIEWS, null);
 
         // Color adaption is tied with showing home handle, only avaliable if visible
         if (visible) {
@@ -964,7 +988,7 @@
 
     // TODO(b/112934365): move this back to NavigationBarFragment when prototype is removed
     private void updateAssistantAvailability() {
-        boolean available = mAssistantAvailable && mPrototypeController.isAssistantGestureEnabled();
+        boolean available = mAssistantAvailable && QuickStepContract.isGesturalMode(getContext());
         if (mOverviewProxyService.getProxy() != null) {
             try {
                 mOverviewProxyService.getProxy().onAssistantAvailable(available);
@@ -1267,7 +1291,7 @@
                 NavGesture.class, false /* Only one */);
         setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
 
-        if (mPrototypeController.isEnabled()) {
+        if (QuickStepContract.isGesturalMode(getContext())) {
             WindowManager wm = (WindowManager) getContext()
                     .getSystemService(Context.WINDOW_SERVICE);
             int width = mPrototypeController.getEdgeSensitivityWidth();
@@ -1298,6 +1322,7 @@
             mGestureHelper.destroy();
         }
         mPrototypeController.unregister();
+        getContext().unregisterReceiver(mOverlaysChangedReceiver);
         setUpSwipeUpOnboarding(false);
         for (int i = 0; i < mButtonDispatchers.size(); ++i) {
             mButtonDispatchers.valueAt(i).onDestroy();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
index 9ea8b64..7ea72c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java
@@ -130,7 +130,8 @@
      * @return the width for edge swipe
      */
     public int getEdgeSensitivityWidth() {
-        return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0));
+        // TODO: Move into resource
+        return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 48));
     }
 
     /**
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 3398fd34..25cb7d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java
@@ -58,6 +58,7 @@
 import com.android.systemui.shared.recents.utilities.Utilities;
 import com.android.systemui.shared.system.InputChannelCompat.InputEventDispatcher;
 import com.android.systemui.shared.system.NavigationBarCompat;
+import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
 
@@ -72,6 +73,7 @@
 
     /** Experiment to swipe home button left to execute a back key press */
     private static final String HIDE_BACK_BUTTON_PROP = "quickstepcontroller_hideback";
+    private static final String HIDE_HOME_BUTTON_PROP = "quickstepcontroller_hidehome";
     private static final String ENABLE_CLICK_THROUGH_NAV_PROP = "quickstepcontroller_clickthrough";
     private static final String GESTURE_REGION_THRESHOLD_SETTING = "gesture_region_threshold";
     private static final long BACK_BUTTON_FADE_IN_ALPHA = 150;
@@ -148,7 +150,7 @@
     public void setComponents(NavigationBarView navigationBarView) {
         mNavigationBarView = navigationBarView;
 
-        mNavigationBarView.getBackButton().setVisibility(shouldhideBackButton(mContext)
+        mNavigationBarView.getBackButton().setVisibility(shouldHideBackButton(mContext)
                 ? View.GONE
                 : View.VISIBLE);
     }
@@ -355,7 +357,7 @@
                         if (mCurrentAction != null) {
                             mCurrentAction.endGesture();
                         }
-                    } else if (getBoolGlobalSetting(mContext, ENABLE_CLICK_THROUGH_NAV_PROP)
+                    } else if (QuickStepContract.isGesturalMode(mContext)
                             && !mClickThroughPressed) {
                         // Enable click through functionality where no gesture has been detected and
                         // not passed the drag slop so inject a touch event at the same location
@@ -700,6 +702,8 @@
         return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
     }
 
+    // TODO(112934365): Clean up following methods when cleaning up nav bar experiments
+
     static boolean getBoolGlobalSetting(Context context, String key) {
         return Settings.Global.getInt(context.getContentResolver(), key, 0) != 0;
     }
@@ -708,7 +712,24 @@
         return Settings.Global.getInt(context.getContentResolver(), key, defaultValue);
     }
 
-    public static boolean shouldhideBackButton(Context context) {
-        return getBoolGlobalSetting(context, HIDE_BACK_BUTTON_PROP);
+    /**
+     * @return whether to hide the back button.
+     */
+    public static boolean shouldHideBackButton(Context context) {
+        return QuickStepContract.isGesturalMode(context);
+    }
+
+    /**
+     * @return whether to hide the home button.
+     */
+    public static boolean shouldHideHomeButton(Context context) {
+        return QuickStepContract.isGesturalMode(context);
+    }
+
+    /**
+     * @return whether to show the home handle.
+     */
+    public static boolean showHomeHandle(Context context) {
+        return QuickStepContract.isGesturalMode(context);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 5bd394f..c5996a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -470,10 +470,16 @@
             mNetworkController.recalculateEmergency();
         }
         // Fill in the network name if we think we have it.
-        if (mCurrentState.networkName == mNetworkNameDefault && mServiceState != null
+        if (mCurrentState.networkName.equals(mNetworkNameDefault) && mServiceState != null
                 && !TextUtils.isEmpty(mServiceState.getOperatorAlphaShort())) {
             mCurrentState.networkName = mServiceState.getOperatorAlphaShort();
         }
+        // If this is the data subscription, update the currentState data name
+        if (mCurrentState.networkNameData.equals(mNetworkNameDefault) && mServiceState != null
+                && mCurrentState.dataSim
+                && !TextUtils.isEmpty(mServiceState.getDataOperatorAlphaShort())) {
+            mCurrentState.networkNameData = mServiceState.getDataOperatorAlphaShort();
+        }
 
         notifyListenersIfNecessary();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 51fef7d..71db618 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -37,6 +37,7 @@
     DataUsageController getMobileDataController();
     DataSaverController getDataSaverController();
     String getMobileDataNetworkName();
+    int getNumberSubscriptions();
 
     boolean hasVoiceCallingFeature();
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index ef39912..d01430a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -376,6 +376,11 @@
         return controller != null ? controller.getState().networkNameData : "";
     }
 
+    @Override
+    public int getNumberSubscriptions() {
+        return mMobileSignalControllers.size();
+    }
+
     public boolean isEmergencyOnly() {
         if (mMobileSignalControllers.size() == 0) {
             // When there are no active subscriptions, determine emengency state from last
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
index fa4b3fe..ecf608b 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbContaminantActivity.java
@@ -16,14 +16,17 @@
 
 package com.android.systemui.usb;
 
+import android.app.AlertDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.hardware.usb.ParcelableUsbPort;
 import android.hardware.usb.UsbManager;
 import android.hardware.usb.UsbPort;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.Window;
 import android.view.WindowManager;
+import android.widget.Toast;
 
 import com.android.internal.app.AlertActivity;
 import com.android.internal.app.AlertController;
@@ -36,7 +39,6 @@
                                   implements DialogInterface.OnClickListener {
     private static final String TAG = "UsbContaminantActivity";
 
-    private UsbDisconnectedReceiver mDisconnectedReceiver;
     private UsbPort mUsbPort;
 
     @Override
@@ -55,8 +57,10 @@
         final AlertController.AlertParams ap = mAlertParams;
         ap.mTitle = getString(R.string.usb_contaminant_title);
         ap.mMessage = getString(R.string.usb_contaminant_message);
-        ap.mPositiveButtonText = getString(android.R.string.ok);
-        ap.mPositiveButtonListener = this;
+        ap.mNegativeButtonText = getString(android.R.string.ok);
+        ap.mNeutralButtonText = getString(R.string.usb_disable_contaminant_detection);
+        ap.mNegativeButtonListener = this;
+        ap.mNeutralButtonListener = this;
 
         setupAlert();
     }
@@ -68,6 +72,15 @@
 
     @Override
     public void onClick(DialogInterface dialog, int which) {
+        if (which == AlertDialog.BUTTON_NEUTRAL) {
+            try {
+                mUsbPort.enableContaminantDetection(false);
+                Toast.makeText(this, R.string.usb_port_enabled,
+                    Toast.LENGTH_SHORT).show();
+            } catch (Exception e) {
+                Log.e(TAG, "Unable to notify Usb service", e);
+            }
+        }
         finish();
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 5cafc02..4fe18b4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -448,7 +448,12 @@
         }
     }
 
-   protected void assertNetworkNameEquals(String expected) {
+    protected void assertNetworkNameEquals(String expected) {
        assertEquals("Network name", expected, mMobileSignalController.getState().networkName);
-   }
+    }
+
+    protected void assertDataNetworkNameEquals(String expected) {
+        assertEquals("Data network name", expected, mNetworkController.getMobileDataNetworkName());
+    }
+
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index 68323c9..cd0a0441 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -285,6 +285,15 @@
         testDataActivity(TelephonyManager.DATA_ACTIVITY_INOUT, true, true);
     }
 
+    @Test
+    public void testUpdateDataNetworkName() {
+        setupDefaultSignal();
+        String newDataName = "TestDataName";
+        when(mServiceState.getDataOperatorAlphaShort()).thenReturn(newDataName);
+        updateServiceState();
+        assertDataNetworkNameEquals(newDataName);
+    }
+
     private void testDataActivity(int direction, boolean in, boolean out) {
         updateDataActivity(direction);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index bcbba8b..ac6544e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -20,6 +20,7 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.net.ConnectivityManager;
@@ -55,7 +56,7 @@
     @Test
     public void testNoIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -117,7 +118,7 @@
     @Test
     public void testNoSimlessIconWithoutMobile() {
         // Turn off mobile network support.
-        Mockito.when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
+        when(mMockCm.isNetworkSupported(ConnectivityManager.TYPE_MOBILE)).thenReturn(false);
         // Create a new NetworkController as this is currently handled in constructor.
         mNetworkController = new NetworkControllerImpl(mContext, mMockCm, mMockTm, mMockWm, mMockSm,
                 mConfig, Looper.getMainLooper(), mCallbackHandler,
@@ -253,14 +254,14 @@
 
             // Generate a list of subscriptions we will tell the NetworkController to use.
             SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-            Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+            when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
             subscriptions.add(mockSubInfo);
         }
         assertTrue(mNetworkController.hasCorrectMobileControllers(subscriptions));
 
         // Add a subscription that the NetworkController doesn't know about.
         SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-        Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
+        when(mockSubInfo.getSubscriptionId()).thenReturn(notTestSubscription);
         subscriptions.add(mockSubInfo);
         assertFalse(mNetworkController.hasCorrectMobileControllers(subscriptions));
     }
@@ -290,8 +291,8 @@
             if (i != indexToSkipSubscription) {
                 // Generate a list of subscriptions we will tell the NetworkController to use.
                 SubscriptionInfo mockSubInfo = Mockito.mock(SubscriptionInfo.class);
-                Mockito.when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
-                Mockito.when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSubscriptionId()).thenReturn(testSubscriptions[i]);
+                when(mockSubInfo.getSimSlotIndex()).thenReturn(testSubscriptions[i]);
                 subscriptions.add(mockSubInfo);
             }
         }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
index 5385f6d..d5ba381 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/utils/leaks/FakeNetworkController.java
@@ -93,4 +93,9 @@
     public String getMobileDataNetworkName() {
         return "";
     }
+
+    @Override
+    public int getNumberSubscriptions() {
+        return 0;
+    }
 }
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index b522344..c57d4e9 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -48,14 +48,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := frameworks-base-overlays-debug
-LOCAL_REQUIRED_MODULES := \
-	ExperimentNavigationBarFloatingOverlay \
-	ExperimentNavigationBarVisualInsetOverlay \
-	ExperimentNavigationBarDefaultOverlay \
-	ExperimentNavigationBarSlimOverlay32 \
-	ExperimentNavigationBarSlimOverlay40 \
-	ExperimentNavigationBarLargeOverlay56 \
-	ExperimentNavigationBarLargeOverlay64
 
 include $(BUILD_PHONY_PACKAGE)
 include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
new file mode 100644
index 0000000..721d11b
--- /dev/null
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/dimens.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources>
+    <!-- Height of the bottom navigation / system bar. -->
+    <dimen name="navigation_bar_height">16dp</dimen>
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
+    <dimen name="navigation_bar_width">16dp</dimen>
+    <!-- Height of the bottom navigation / system bar. -->
+    <dimen name="navigation_bar_frame_height">48dp</dimen>
+    <!-- Width of the navigation bar when it is placed vertically on the screen -->
+    <dimen name="navigation_bar_frame_width">48dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java
index 98311fc..5b9c1f8 100644
--- a/services/core/java/com/android/server/StorageManagerService.java
+++ b/services/core/java/com/android/server/StorageManagerService.java
@@ -2881,6 +2881,32 @@
         mVold.commitChanges();
     }
 
+    /**
+     * Check if we should be mounting with checkpointing or are checkpointing now
+     */
+    @Override
+    public boolean needsCheckpoint() throws RemoteException {
+        // Only the system process is permitted to commit checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        return mVold.needsCheckpoint();
+    }
+
+    /**
+     * Abort the current set of changes and either try again, or abort entirely
+     */
+    @Override
+    public void abortChanges(String message, boolean retry) throws RemoteException {
+        // Only the system process is permitted to abort checkpoints
+        if (Binder.getCallingUid() != android.os.Process.SYSTEM_UID) {
+            throw new SecurityException("no permission to commit checkpoint changes");
+        }
+
+        mVold.abortChanges(message, retry);
+    }
+
     @Override
     public String getPassword() throws RemoteException {
         mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
@@ -3871,6 +3897,7 @@
                         case "com.jrtstudio.AnotherMusicPlayer": // b/129084562
                         case "ak.alizandro.smartaudiobookplayer": // b/129084042
                         case "com.campmobile.snow": // b/128803870
+                        case "com.qnap.qfile": // b/126374406
                             return Zygote.MOUNT_EXTERNAL_LEGACY;
                     }
                 }
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 26896f5..05b7e0c 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1885,7 +1885,7 @@
                 pw.println("mDataConnectionState=" + mDataConnectionState[i]);
                 pw.println("mCellLocation=" + mCellLocation[i]);
                 pw.println("mCellInfo=" + mCellInfo.get(i));
-                pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i).toString());
+                pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
                 pw.decreaseIndent();
             }
             pw.println("mCallNetworkType=" + mCallNetworkType);
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 712edcc..da66590 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -58,7 +58,6 @@
     private static final int CE_DATABASE_VERSION = 10;
     private static final int DE_DATABASE_VERSION = 3; // Added visibility support in O
 
-
     static final String TABLE_ACCOUNTS = "accounts";
     private static final String ACCOUNTS_ID = "_id";
     private static final String ACCOUNTS_NAME = "name";
@@ -267,6 +266,13 @@
         }
 
         @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts CE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
+        @Override
         public void onOpen(SQLiteDatabase db) {
             if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "opened database " + CE_DATABASE_NAME);
         }
@@ -616,6 +622,13 @@
             }
         }
 
+        @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.e(TAG, "onDowngrade: recreate accounts DE table");
+            resetDatabase(db);
+            onCreate(db);
+        }
+
         public SQLiteDatabase getReadableDatabaseUserIsUnlocked() {
             if(!mCeAttached) {
                 Log.wtf(TAG, "getReadableDatabaseUserIsUnlocked called while user " + mUserId
@@ -1399,4 +1412,26 @@
         return new AccountsDb(deDatabaseHelper, context, preNDatabaseFile);
     }
 
+    /**
+     * Removes all tables and triggers created by AccountManager.
+     */
+    private static void resetDatabase(SQLiteDatabase db) {
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='table'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                // Skip tables managed by SQLiteDatabase
+                if ("android_metadata".equals(name) || "sqlite_sequence".equals(name)) {
+                    continue;
+                }
+                db.execSQL("DROP TABLE IF EXISTS " + name);
+            }
+        }
+
+        try (Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type ='trigger'", null)) {
+            while (c.moveToNext()) {
+                String name = c.getString(0);
+                db.execSQL("DROP TRIGGER IF EXISTS " + name);
+            }
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index e357ce8..1878d00 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -1805,7 +1805,7 @@
                                 || (callerApp.getCurProcState() <= ActivityManager.PROCESS_STATE_TOP
                                         && (flags & Context.BIND_TREAT_LIKE_ACTIVITY) != 0),
                         b.client);
-                mAm.updateOomAdjLocked(s.app, true);
+                mAm.updateOomAdjLocked();
             }
 
             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index b447c53..1681c5b 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.provider.DeviceConfig.NAMESPACE_ATTENTION_MANAGER_SERVICE;
 import static android.provider.Settings.System.ADAPTIVE_SLEEP;
+import static android.service.attention.AttentionService.ATTENTION_FAILURE_CANCELLED;
 
 import android.Manifest;
 import android.annotation.NonNull;
@@ -156,9 +157,8 @@
      *
      * @return {@code true} if the framework was able to send the provided callback to the service
      */
-    private boolean checkAttention(int requestCode, long timeout,
-            AttentionCallbackInternal callback) {
-        Preconditions.checkNotNull(callback);
+    private boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
+        Preconditions.checkNotNull(callbackInternal);
 
         if (!isAttentionServiceSupported()) {
             Slog.w(LOG_TAG, "Trying to call checkAttention() on an unsupported device.");
@@ -172,6 +172,7 @@
 
         synchronized (mLock) {
             final long now = SystemClock.uptimeMillis();
+            // schedule shutting down the connection if no one resets this timer
             freeIfInactiveLocked();
 
             final UserState userState = getOrCreateCurrentUserStateLocked();
@@ -184,46 +185,50 @@
                 // make sure every callback is called back
                 if (userState.mPendingAttentionCheck != null) {
                     userState.mPendingAttentionCheck.cancel(
-                            AttentionService.ATTENTION_FAILURE_UNKNOWN);
+                            ATTENTION_FAILURE_CANCELLED);
                 }
-                userState.mPendingAttentionCheck = new PendingAttentionCheck(requestCode,
-                        callback, () -> checkAttention(requestCode, timeout, callback));
+                // fire the check when the service is started
+                userState.mPendingAttentionCheck = new PendingAttentionCheck(
+                        callbackInternal, () -> checkAttention(timeout, callbackInternal));
             } else {
                 try {
                     // throttle frequent requests
-                    final AttentionCheckCache attentionCheckCache = userState.mAttentionCheckCache;
-                    if (attentionCheckCache != null && now
-                            < attentionCheckCache.mLastComputed + STALE_AFTER_MILLIS) {
-                        callback.onSuccess(requestCode, attentionCheckCache.mResult,
-                                attentionCheckCache.mTimestamp);
+                    final AttentionCheckCache cache = userState.mAttentionCheckCache;
+                    if (cache != null && now < cache.mLastComputed + STALE_AFTER_MILLIS) {
+                        callbackInternal.onSuccess(cache.mResult, cache.mTimestamp);
                         return true;
                     }
 
+                    // schedule request cancellation if not returned by that point yet
                     cancelAfterTimeoutLocked(timeout);
 
-                    userState.mCurrentAttentionCheckRequestCode = requestCode;
-                    userState.mService.checkAttention(requestCode, new IAttentionCallback.Stub() {
-                        @Override
-                        public void onSuccess(int requestCode, int result, long timestamp) {
-                            callback.onSuccess(requestCode, result, timestamp);
-                            synchronized (mLock) {
-                                userState.mAttentionCheckCache = new AttentionCheckCache(
-                                        SystemClock.uptimeMillis(), result,
-                                        timestamp);
-                                userState.mCurrentAttentionCheckIsFulfilled = true;
-                            }
-                            StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
-                                    result);
-                        }
+                    userState.mCurrentAttentionCheck = new AttentionCheck(callbackInternal,
+                            new IAttentionCallback.Stub() {
+                                @Override
+                                public void onSuccess(int result, long timestamp) {
+                                    callbackInternal.onSuccess(result, timestamp);
+                                    synchronized (mLock) {
+                                        userState.mAttentionCheckCache = new AttentionCheckCache(
+                                                SystemClock.uptimeMillis(), result,
+                                                timestamp);
+                                        userState.mCurrentAttentionCheckIsFulfilled = true;
+                                    }
+                                    StatsLog.write(
+                                            StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
+                                            result);
+                                }
 
-                        @Override
-                        public void onFailure(int requestCode, int error) {
-                            callback.onFailure(requestCode, error);
-                            userState.mCurrentAttentionCheckIsFulfilled = true;
-                            StatsLog.write(StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
-                                    error);
-                        }
-                    });
+                                @Override
+                                public void onFailure(int error) {
+                                    callbackInternal.onFailure(error);
+                                    userState.mCurrentAttentionCheckIsFulfilled = true;
+                                    StatsLog.write(
+                                            StatsLog.ATTENTION_MANAGER_SERVICE_RESULT_REPORTED,
+                                            error);
+                                }
+                            });
+                    userState.mService.checkAttention(
+                            userState.mCurrentAttentionCheck.mIAttentionCallback);
                 } catch (RemoteException e) {
                     Slog.e(LOG_TAG, "Cannot call into the AttentionService");
                     return false;
@@ -234,7 +239,7 @@
     }
 
     /** Cancels the specified attention check. */
-    private void cancelAttentionCheck(int requestCode) {
+    private void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
         synchronized (mLock) {
             final UserState userState = peekCurrentUserStateLocked();
             if (userState == null) {
@@ -242,15 +247,21 @@
             }
             if (userState.mService == null) {
                 if (userState.mPendingAttentionCheck != null
-                        && userState.mPendingAttentionCheck.mRequestCode == requestCode) {
+                        && userState.mPendingAttentionCheck.mCallbackInternal.equals(
+                        callbackInternal)) {
                     userState.mPendingAttentionCheck = null;
                 }
                 return;
             }
-            try {
-                userState.mService.cancelAttentionCheck(requestCode);
-            } catch (RemoteException e) {
-                Slog.e(LOG_TAG, "Cannot call into the AttentionService");
+            if (userState.mCurrentAttentionCheck.mCallbackInternal.equals(callbackInternal)) {
+                try {
+                    userState.mService.cancelAttentionCheck(
+                            userState.mCurrentAttentionCheck.mIAttentionCallback);
+                } catch (RemoteException e) {
+                    Slog.e(LOG_TAG, "Cannot call into the AttentionService");
+                }
+            } else {
+                Slog.e(LOG_TAG, "Cannot cancel a non-current request");
             }
         }
     }
@@ -387,14 +398,13 @@
         }
 
         @Override
-        public boolean checkAttention(int requestCode, long timeout,
-                AttentionCallbackInternal callback) {
-            return AttentionManagerService.this.checkAttention(requestCode, timeout, callback);
+        public boolean checkAttention(long timeout, AttentionCallbackInternal callbackInternal) {
+            return AttentionManagerService.this.checkAttention(timeout, callbackInternal);
         }
 
         @Override
-        public void cancelAttentionCheck(int requestCode) {
-            AttentionManagerService.this.cancelAttentionCheck(requestCode);
+        public void cancelAttentionCheck(AttentionCallbackInternal callbackInternal) {
+            AttentionManagerService.this.cancelAttentionCheck(callbackInternal);
         }
 
         @Override
@@ -417,19 +427,17 @@
     }
 
     private static final class PendingAttentionCheck {
-        private final int mRequestCode;
-        private final AttentionCallbackInternal mCallback;
+        private final AttentionCallbackInternal mCallbackInternal;
         private final Runnable mRunnable;
 
-        PendingAttentionCheck(int requestCode, AttentionCallbackInternal callback,
+        PendingAttentionCheck(AttentionCallbackInternal callbackInternal,
                 Runnable runnable) {
-            mRequestCode = requestCode;
-            mCallback = callback;
+            mCallbackInternal = callbackInternal;
             mRunnable = runnable;
         }
 
         void cancel(@AttentionFailureCodes int failureCode) {
-            mCallback.onFailure(mRequestCode, failureCode);
+            mCallbackInternal.onFailure(failureCode);
         }
 
         void run() {
@@ -437,6 +445,17 @@
         }
     }
 
+    private static final class AttentionCheck {
+        private final AttentionCallbackInternal mCallbackInternal;
+        private final IAttentionCallback mIAttentionCallback;
+
+        AttentionCheck(AttentionCallbackInternal callbackInternal,
+                IAttentionCallback iAttentionCallback) {
+            mCallbackInternal = callbackInternal;
+            mIAttentionCallback = iAttentionCallback;
+        }
+    }
+
     private static final class UserState {
         final ComponentName mComponentName;
         final AttentionServiceConnection mConnection = new AttentionServiceConnection();
@@ -446,12 +465,12 @@
         @GuardedBy("mLock")
         boolean mBinding;
         @GuardedBy("mLock")
-        int mCurrentAttentionCheckRequestCode;
+        AttentionCheck mCurrentAttentionCheck;
         @GuardedBy("mLock")
         boolean mCurrentAttentionCheckIsFulfilled;
+
         @GuardedBy("mLock")
         PendingAttentionCheck mPendingAttentionCheck;
-
         @GuardedBy("mLock")
         AttentionCheckCache mAttentionCheckCache;
 
@@ -569,8 +588,7 @@
                         if (userState != null) {
                             // If not called back already.
                             if (!userState.mCurrentAttentionCheckIsFulfilled) {
-                                cancel(userState,
-                                        AttentionService.ATTENTION_FAILURE_TIMED_OUT);
+                                cancel(userState, AttentionService.ATTENTION_FAILURE_TIMED_OUT);
                             }
 
                         }
@@ -588,13 +606,14 @@
         if (userState.mService != null) {
             try {
                 userState.mService.cancelAttentionCheck(
-                        userState.mCurrentAttentionCheckRequestCode);
+                        userState.mCurrentAttentionCheck.mIAttentionCallback);
             } catch (RemoteException e) {
                 Slog.e(LOG_TAG, "Unable to cancel attention check");
             }
 
             if (userState.mPendingAttentionCheck != null) {
                 userState.mPendingAttentionCheck.cancel(failureCode);
+                userState.mPendingAttentionCheck = null;
             }
         }
     }
diff --git a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
index 09badec..e570ef1e 100644
--- a/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
+++ b/services/core/java/com/android/server/connectivity/TcpKeepaliveController.java
@@ -23,7 +23,10 @@
 import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
 import static android.system.OsConstants.ENOPROTOOPT;
 import static android.system.OsConstants.FIONREAD;
+import static android.system.OsConstants.IPPROTO_IP;
 import static android.system.OsConstants.IPPROTO_TCP;
+import static android.system.OsConstants.IP_TOS;
+import static android.system.OsConstants.IP_TTL;
 import static android.system.OsConstants.TIOCOUTQ;
 
 import android.annotation.NonNull;
@@ -193,6 +196,12 @@
             trw = NetworkUtils.getTcpRepairWindow(fd);
             tcpDetails.rcvWnd = trw.rcvWnd;
             tcpDetails.rcvWndScale = trw.rcvWndScale;
+            if (tcpDetails.srcAddress.length == 4 /* V4 address length */) {
+                // Query TOS.
+                tcpDetails.tos = Os.getsockoptInt(fd, IPPROTO_IP, IP_TOS);
+                // Query TTL.
+                tcpDetails.ttl = Os.getsockoptInt(fd, IPPROTO_IP, IP_TTL);
+            }
         } catch (ErrnoException e) {
             Log.e(TAG, "Exception reading TCP state from socket", e);
             if (e.errno == ENOPROTOOPT) {
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index ed420b7..45505c7 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -26,7 +26,6 @@
 
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
 import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_NIGHT_DISPLAY;
-import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION;
 
 import android.Manifest;
 import android.animation.Animator;
@@ -88,19 +87,13 @@
 import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeParseException;
-import java.util.Arrays;
 
 /**
  * Controls the display's color transforms.
  */
 public final class ColorDisplayService extends SystemService {
 
-    private static final String TAG = "ColorDisplayService";
-
-    /**
-     * The transition time, in milliseconds, for Night Display to turn on/off.
-     */
-    private static final long TRANSITION_DURATION = 3000L;
+    static final String TAG = "ColorDisplayService";
 
     /**
      * The identity matrix, used if one of the given matrices is {@code null}.
@@ -111,6 +104,11 @@
         Matrix.setIdentityM(MATRIX_IDENTITY, 0);
     }
 
+    /**
+     * The transition time, in milliseconds, for Night Display to turn on/off.
+     */
+    private static final long TRANSITION_DURATION = 3000L;
+
     private static final int MSG_APPLY_NIGHT_DISPLAY_IMMEDIATE = 0;
     private static final int MSG_APPLY_NIGHT_DISPLAY_ANIMATED = 1;
     private static final int MSG_APPLY_GLOBAL_SATURATION = 2;
@@ -133,59 +131,8 @@
     final DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController =
             new DisplayWhiteBalanceTintController();
 
-    private final TintController mGlobalSaturationTintController = new TintController() {
-
-        private float[] mMatrixGlobalSaturation = new float[16];
-
-        @Override
-        public void setUp(Context context, boolean needsLinear) {
-        }
-
-        @Override
-        public float[] getMatrix() {
-            return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length);
-        }
-
-        @Override
-        public void setMatrix(int saturationLevel) {
-            if (saturationLevel < 0) {
-                saturationLevel = 0;
-            } else if (saturationLevel > 100) {
-                saturationLevel = 100;
-            }
-            Slog.d(TAG, "Setting saturation level: " + saturationLevel);
-
-            if (saturationLevel == 100) {
-                setActivated(false);
-                Matrix.setIdentityM(mMatrixGlobalSaturation, 0);
-            } else {
-                setActivated(true);
-                float saturation = saturationLevel * 0.1f;
-                float desaturation = 1.0f - saturation;
-                float[] luminance = {0.231f * desaturation, 0.715f * desaturation,
-                        0.072f * desaturation};
-                mMatrixGlobalSaturation[0] = luminance[0] + saturation;
-                mMatrixGlobalSaturation[1] = luminance[0];
-                mMatrixGlobalSaturation[2] = luminance[0];
-                mMatrixGlobalSaturation[4] = luminance[1];
-                mMatrixGlobalSaturation[5] = luminance[1] + saturation;
-                mMatrixGlobalSaturation[6] = luminance[1];
-                mMatrixGlobalSaturation[8] = luminance[2];
-                mMatrixGlobalSaturation[9] = luminance[2];
-                mMatrixGlobalSaturation[10] = luminance[2] + saturation;
-            }
-        }
-
-        @Override
-        public int getLevel() {
-            return LEVEL_COLOR_MATRIX_SATURATION;
-        }
-
-        @Override
-        public boolean isAvailable(Context context) {
-            return ColorDisplayManager.isColorTransformAccelerated(context);
-        }
-    };
+    private final TintController mGlobalSaturationTintController =
+            new GlobalSaturationTintController();
 
     /**
      * Matrix and offset used for converting color to grayscale.
@@ -1084,82 +1031,6 @@
         }
     }
 
-    private abstract static class TintController {
-
-        private ValueAnimator mAnimator;
-        private Boolean mIsActivated;
-
-        public ValueAnimator getAnimator() {
-            return mAnimator;
-        }
-
-        public void setAnimator(ValueAnimator animator) {
-            mAnimator = animator;
-        }
-
-        /**
-         * Cancel the animator if it's still running.
-         */
-        public void cancelAnimator() {
-            if (mAnimator != null) {
-                mAnimator.cancel();
-            }
-        }
-
-        /**
-         * End the animator if it's still running, jumping to the end state.
-         */
-        public void endAnimator() {
-            if (mAnimator != null) {
-                mAnimator.end();
-                mAnimator = null;
-            }
-        }
-
-        public void setActivated(Boolean isActivated) {
-            mIsActivated = isActivated;
-        }
-
-        public boolean isActivated() {
-            return mIsActivated != null && mIsActivated;
-        }
-
-        public boolean isActivatedStateNotSet() {
-            return mIsActivated == null;
-        }
-
-        /**
-         * Dump debug information.
-         */
-        public void dump(PrintWriter pw) {
-        }
-
-        /**
-         * Set up any constants needed for computing the matrix.
-         */
-        public abstract void setUp(Context context, boolean needsLinear);
-
-        /**
-         * Sets the 4x4 matrix to apply.
-         */
-        public abstract void setMatrix(int value);
-
-        /**
-         * Get the 4x4 matrix to apply.
-         */
-        public abstract float[] getMatrix();
-
-        /**
-         * Get the color transform level to apply the matrix.
-         */
-        public abstract int getLevel();
-
-        /**
-         * Returns whether or not this transform type is available on this device.
-         */
-        public abstract boolean isAvailable(Context context);
-    }
-
     private final class NightDisplayTintController extends TintController {
 
         private final float[] mMatrix = new float[16];
diff --git a/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java
new file mode 100644
index 0000000..71fdcc7
--- /dev/null
+++ b/services/core/java/com/android/server/display/color/GlobalSaturationTintController.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.color;
+
+import static com.android.server.display.color.DisplayTransformManager.LEVEL_COLOR_MATRIX_SATURATION;
+
+import android.content.Context;
+import android.hardware.display.ColorDisplayManager;
+import android.opengl.Matrix;
+import android.util.Slog;
+
+import java.util.Arrays;
+
+/** Control the color transform for global device saturation. */
+public class GlobalSaturationTintController extends TintController {
+
+    private final float[] mMatrixGlobalSaturation = new float[16];
+
+    @Override
+    public void setUp(Context context, boolean needsLinear) {
+    }
+
+    @Override
+    public float[] getMatrix() {
+        return Arrays.copyOf(mMatrixGlobalSaturation, mMatrixGlobalSaturation.length);
+    }
+
+    @Override
+    public void setMatrix(int saturationLevel) {
+        if (saturationLevel < 0) {
+            saturationLevel = 0;
+        } else if (saturationLevel > 100) {
+            saturationLevel = 100;
+        }
+        Slog.d(ColorDisplayService.TAG, "Setting saturation level: " + saturationLevel);
+
+        if (saturationLevel == 100) {
+            setActivated(false);
+            Matrix.setIdentityM(mMatrixGlobalSaturation, 0);
+        } else {
+            setActivated(true);
+            float saturation = saturationLevel * 0.01f;
+            float desaturation = 1.0f - saturation;
+            float[] luminance = {0.231f * desaturation, 0.715f * desaturation,
+                    0.072f * desaturation};
+            mMatrixGlobalSaturation[0] = luminance[0] + saturation;
+            mMatrixGlobalSaturation[1] = luminance[0];
+            mMatrixGlobalSaturation[2] = luminance[0];
+            mMatrixGlobalSaturation[4] = luminance[1];
+            mMatrixGlobalSaturation[5] = luminance[1] + saturation;
+            mMatrixGlobalSaturation[6] = luminance[1];
+            mMatrixGlobalSaturation[8] = luminance[2];
+            mMatrixGlobalSaturation[9] = luminance[2];
+            mMatrixGlobalSaturation[10] = luminance[2] + saturation;
+        }
+    }
+
+    @Override
+    public int getLevel() {
+        return LEVEL_COLOR_MATRIX_SATURATION;
+    }
+
+    @Override
+    public boolean isAvailable(Context context) {
+        return ColorDisplayManager.isColorTransformAccelerated(context);
+    }
+}
diff --git a/services/core/java/com/android/server/display/color/TintController.java b/services/core/java/com/android/server/display/color/TintController.java
new file mode 100644
index 0000000..b291c64
--- /dev/null
+++ b/services/core/java/com/android/server/display/color/TintController.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.color;
+
+import android.animation.ValueAnimator;
+import android.content.Context;
+
+import java.io.PrintWriter;
+
+abstract class TintController {
+
+    private ValueAnimator mAnimator;
+    private Boolean mIsActivated;
+
+    public ValueAnimator getAnimator() {
+        return mAnimator;
+    }
+
+    public void setAnimator(ValueAnimator animator) {
+        mAnimator = animator;
+    }
+
+    /**
+     * Cancel the animator if it's still running.
+     */
+    public void cancelAnimator() {
+        if (mAnimator != null) {
+            mAnimator.cancel();
+        }
+    }
+
+    /**
+     * End the animator if it's still running, jumping to the end state.
+     */
+    public void endAnimator() {
+        if (mAnimator != null) {
+            mAnimator.end();
+            mAnimator = null;
+        }
+    }
+
+    public void setActivated(Boolean isActivated) {
+        mIsActivated = isActivated;
+    }
+
+    public boolean isActivated() {
+        return mIsActivated != null && mIsActivated;
+    }
+
+    public boolean isActivatedStateNotSet() {
+        return mIsActivated == null;
+    }
+
+    /**
+     * Dump debug information.
+     */
+    public void dump(PrintWriter pw) {
+    }
+
+    /**
+     * Set up any constants needed for computing the matrix.
+     */
+    public abstract void setUp(Context context, boolean needsLinear);
+
+    /**
+     * Sets the 4x4 matrix to apply.
+     */
+    public abstract void setMatrix(int value);
+
+    /**
+     * Get the 4x4 matrix to apply.
+     */
+    public abstract float[] getMatrix();
+
+    /**
+     * Get the color transform level to apply the matrix.
+     */
+    public abstract int getLevel();
+
+    /**
+     * Returns whether or not this transform type is available on this device.
+     */
+    public abstract boolean isAvailable(Context context);
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
new file mode 100644
index 0000000..d284c60
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderProxy.java
@@ -0,0 +1,341 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.media.IMediaRoute2Callback;
+import android.media.IMediaRoute2Provider;
+import android.media.MediaRoute2ProviderService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+
+/**
+ * Maintains a connection to a particular media route provider service.
+ */
+final class MediaRoute2ProviderProxy implements ServiceConnection {
+    private static final String TAG = "MediaRoute2ProviderProxy";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    private final ComponentName mComponentName;
+    private final int mUserId;
+    private final Handler mHandler;
+
+    private Callback mCallback;
+
+    // Selected Route info
+    public int mSelectedUid;
+    public String mSelectedRouteId;
+
+    // Connection state
+    private boolean mRunning;
+    private boolean mBound;
+    private Connection mActiveConnection;
+    private boolean mConnectionReady;
+
+    MediaRoute2ProviderProxy(Context context, ComponentName componentName, int userId) {
+        mContext = context;
+        mComponentName = componentName;
+        mUserId = userId;
+        mHandler = new Handler();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Proxy");
+        pw.println(prefix + "  mUserId=" + mUserId);
+        pw.println(prefix + "  mRunning=" + mRunning);
+        pw.println(prefix + "  mBound=" + mBound);
+        pw.println(prefix + "  mActiveConnection=" + mActiveConnection);
+        pw.println(prefix + "  mConnectionReady=" + mConnectionReady);
+    }
+
+    public void setCallback(Callback callback) {
+        mCallback = callback;
+    }
+
+    public void setSelectedRoute(int uid, String routeId) {
+        if (mConnectionReady) {
+            mActiveConnection.selectRoute(uid, routeId);
+            updateBinding();
+        }
+    }
+
+    public boolean hasComponentName(String packageName, String className) {
+        return mComponentName.getPackageName().equals(packageName)
+                && mComponentName.getClassName().equals(className);
+    }
+
+    public String getFlattenedComponentName() {
+        return mComponentName.flattenToShortString();
+    }
+
+    public void start() {
+        if (!mRunning) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Starting");
+            }
+
+            mRunning = true;
+            updateBinding();
+        }
+    }
+
+    public void stop() {
+        if (mRunning) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Stopping");
+            }
+
+            mRunning = false;
+            updateBinding();
+        }
+    }
+
+    public void rebindIfDisconnected() {
+        if (mActiveConnection == null && shouldBind()) {
+            unbind();
+            bind();
+        }
+    }
+
+    private void updateBinding() {
+        if (shouldBind()) {
+            bind();
+        } else {
+            unbind();
+        }
+    }
+
+    private boolean shouldBind() {
+        //TODO: binding could be delayed until it's necessary.
+        if (mRunning) {
+            return true;
+        }
+        return false;
+    }
+
+    private void bind() {
+        if (!mBound) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Binding");
+            }
+
+            Intent service = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
+            service.setComponent(mComponentName);
+            try {
+                mBound = mContext.bindServiceAsUser(service, this,
+                        Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+                        new UserHandle(mUserId));
+                if (!mBound && DEBUG) {
+                    Slog.d(TAG, this + ": Bind failed");
+                }
+            } catch (SecurityException ex) {
+                if (DEBUG) {
+                    Slog.d(TAG, this + ": Bind failed", ex);
+                }
+            }
+        }
+    }
+
+    private void unbind() {
+        if (mBound) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Unbinding");
+            }
+
+            mBound = false;
+            disconnect();
+            mContext.unbindService(this);
+        }
+    }
+
+    @Override
+    public void onServiceConnected(ComponentName name, IBinder service) {
+        if (DEBUG) {
+            Slog.d(TAG, this + ": Connected");
+        }
+
+        if (mBound) {
+            disconnect();
+
+            IMediaRoute2Provider provider = IMediaRoute2Provider.Stub.asInterface(service);
+            if (provider != null) {
+                Connection connection = new Connection(provider);
+                if (connection.register()) {
+                    mActiveConnection = connection;
+                } else {
+                    if (DEBUG) {
+                        Slog.d(TAG, this + ": Registration failed");
+                    }
+                }
+            } else {
+                Slog.e(TAG, this + ": Service returned invalid remote display provider binder");
+            }
+        }
+    }
+
+    @Override
+    public void onServiceDisconnected(ComponentName name) {
+        if (DEBUG) {
+            Slog.d(TAG, this + ": Service disconnected");
+        }
+        disconnect();
+    }
+
+    private void onConnectionReady(Connection connection) {
+        if (mActiveConnection == connection) {
+            mConnectionReady = true;
+        }
+    }
+
+    private void onConnectionDied(Connection connection) {
+        if (mActiveConnection == connection) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": Service connection died");
+            }
+            disconnect();
+        }
+    }
+
+    private void onRouteSelected(Connection connection, int uid, String routeId) {
+        mSelectedUid = uid;
+        mSelectedRouteId = routeId;
+
+        if (mActiveConnection == connection) {
+            if (DEBUG) {
+                Slog.d(TAG, this + ": State changed ");
+            }
+            mHandler.post(mStateChanged);
+        }
+    }
+
+    private void disconnect() {
+        if (mActiveConnection != null) {
+            mConnectionReady = false;
+            mActiveConnection.dispose();
+            mActiveConnection = null;
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "Service connection " + mComponentName.flattenToShortString();
+    }
+
+    private final Runnable mStateChanged = new Runnable() {
+        @Override
+        public void run() {
+            if (mCallback != null) {
+                mCallback.onProviderStateChanged(MediaRoute2ProviderProxy.this);
+            }
+        }
+    };
+
+    public interface Callback {
+        void onProviderStateChanged(MediaRoute2ProviderProxy provider);
+    }
+
+    private final class Connection implements DeathRecipient {
+        private final IMediaRoute2Provider mProvider;
+        private final ProviderCallback mCallback;
+
+        Connection(IMediaRoute2Provider provider) {
+            mProvider = provider;
+            mCallback = new ProviderCallback(this);
+        }
+
+        public boolean register() {
+            try {
+                mProvider.asBinder().linkToDeath(this, 0);
+                mProvider.setCallback(mCallback);
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        onConnectionReady(Connection.this);
+                    }
+                });
+                return true;
+            } catch (RemoteException ex) {
+                binderDied();
+            }
+            return false;
+        }
+
+        public void dispose() {
+            mProvider.asBinder().unlinkToDeath(this, 0);
+            mCallback.dispose();
+        }
+
+        public void selectRoute(int uid, String id) {
+            try {
+                mProvider.selectRoute(uid, id);
+            } catch (RemoteException ex) {
+                Slog.e(TAG, "Failed to deliver request to set discovery mode.", ex);
+            }
+        }
+
+        @Override
+        public void binderDied() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onConnectionDied(Connection.this);
+                }
+            });
+        }
+
+        void postRouteSelected(int uid, String routeId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    onRouteSelected(Connection.this, uid, routeId);
+                }
+            });
+        }
+    }
+
+    private static final class ProviderCallback extends IMediaRoute2Callback.Stub  {
+        private final WeakReference<Connection> mConnectionRef;
+
+        ProviderCallback(Connection connection) {
+            mConnectionRef = new WeakReference<Connection>(connection);
+        }
+
+        public void dispose() {
+            mConnectionRef.clear();
+        }
+
+        @Override
+        public void onRouteSelected(int uid, String routeId) throws RemoteException {
+            Connection connection = mConnectionRef.get();
+            if (connection != null) {
+                connection.postRouteSelected(uid, routeId);
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
new file mode 100644
index 0000000..08d8c58
--- /dev/null
+++ b/services/core/java/com/android/server/media/MediaRoute2ProviderWatcher.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.media;
+
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.media.MediaRoute2ProviderService;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Slog;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ */
+final class MediaRoute2ProviderWatcher {
+    private static final String TAG = "MediaRouteProvider";  // max. 23 chars
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final Context mContext;
+    private final Callback mCallback;
+    private final Handler mHandler;
+    private final int mUserId;
+    private final PackageManager mPackageManager;
+
+    private final ArrayList<MediaRoute2ProviderProxy> mProviders = new ArrayList<>();
+    private boolean mRunning;
+
+    MediaRoute2ProviderWatcher(Context context,
+            Callback callback, Handler handler, int userId) {
+        mContext = context;
+        mCallback = callback;
+        mHandler = handler;
+        mUserId = userId;
+        mPackageManager = context.getPackageManager();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        pw.println(prefix + "Watcher");
+        pw.println(prefix + "  mUserId=" + mUserId);
+        pw.println(prefix + "  mRunning=" + mRunning);
+        pw.println(prefix + "  mProviders.size()=" + mProviders.size());
+    }
+
+    public void start() {
+        if (!mRunning) {
+            mRunning = true;
+
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(Intent.ACTION_PACKAGE_ADDED);
+            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+            filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
+            filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+            filter.addDataScheme("package");
+            mContext.registerReceiverAsUser(mScanPackagesReceiver,
+                    new UserHandle(mUserId), filter, null, mHandler);
+
+            // Scan packages.
+            // Also has the side-effect of restarting providers if needed.
+            mHandler.post(mScanPackagesRunnable);
+        }
+    }
+
+    public void stop() {
+        if (mRunning) {
+            mRunning = false;
+
+            mContext.unregisterReceiver(mScanPackagesReceiver);
+            mHandler.removeCallbacks(mScanPackagesRunnable);
+
+            // Stop all providers.
+            for (int i = mProviders.size() - 1; i >= 0; i--) {
+                mProviders.get(i).stop();
+            }
+        }
+    }
+
+    private void scanPackages() {
+        if (!mRunning) {
+            return;
+        }
+
+        // Add providers for all new services.
+        // Reorder the list so that providers left at the end will be the ones to remove.
+        int targetIndex = 0;
+        Intent intent = new Intent(MediaRoute2ProviderService.SERVICE_INTERFACE);
+        for (ResolveInfo resolveInfo : mPackageManager.queryIntentServicesAsUser(
+                intent, 0, mUserId)) {
+            ServiceInfo serviceInfo = resolveInfo.serviceInfo;
+            if (serviceInfo != null) {
+                int sourceIndex = findProvider(serviceInfo.packageName, serviceInfo.name);
+                if (sourceIndex < 0) {
+                    MediaRoute2ProviderProxy provider =
+                            new MediaRoute2ProviderProxy(mContext,
+                            new ComponentName(serviceInfo.packageName, serviceInfo.name),
+                            mUserId);
+                    provider.start();
+                    mProviders.add(targetIndex++, provider);
+                    mCallback.addProvider(provider);
+                } else if (sourceIndex >= targetIndex) {
+                    MediaRoute2ProviderProxy provider = mProviders.get(sourceIndex);
+                    provider.start(); // restart the provider if needed
+                    provider.rebindIfDisconnected();
+                    Collections.swap(mProviders, sourceIndex, targetIndex++);
+                }
+            }
+        }
+
+        // Remove providers for missing services.
+        if (targetIndex < mProviders.size()) {
+            for (int i = mProviders.size() - 1; i >= targetIndex; i--) {
+                MediaRoute2ProviderProxy provider = mProviders.get(i);
+                mCallback.removeProvider(provider);
+                mProviders.remove(provider);
+                provider.stop();
+            }
+        }
+    }
+
+    private int findProvider(String packageName, String className) {
+        int count = mProviders.size();
+        for (int i = 0; i < count; i++) {
+            MediaRoute2ProviderProxy provider = mProviders.get(i);
+            if (provider.hasComponentName(packageName, className)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    private final BroadcastReceiver mScanPackagesReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Slog.d(TAG, "Received package manager broadcast: " + intent);
+            }
+            scanPackages();
+        }
+    };
+
+    private final Runnable mScanPackagesRunnable = new Runnable() {
+        @Override
+        public void run() {
+            scanPackages();
+        }
+    };
+
+    public interface Callback {
+        void addProvider(MediaRoute2ProviderProxy provider);
+        void removeProvider(MediaRoute2ProviderProxy provider);
+    }
+}
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 3eb7321..f822e82 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -16,14 +16,10 @@
 
 package com.android.server.media;
 
-import com.android.internal.util.DumpUtils;
-import com.android.server.Watchdog;
-
 import android.annotation.NonNull;
 import android.app.ActivityManager;
 import android.bluetooth.BluetoothA2dp;
 import android.bluetooth.BluetoothDevice;
-import android.bluetooth.BluetoothProfile;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -34,6 +30,7 @@
 import android.media.AudioSystem;
 import android.media.IAudioRoutesObserver;
 import android.media.IAudioService;
+import android.media.IMediaRouter2ManagerClient;
 import android.media.IMediaRouterClient;
 import android.media.IMediaRouterService;
 import android.media.MediaRouter;
@@ -53,10 +50,14 @@
 import android.util.ArrayMap;
 import android.util.IntArray;
 import android.util.Log;
+import android.util.Pair;
 import android.util.Slog;
 import android.util.SparseArray;
 import android.util.TimeUtils;
 
+import com.android.internal.util.DumpUtils;
+import com.android.server.Watchdog;
+
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -97,6 +98,7 @@
     private final Object mLock = new Object();
     private final SparseArray<UserRecord> mUserRecords = new SparseArray<>();
     private final ArrayMap<IBinder, ClientRecord> mAllClientRecords = new ArrayMap<>();
+    private final ArrayMap<IBinder, ManagerRecord> mAllManagerRecords = new ArrayMap<>();
     private int mCurrentUserId = -1;
     private final IAudioService mAudioService;
     private final AudioPlayerStateMonitor mAudioPlayerStateMonitor;
@@ -306,6 +308,22 @@
 
     // Binder call
     @Override
+    public void setControlCategories(IMediaRouterClient client, List<String> categories) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                setControlCategoriesLocked(client, categories);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
     public void setDiscoveryRequest(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         if (client == null) {
@@ -404,6 +422,65 @@
         }
     }
 
+    // Binder call
+    @Override
+    public void registerManagerAsUser(IMediaRouter2ManagerClient client,
+            String packageName, int userId) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+        //TODO: should check permission
+        final boolean trusted = true;
+
+        final int uid = Binder.getCallingUid();
+        if (!validatePackageName(uid, packageName)) {
+            throw new SecurityException("packageName must match the calling uid");
+        }
+
+        final int pid = Binder.getCallingPid();
+        final int resolvedUserId = ActivityManager.handleIncomingUser(pid, uid, userId,
+                false /*allowAll*/, true /*requireFull*/, "registerManagerAsUser", packageName);
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                registerManagerLocked(client, uid, pid, packageName, resolvedUserId, trusted);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
+    public void unregisterManager(IMediaRouter2ManagerClient client) {
+        if (client == null) {
+            throw new IllegalArgumentException("client must not be null");
+        }
+
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                unregisterManagerLocked(client, false);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
+    // Binder call
+    @Override
+    public void setRemoteRoute(IMediaRouter2ManagerClient client,
+            int uid, String routeId, boolean explicit) {
+        final long token = Binder.clearCallingIdentity();
+        try {
+            synchronized (mLock) {
+                setRemoteRouteLocked(client, uid, routeId, explicit);
+            }
+        } finally {
+            Binder.restoreCallingIdentity(token);
+        }
+    }
+
     void restoreBluetoothA2dp() {
         try {
             boolean a2dpOn;
@@ -475,6 +552,12 @@
         }
     }
 
+    void clientDied(ManagerRecord managerRecord) {
+        synchronized (mLock) {
+            unregisterManagerLocked(managerRecord.mClient, true);
+        }
+    }
+
     private void registerClientLocked(IMediaRouterClient client,
             int uid, int pid, String packageName, int userId, boolean trusted) {
         final IBinder binder = client.asBinder();
@@ -522,6 +605,17 @@
         return null;
     }
 
+    private void setControlCategoriesLocked(IMediaRouterClient client, List<String> categories) {
+        final IBinder binder = client.asBinder();
+        ClientRecord clientRecord = mAllClientRecords.get(binder);
+
+        if (clientRecord != null) {
+            clientRecord.mControlCategories = categories;
+            clientRecord.mUserRecord.mHandler.obtainMessage(
+                    UserHandler.MSG_UPDATE_CLIENT_USAGE, clientRecord).sendToTarget();
+        }
+    }
+
     private void setDiscoveryRequestLocked(IMediaRouterClient client,
             int routeTypes, boolean activeScan) {
         final IBinder binder = client.asBinder();
@@ -575,6 +669,63 @@
         }
     }
 
+    private void registerManagerLocked(IMediaRouter2ManagerClient client,
+            int uid, int pid, String packageName, int userId, boolean trusted) {
+        final IBinder binder = client.asBinder();
+        ManagerRecord managerRecord = mAllManagerRecords.get(binder);
+        if (managerRecord == null) {
+            boolean newUser = false;
+            UserRecord userRecord = mUserRecords.get(userId);
+            if (userRecord == null) {
+                userRecord = new UserRecord(userId);
+                newUser = true;
+            }
+            managerRecord = new ManagerRecord(userRecord, client, uid, pid, packageName, trusted);
+            try {
+                binder.linkToDeath(managerRecord, 0);
+            } catch (RemoteException ex) {
+                throw new RuntimeException("Media router client died prematurely.", ex);
+            }
+
+            if (newUser) {
+                mUserRecords.put(userId, userRecord);
+                initializeUserLocked(userRecord);
+            }
+
+            userRecord.mManagerRecords.add(managerRecord);
+            mAllManagerRecords.put(binder, managerRecord);
+
+            // send client usage to manager
+            final int clientCount = userRecord.mClientRecords.size();
+            for (int i = 0; i < clientCount; i++) {
+                userRecord.mHandler.obtainMessage(UserHandler.MSG_UPDATE_CLIENT_USAGE,
+                        userRecord.mClientRecords.get(i)).sendToTarget();
+            }
+        }
+    }
+
+    private void unregisterManagerLocked(IMediaRouter2ManagerClient client, boolean died) {
+        ManagerRecord clientRecord = mAllManagerRecords.remove(client.asBinder());
+        if (clientRecord != null) {
+            UserRecord userRecord = clientRecord.mUserRecord;
+            userRecord.mManagerRecords.remove(clientRecord);
+            clientRecord.dispose();
+            disposeUserIfNeededLocked(userRecord); // since client removed from user
+        }
+    }
+
+    private void setRemoteRouteLocked(IMediaRouter2ManagerClient client,
+            int uid, String routeId, boolean explicit) {
+        ManagerRecord managerRecord = mAllManagerRecords.get(client.asBinder());
+        if (managerRecord != null) {
+            if (explicit && managerRecord.mTrusted) {
+                Pair<Integer, String> obj = new Pair<>(uid, routeId);
+                managerRecord.mUserRecord.mHandler.obtainMessage(
+                        UserHandler.MSG_SELECT_REMOTE_ROUTE, obj).sendToTarget();
+            }
+        }
+    }
+
     private void requestSetVolumeLocked(IMediaRouterClient client,
             String routeId, int volume) {
         final IBinder binder = client.asBinder();
@@ -667,6 +818,46 @@
         }
     }
 
+    final class ManagerRecord implements DeathRecipient {
+        public final UserRecord mUserRecord;
+        public final IMediaRouter2ManagerClient mClient;
+        public final int mUid;
+        public final int mPid;
+        public final String mPackageName;
+        public final boolean mTrusted;
+
+        ManagerRecord(UserRecord userRecord, IMediaRouter2ManagerClient client,
+                int uid, int pid, String packageName, boolean trusted) {
+            mUserRecord = userRecord;
+            mClient = client;
+            mUid = uid;
+            mPid = pid;
+            mPackageName = packageName;
+            mTrusted = trusted;
+        }
+
+        public void dispose() {
+            mClient.asBinder().unlinkToDeath(this, 0);
+        }
+
+        @Override
+        public void binderDied() {
+            clientDied(this);
+        }
+
+        public void dump(PrintWriter pw, String prefix) {
+            pw.println(prefix + this);
+
+            final String indent = prefix + "  ";
+            pw.println(indent + "mTrusted=" + mTrusted);
+        }
+
+        @Override
+        public String toString() {
+            return "Client " + mPackageName + " (pid " + mPid + ")";
+        }
+    }
+
     /**
      * Information about a particular client of the media router.
      * The contents of this object is guarded by mLock.
@@ -678,6 +869,7 @@
         public final int mPid;
         public final String mPackageName;
         public final boolean mTrusted;
+        public List<String> mControlCategories;
 
         public int mRouteTypes;
         public boolean mActiveScan;
@@ -728,7 +920,8 @@
      */
     final class UserRecord {
         public final int mUserId;
-        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<ClientRecord>();
+        public final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
+        public final ArrayList<ManagerRecord> mManagerRecords = new ArrayList<>();
         public final UserHandler mHandler;
         public MediaRouterClientState mRouterState;
 
@@ -783,7 +976,9 @@
      */
     static final class UserHandler extends Handler
             implements RemoteDisplayProviderWatcher.Callback,
-            RemoteDisplayProviderProxy.Callback {
+            RemoteDisplayProviderProxy.Callback,
+            MediaRoute2ProviderWatcher.Callback,
+            MediaRoute2ProviderProxy.Callback {
         public static final int MSG_START = 1;
         public static final int MSG_STOP = 2;
         public static final int MSG_UPDATE_DISCOVERY_REQUEST = 3;
@@ -794,6 +989,9 @@
         private static final int MSG_UPDATE_CLIENT_STATE = 8;
         private static final int MSG_CONNECTION_TIMED_OUT = 9;
 
+        private static final int MSG_SELECT_REMOTE_ROUTE = 10;
+        private static final int MSG_UPDATE_CLIENT_USAGE = 11;
+
         private static final int TIMEOUT_REASON_NOT_AVAILABLE = 1;
         private static final int TIMEOUT_REASON_CONNECTION_LOST = 2;
         private static final int TIMEOUT_REASON_WAITING_FOR_CONNECTING = 3;
@@ -809,11 +1007,17 @@
         private final MediaRouterService mService;
         private final UserRecord mUserRecord;
         private final RemoteDisplayProviderWatcher mWatcher;
+        private final MediaRoute2ProviderWatcher mMediaWatcher;
+
         private final ArrayList<ProviderRecord> mProviderRecords =
                 new ArrayList<ProviderRecord>();
         private final ArrayList<IMediaRouterClient> mTempClients =
                 new ArrayList<IMediaRouterClient>();
 
+        private final ArrayList<MediaRoute2ProviderProxy> mMediaProviders =
+                new ArrayList<>();
+        private final ArrayList<IMediaRouter2ManagerClient> mTempManagers = new ArrayList<>();
+
         private boolean mRunning;
         private int mDiscoveryMode = RemoteDisplayState.DISCOVERY_MODE_NONE;
         private RouteRecord mSelectedRouteRecord;
@@ -828,6 +1032,8 @@
             mUserRecord = userRecord;
             mWatcher = new RemoteDisplayProviderWatcher(service.mContext, this,
                     this, mUserRecord.mUserId);
+            mMediaWatcher = new MediaRoute2ProviderWatcher(service.mContext, this,
+                    this, mUserRecord.mUserId);
         }
 
         @Override
@@ -869,6 +1075,15 @@
                     connectionTimedOut();
                     break;
                 }
+                case MSG_SELECT_REMOTE_ROUTE: {
+                    Pair<Integer, String> obj = (Pair<Integer, String>) msg.obj;
+                    selectRemoteRoute(obj.first, obj.second);
+                    break;
+                }
+                case MSG_UPDATE_CLIENT_USAGE: {
+                    updateClientUsage((ClientRecord) msg.obj);
+                    break;
+                }
             }
         }
 
@@ -900,6 +1115,7 @@
             if (!mRunning) {
                 mRunning = true;
                 mWatcher.start(); // also starts all providers
+                mMediaWatcher.start();
             }
         }
 
@@ -908,6 +1124,7 @@
                 mRunning = false;
                 unselectSelectedRoute();
                 mWatcher.stop(); // also stops all providers
+                mMediaWatcher.stop();
             }
         }
 
@@ -1039,6 +1256,26 @@
             }
         }
 
+        @Override
+        public void addProvider(MediaRoute2ProviderProxy provider) {
+            provider.setCallback(this);
+            mMediaProviders.add(provider);
+        }
+
+        @Override
+        public void removeProvider(MediaRoute2ProviderProxy provider) {
+            mMediaProviders.remove(provider);
+        }
+
+        @Override
+        public void onProviderStateChanged(MediaRoute2ProviderProxy provider) {
+            updateProvider(provider);
+        }
+
+        private void updateProvider(MediaRoute2ProviderProxy provider) {
+            scheduleUpdateClientState();
+        }
+
         /**
          * This function is called whenever the state of the selected route may have changed.
          * It checks the state and updates timeouts or unselects the route as appropriate.
@@ -1149,6 +1386,17 @@
             unselectSelectedRoute();
         }
 
+        private void selectRemoteRoute(int uid, String routeId) {
+            if (routeId != null) {
+                final int providerCount = mMediaProviders.size();
+
+                //TODO: should find proper provider (currently assumes a single provider)
+                for (int i = 0; i < providerCount; ++i) {
+                    mMediaProviders.get(i).setSelectedRoute(uid, routeId);
+                }
+            }
+        }
+
         private void scheduleUpdateClientState() {
             if (!mClientStateUpdateScheduled) {
                 mClientStateUpdateScheduled = true;
@@ -1166,6 +1414,15 @@
                 mProviderRecords.get(i).appendClientState(routerState);
             }
 
+            //TODO: send provider info
+            int selectedUid = 0;
+            String selectedRouteId = null;
+            final int mediaCount = mMediaProviders.size();
+            for (int i = 0; i < mediaCount; i++) {
+                selectedUid = mMediaProviders.get(i).mSelectedUid;
+                selectedRouteId = mMediaProviders.get(i).mSelectedRouteId;
+            }
+
             try {
                 synchronized (mService.mLock) {
                     // Update the UserRecord.
@@ -1176,6 +1433,11 @@
                     for (int i = 0; i < count; i++) {
                         mTempClients.add(mUserRecord.mClientRecords.get(i).mClient);
                     }
+
+                    final int count2 = mUserRecord.mManagerRecords.size();
+                    for (int i = 0; i < count2; i++) {
+                        mTempManagers.add(mUserRecord.mManagerRecords.get(i).mClient);
+                    }
                 }
 
                 // Notify all clients (outside of the lock).
@@ -1187,9 +1449,39 @@
                         Slog.w(TAG, "Failed to call onStateChanged. Client probably died.");
                     }
                 }
+                //TODO: Call proper callbacks when provider descriptor is implemented.
+                final int count2 = mTempManagers.size();
+                for (int i = 0; i < count2; i++) {
+                    try {
+                        mTempManagers.get(i).onRouteSelected(selectedUid, selectedRouteId);
+                    } catch (RemoteException ex) {
+                        Slog.w(TAG, "Failed to call onStateChanged. Manager probably died.", ex);
+                    }
+                }
             } finally {
                 // Clear the list in preparation for the next time.
                 mTempClients.clear();
+                mTempManagers.clear();
+            }
+        }
+
+        private void updateClientUsage(ClientRecord clientRecord) {
+            List<IMediaRouter2ManagerClient> managers = new ArrayList<>();
+            synchronized (mService.mLock) {
+                final int count = mUserRecord.mManagerRecords.size();
+                for (int i = 0; i < count; i++) {
+                    managers.add(mUserRecord.mManagerRecords.get(i).mClient);
+                }
+            }
+            final int count = managers.size();
+            for (int i = 0; i < count; i++) {
+                try {
+                    managers.get(i).onControlCategoriesChanged(clientRecord.mUid,
+                            clientRecord.mControlCategories);
+                } catch (RemoteException ex) {
+                    Slog.w(TAG, "Failed to call onControlCategoriesChanged. "
+                            + "Manager probably died.", ex);
+                }
             }
         }
 
@@ -1576,4 +1868,5 @@
             }
         }
     }
+
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e43fc1f..dddb7ef 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -4106,11 +4106,19 @@
         if (r == null) {
             return;
         }
-        if (mAssistants.isAdjustmentAllowed(adjustment.getKey())) {
-            if (adjustment.getSignals() != null) {
-                Bundle.setDefusable(adjustment.getSignals(), true);
-                r.addAdjustment(adjustment);
+        if (adjustment.getSignals() != null) {
+            final Bundle adjustments = adjustment.getSignals();
+            Bundle.setDefusable(adjustments, true);
+            List<String> toRemove = new ArrayList<>();
+            for (String potentialKey : adjustments.keySet()) {
+                if (!mAssistants.isAdjustmentAllowed(potentialKey)) {
+                    toRemove.add(potentialKey);
+                }
             }
+            for (String removeKey : toRemove) {
+                adjustments.remove(removeKey);
+            }
+            r.addAdjustment(adjustment);
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 18cfa4a..9b6333d 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -40,6 +40,7 @@
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManagerInternal;
+import android.content.pm.PackageParser;
 import android.content.pm.ParceledListSlice;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ShortcutInfo;
@@ -66,6 +67,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.content.PackageMonitor;
 import com.android.internal.os.BackgroundThread;
+import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.Preconditions;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -441,6 +443,44 @@
             if (isManagedProfileAdmin(user, appInfo.packageName)) {
                 return false;
             }
+            // If app does not have any components or any permissions, the app can legitimately
+            // have no icon so we do not show the synthetic activity.
+            return hasComponentsAndRequestsPermissions(appInfo.packageName);
+        }
+
+        private boolean hasComponentsAndRequestsPermissions(@NonNull String packageName) {
+            final PackageManagerInternal pmInt =
+                    LocalServices.getService(PackageManagerInternal.class);
+            final PackageParser.Package pkg = pmInt.getPackage(packageName);
+            if (pkg == null) {
+                // Should not happen, but we shouldn't be failing if it does
+                return false;
+            }
+            if (ArrayUtils.isEmpty(pkg.requestedPermissions)) {
+                return false;
+            }
+            if (!hasApplicationDeclaredActivities(pkg)
+                    && ArrayUtils.isEmpty(pkg.receivers)
+                    && ArrayUtils.isEmpty(pkg.providers)
+                    && ArrayUtils.isEmpty(pkg.services)) {
+                return false;
+            }
+            return true;
+        }
+
+        private boolean hasApplicationDeclaredActivities(@NonNull PackageParser.Package pkg) {
+            if (pkg.activities == null) {
+                return false;
+            }
+            if (ArrayUtils.isEmpty(pkg.activities)) {
+                return false;
+            }
+            // If it only contains synthetic AppDetailsActivity only, it means application does
+            // not have actual activity declared in manifest.
+            if (pkg.activities.size() == 1 && PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
+                    pkg.activities.get(0).className)) {
+                return false;
+            }
             return true;
         }
 
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 66b530f..f1d4524 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -476,6 +476,7 @@
                     mResolvedBaseFile.getAbsolutePath() : null;
             info.progress = mProgress;
             info.sealed = mSealed;
+            info.isCommitted = mCommitted;
             info.active = mActiveCount.get() > 0;
 
             info.mode = params.mode;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 73b000e..1a33b16 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -1141,11 +1141,22 @@
                     switch (userStatus) {
                         case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
                             if (!verified) {
-                                // updatedStatus is already UNDEFINED
-                                needUpdate = true;
+                                // Don't demote if sysconfig says 'always'
+                                SystemConfig systemConfig = SystemConfig.getInstance();
+                                ArraySet<String> packages = systemConfig.getLinkedApps();
+                                if (!packages.contains(packageName)) {
+                                    // updatedStatus is already UNDEFINED
+                                    needUpdate = true;
 
-                                if (DEBUG_DOMAIN_VERIFICATION) {
-                                    Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Formerly validated but now failing; demoting");
+                                    }
+                                } else {
+                                    if (DEBUG_DOMAIN_VERIFICATION) {
+                                        Slog.d(TAG, "Updating bundled package " + packageName
+                                                + " failed autoVerify, but sysconfig supersedes");
+                                    }
+                                    // leave needUpdate == false here intentionally
                                 }
                             }
                             break;
@@ -17789,6 +17800,12 @@
     @Override
     public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
         final int callingUid = Binder.getCallingUid();
+        if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
+                != PERMISSION_GRANTED) {
+            EventLog.writeEvent(0x534e4554, "128599183", -1, "");
+            throw new SecurityException(android.Manifest.permission.MANAGE_USERS
+                    + " permission is required to call this API");
+        }
         if (getInstantAppPackageName(callingUid) != null
                 && !isCallerSameApp(packageName, callingUid)) {
             return false;
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index 0a17e130..212df43 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -189,11 +189,8 @@
     @Deprecated
     private static final Set<String> STORAGE_PERMISSIONS = new ArraySet<>();
     static {
-        // STOPSHIP(b/112545973): remove once feature enabled by default
-        if (!StorageManager.hasIsolatedStorage()) {
-            STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
-            STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
-        }
+        STORAGE_PERMISSIONS.add(Manifest.permission.READ_EXTERNAL_STORAGE);
+        STORAGE_PERMISSIONS.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
     }
 
     private static final Set<String> MEDIA_AURAL_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 40f2a2b..3029f51 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1666,18 +1666,6 @@
             for (int i = 0; i < numPerms; i++) {
                 String permission = pkg.requestedPermissions.get(i);
 
-                int op = permissionToOpCode(permission);
-                if (op == OP_NONE) {
-                    continue;
-                }
-
-                // Runtime permissions are per uid, not per package, hence per package app-op
-                // modes should never have been set. It is possible to set them via the shell
-                // though. Revert such settings during boot to get the device back into a good
-                // state.
-                LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
-                        op, getUid(userId, getAppId(pkg.applicationInfo.uid)));
-
                 // For pre-M apps the runtime permission do not store the state
                 if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                     continue;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 55af357..1c5c7a3 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3807,6 +3807,9 @@
             }
 
             case KeyEvent.KEYCODE_POWER: {
+                Slog.d(TAG, "interceptKeyBeforeQueueing: KEYCODE_POWER "
+                        + KeyEvent.actionToString(event.getAction())
+                        + " mPowerKeyHandled=" + mPowerKeyHandled + " b/128933363");
                 // Any activity on the power button stops the accessibility shortcut
                 cancelPendingAccessibilityShortcutAction();
                 result &= ~ACTION_PASS_TO_USER;
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index 701e5af..d9d21ba 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -34,6 +34,7 @@
 import com.android.server.LocalServices;
 
 import java.io.PrintWriter;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -65,6 +66,11 @@
     private final Object mLock;
 
     /**
+     * If we're currently waiting for an attention callback
+     */
+    private final AtomicBoolean mRequested;
+
+    /**
      * {@link android.service.attention.AttentionService} API timeout.
      */
     private long mMaxAttentionApiTimeoutMillis;
@@ -78,11 +84,6 @@
     protected AttentionManagerInternal mAttentionManager;
 
     /**
-     * If we're currently waiting for an attention callback
-     */
-    private boolean mRequested;
-
-    /**
      * Current wakefulness of the device. {@see PowerManagerInternal}
      */
     private int mWakefulness;
@@ -94,14 +95,11 @@
 
     @VisibleForTesting
     final AttentionCallbackInternal mCallback = new AttentionCallbackInternal() {
-
         @Override
-        public void onSuccess(int requestCode, int result, long timestamp) {
-            Slog.v(TAG, "onSuccess: " + requestCode + ", " + result
-                    + " - current requestCode: " + getRequestCode());
-            synchronized (mLock) {
-                if (requestCode == getRequestCode() && mRequested) {
-                    mRequested = false;
+        public void onSuccess(int result, long timestamp) {
+            Slog.v(TAG, "onSuccess: " + result);
+            if (mRequested.getAndSet(false)) {
+                synchronized (mLock) {
                     if (mWakefulness != PowerManagerInternal.WAKEFULNESS_AWAKE) {
                         if (DEBUG) Slog.d(TAG, "Device slept before receiving callback.");
                         return;
@@ -116,19 +114,16 @@
         }
 
         @Override
-        public void onFailure(int requestCode, int error) {
+        public void onFailure(int error) {
             Slog.i(TAG, "Failed to check attention: " + error);
-            synchronized (mLock) {
-                if (requestCode == getRequestCode()) {
-                    mRequested = false;
-                }
-            }
+            mRequested.set(false);
         }
     };
 
     public AttentionDetector(Runnable onUserAttention, Object lock) {
         mOnUserAttention = onUserAttention;
         mLock = lock;
+        mRequested = new AtomicBoolean(false);
 
         // Device starts with an awake state upon boot.
         mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
@@ -181,9 +176,11 @@
                         + (whenToCheck - whenToStopExtending));
             }
             return nextScreenDimming;
-        } else if (mRequested) {
+        } else if (mRequested.get()) {
             if (DEBUG) {
-                Slog.d(TAG, "Pending attention callback, wait. " + getRequestCode());
+                // TODO(b/128134941): consider adding a member ID increasing counter in
+                //  AttentionCallbackInternal to track this better.
+                Slog.d(TAG, "Pending attention callback, wait.");
             }
             return whenToCheck;
         }
@@ -192,14 +189,13 @@
         // callback might arrive before #checkAttention returns (if there are cached results.)
         // This means that we must assume that the request was successful, and then cancel it
         // afterwards if AttentionManager couldn't deliver it.
-        mRequested = true;
-        final boolean sent = mAttentionManager.checkAttention(getRequestCode(),
-                getAttentionTimeout(), mCallback);
+        mRequested.set(true);
+        final boolean sent = mAttentionManager.checkAttention(getAttentionTimeout(), mCallback);
         if (!sent) {
-            mRequested = false;
+            mRequested.set(false);
         }
 
-        Slog.v(TAG, "Checking user attention with request code: " + getRequestCode());
+        Slog.v(TAG, "Checking user attention");
         return whenToCheck;
     }
 
@@ -241,9 +237,9 @@
     }
 
     private void cancelCurrentRequestIfAny() {
-        if (mRequested) {
-            mAttentionManager.cancelAttentionCheck(getRequestCode());
-            mRequested = false;
+        if (mRequested.get()) {
+            mAttentionManager.cancelAttentionCheck(mCallback);
+            mRequested.set(false);
         }
     }
 
@@ -255,11 +251,6 @@
     }
 
     @VisibleForTesting
-    int getRequestCode() {
-        return (int) (mLastUserActivityTime % Integer.MAX_VALUE);
-    }
-
-    @VisibleForTesting
     long getAttentionTimeout() {
         return mMaxAttentionApiTimeoutMillis;
     }
diff --git a/services/net/java/android/net/TcpKeepalivePacketData.java b/services/net/java/android/net/TcpKeepalivePacketData.java
index d79ad1f..7f2f499 100644
--- a/services/net/java/android/net/TcpKeepalivePacketData.java
+++ b/services/net/java/android/net/TcpKeepalivePacketData.java
@@ -38,7 +38,7 @@
 public class TcpKeepalivePacketData extends KeepalivePacketData implements Parcelable {
     private static final String TAG = "TcpKeepalivePacketData";
 
-     /** TCP sequence number. */
+    /** TCP sequence number. */
     public final int tcpSeq;
 
     /** TCP ACK number. */
@@ -50,6 +50,12 @@
     /** TCP RCV window scale. */
     public final int tcpWndScale;
 
+    /** IP TOS. */
+    public final int ipTos;
+
+    /** IP TTL. */
+    public final int ipTtl;
+
     private static final int IPV4_HEADER_LENGTH = 20;
     private static final int IPV6_HEADER_LENGTH = 40;
     private static final int TCP_HEADER_LENGTH = 20;
@@ -65,6 +71,8 @@
         // In the packet, the window is shifted right by the window scale.
         tcpWnd = tcpDetails.rcvWnd;
         tcpWndScale = tcpDetails.rcvWndScale;
+        ipTos = tcpDetails.tos;
+        ipTtl = tcpDetails.ttl;
     }
 
     /**
@@ -98,12 +106,11 @@
         final int length = IPV4_HEADER_LENGTH + TCP_HEADER_LENGTH;
         ByteBuffer buf = ByteBuffer.allocate(length);
         buf.order(ByteOrder.BIG_ENDIAN);
-        // IP version and TOS. TODO : fetch this from getsockopt(SOL_IP, IP_TOS)
-        buf.putShort((short) 0x4500);
+        buf.put((byte) 0x45);                       // IP version and IHL
+        buf.put((byte) tcpDetails.tos);             // TOS
         buf.putShort((short) length);
-        buf.putInt(0x4000);                         // ID, flags=DF, offset
-        // TODO : fetch TTL from getsockopt(SOL_IP, IP_TTL)
-        buf.put((byte) 64);
+        buf.putInt(0x00004000);                     // ID, flags=DF, offset
+        buf.put((byte) tcpDetails.ttl);             // TTL
         buf.put((byte) OsConstants.IPPROTO_TCP);
         final int ipChecksumOffset = buf.position();
         buf.putShort((short) 0);                    // IP checksum
@@ -117,7 +124,9 @@
         buf.putShort((short) (tcpDetails.rcvWnd >> tcpDetails.rcvWndScale));   // Window size
         final int tcpChecksumOffset = buf.position();
         buf.putShort((short) 0);                    // TCP checksum
-        // URG is not set therefore the urgent pointer is not included
+        // URG is not set therefore the urgent pointer is zero.
+        buf.putShort((short) 0);                    // Urgent pointer
+
         buf.putShort(ipChecksumOffset, IpUtils.ipChecksum(buf, 0));
         buf.putShort(tcpChecksumOffset, IpUtils.tcpChecksum(
                 buf, 0, IPV4_HEADER_LENGTH, TCP_HEADER_LENGTH));
@@ -138,13 +147,15 @@
                 && this.tcpAck == other.tcpAck
                 && this.tcpSeq == other.tcpSeq
                 && this.tcpWnd == other.tcpWnd
-                && this.tcpWndScale == other.tcpWndScale;
+                && this.tcpWndScale == other.tcpWndScale
+                && this.ipTos == other.ipTos
+                && this.ipTtl == other.ipTtl;
     }
 
     @Override
     public int hashCode() {
         return Objects.hash(srcAddress, dstAddress, srcPort, dstPort, tcpAck, tcpSeq, tcpWnd,
-                tcpWndScale);
+                tcpWndScale, ipTos, ipTtl);
     }
 
     /**
@@ -164,6 +175,8 @@
         out.writeInt(tcpAck);
         out.writeInt(tcpWnd);
         out.writeInt(tcpWndScale);
+        out.writeInt(ipTos);
+        out.writeInt(ipTtl);
     }
 
     private TcpKeepalivePacketData(Parcel in) {
@@ -172,6 +185,8 @@
         tcpAck = in.readInt();
         tcpWnd = in.readInt();
         tcpWndScale = in.readInt();
+        ipTos = in.readInt();
+        ipTtl = in.readInt();
     }
 
     /** Parcelable Creator. */
@@ -200,6 +215,8 @@
         parcel.ack = tcpAck;
         parcel.rcvWnd = tcpWnd;
         parcel.rcvWndScale = tcpWndScale;
+        parcel.tos = ipTos;
+        parcel.ttl = ipTtl;
         return parcel;
     }
 
@@ -212,6 +229,8 @@
                 + " seq: " + tcpSeq
                 + " ack: " + tcpAck
                 + " wnd: " + tcpWnd
-                + " wndScale: " + tcpWndScale;
+                + " wndScale: " + tcpWndScale
+                + " tos: " + ipTos
+                + " ttl: " + ipTtl;
     }
 }
diff --git a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
index d66b6ae..e25168d 100644
--- a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
@@ -25,4 +25,6 @@
     int ack;
     int rcvWnd;
     int rcvWndScale;
+    int tos;
+    int ttl;
 }
diff --git a/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java
new file mode 100644
index 0000000..7b88a0e
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/color/GlobalSaturationTintControllerTest.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display.color;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.opengl.Matrix;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class GlobalSaturationTintControllerTest {
+
+    @Test
+    public void setAndGetMatrix() {
+        final GlobalSaturationTintController tintController = new GlobalSaturationTintController();
+        tintController.setMatrix(50);
+        assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f)
+                .of(new float[]{0.6155f, 0.1155f, 0.1155f, 0.0f, 0.3575f, 0.85749996f, 0.3575f,
+                        0.0f, 0.036f, 0.036f, 0.536f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f});
+    }
+
+    @Test
+    public void resetMatrix() {
+        final GlobalSaturationTintController tintController = new GlobalSaturationTintController();
+        tintController.setMatrix(100);
+        final float[] matrix = new float[16];
+        Matrix.setIdentityM(matrix, 0);
+        assertThat(tintController.getMatrix()).hasValuesWithin(0.00001f).of(matrix);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
index 58055e5..5a9ca0f 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/SyntheticPasswordTests.java
@@ -353,8 +353,8 @@
 
         // Verify DPM gets notified about new device lock
         mService.mHandler.runWithScissors(() -> {}, 0 /*now*/); // Flush runnables on handler
-        PasswordMetrics metric = PasswordMetrics.computeForPassword(pattern);
-        metric.quality = PASSWORD_QUALITY_SOMETHING;
+        final PasswordMetrics metric = PasswordMetrics.computeForCredential(
+                LockPatternUtils.CREDENTIAL_TYPE_PATTERN, pattern);
         verify(mDevicePolicyManager).setActivePasswordState(metric, PRIMARY_USER_ID);
 
         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index a1a58b4..5de41ea 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
@@ -29,6 +28,7 @@
 import static org.mockito.Mockito.when;
 
 import android.attention.AttentionManagerInternal;
+import android.attention.AttentionManagerInternal.AttentionCallbackInternal;
 import android.os.PowerManager;
 import android.os.PowerManagerInternal;
 import android.os.SystemClock;
@@ -41,14 +41,17 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
 @SmallTest
 public class AttentionDetectorTest extends AndroidTestCase {
 
-    private @Mock AttentionManagerInternal mAttentionManagerInternal;
-    private @Mock Runnable mOnUserAttention;
+    @Mock
+    private AttentionManagerInternal mAttentionManagerInternal;
+    @Mock
+    private Runnable mOnUserAttention;
     private TestableAttentionDetector mAttentionDetector;
     private long mAttentionTimeout;
     private long mNextDimming;
@@ -57,7 +60,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        when(mAttentionManagerInternal.checkAttention(anyInt(), anyLong(), any()))
+        when(mAttentionManagerInternal.checkAttention(anyLong(), any()))
                 .thenReturn(true);
         mAttentionDetector = new TestableAttentionDetector();
         mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
@@ -82,7 +85,7 @@
     @Test
     public void testOnUserActivity_checksAttention() {
         long when = registerAttention();
-        verify(mAttentionManagerInternal).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal).checkAttention(anyLong(), any());
         assertThat(when).isLessThan(mNextDimming);
     }
 
@@ -92,7 +95,7 @@
                 Settings.System.ADAPTIVE_SLEEP, 0, UserHandle.USER_CURRENT);
         mAttentionDetector.updateEnabledFromSettings(getContext());
         long when = registerAttention();
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(mNextDimming).isEqualTo(when);
     }
 
@@ -100,7 +103,7 @@
     public void testOnUserActivity_doesntCheckIfNotSupported() {
         mAttentionDetector.setAttentionServiceSupported(false);
         long when = registerAttention();
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(mNextDimming).isEqualTo(when);
     }
 
@@ -129,7 +132,7 @@
         mNextDimming = now;
         mAttentionDetector.onUserActivity(now, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
         mAttentionDetector.updateUserActivity(mNextDimming + 5000L);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
     }
 
     @Test
@@ -146,7 +149,7 @@
         long now = SystemClock.uptimeMillis();
         mAttentionDetector.onUserActivity(now - 15000L, PowerManager.USER_ACTIVITY_EVENT_TOUCH);
         mAttentionDetector.updateUserActivity(now + 2000L);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
     }
 
     @Test
@@ -154,7 +157,7 @@
         registerAttention();
         reset(mAttentionManagerInternal);
         long when = mAttentionDetector.updateUserActivity(mNextDimming);
-        verify(mAttentionManagerInternal, never()).checkAttention(anyInt(), anyLong(), any());
+        verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
         assertThat(when).isLessThan(mNextDimming);
     }
 
@@ -162,32 +165,35 @@
     public void testOnWakefulnessChangeStarted_cancelsRequestWhenNotAwake() {
         registerAttention();
         mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_ASLEEP);
-        verify(mAttentionManagerInternal).cancelAttentionCheck(anyInt());
+
+        ArgumentCaptor<AttentionCallbackInternal> callbackCaptor = ArgumentCaptor.forClass(
+                AttentionCallbackInternal.class);
+        verify(mAttentionManagerInternal).cancelAttentionCheck(callbackCaptor.capture());
+        assertEquals(callbackCaptor.getValue(), mAttentionDetector.mCallback);
     }
 
     @Test
     public void testCallbackOnSuccess_ignoresIfNoAttention() {
         registerAttention();
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_ABSENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_ABSENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention, never()).run();
     }
 
     @Test
     public void testCallbackOnSuccess_callsCallback() {
         registerAttention();
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention).run();
     }
 
     @Test
     public void testCallbackOnFailure_unregistersCurrentRequestCode() {
         registerAttention();
-        mAttentionDetector.mCallback.onFailure(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_FAILURE_UNKNOWN);
-        mAttentionDetector.mCallback.onSuccess(mAttentionDetector.getRequestCode(),
-                AttentionService.ATTENTION_SUCCESS_PRESENT, SystemClock.uptimeMillis());
+        mAttentionDetector.mCallback.onFailure(AttentionService.ATTENTION_FAILURE_UNKNOWN);
+        mAttentionDetector.mCallback.onSuccess(AttentionService.ATTENTION_SUCCESS_PRESENT,
+                SystemClock.uptimeMillis());
         verify(mOnUserAttention, never()).run();
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 426122a..987d46a 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -40,6 +40,8 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Build.VERSION_CODES.O_MR1;
 import static android.os.Build.VERSION_CODES.P;
+import static android.service.notification.Adjustment.KEY_IMPORTANCE;
+import static android.service.notification.Adjustment.KEY_USER_SENTIMENT;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
 import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
 
@@ -492,6 +494,19 @@
         return answers;
     }
 
+    private void clearDeviceConfig() {
+        DeviceConfig.resetToDefaults(
+                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
+    }
+
+    private void setDefaultAssistantInDeviceConfig(String componentName) {
+        DeviceConfig.setProperty(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+                componentName,
+                false);
+    }
+
     @Test
     public void testCreateNotificationChannels_SingleChannel() throws Exception {
         final NotificationChannel channel =
@@ -831,7 +846,7 @@
         mService.addEnqueuedNotification(r);
 
         Bundle bundle = new Bundle();
-        bundle.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        bundle.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), bundle, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2826,7 +2841,7 @@
         mService.setHandler(handler);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_NONE);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_NONE);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
@@ -2867,7 +2882,7 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
@@ -2885,13 +2900,13 @@
         when(mAssistants.isSameUser(eq(null), anyInt())).thenReturn(true);
 
         Bundle signals = new Bundle();
-        signals.putInt(Adjustment.KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
         Adjustment adjustment = new Adjustment(
                 r.sbn.getPackageName(), r.getKey(), signals, "", r.getUser().getIdentifier());
         mBinderService.applyEnqueuedAdjustmentFromAssistant(null, adjustment);
 
         assertEquals(IMPORTANCE_DEFAULT, r.getImportance());
-        assertFalse(r.hasAdjustment(Adjustment.KEY_IMPORTANCE));
+        assertFalse(r.hasAdjustment(KEY_IMPORTANCE));
     }
 
     @Test
@@ -4275,18 +4290,7 @@
                 .onGranted(eq(xmlConfig), eq(0), eq(true));
     }
 
-    private void clearDeviceConfig() {
-        DeviceConfig.resetToDefaults(
-                Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
-    }
 
-    private void setDefaultAssistantInDeviceConfig(String componentName) {
-        DeviceConfig.setProperty(
-                DeviceConfig.NAMESPACE_SYSTEMUI,
-                SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
-                componentName,
-                false);
-    }
 
     public void testGetAllowedAssistantCapabilities() throws Exception {
         List<String> capabilities = mBinderService.getAllowedAssistantCapabilities(null);
@@ -4301,4 +4305,23 @@
             assertFalse(currentCapabilities.contains(capability));
         }
     }
+
+    public void testAdjustRestrictedKey() throws Exception {
+        NotificationRecord r = generateNotificationRecord(mTestNotificationChannel);
+
+        when(mAssistants.isAdjustmentAllowed(KEY_IMPORTANCE)).thenReturn(true);
+        when(mAssistants.isAdjustmentAllowed(KEY_USER_SENTIMENT)).thenReturn(false);
+
+        Bundle signals = new Bundle();
+        signals.putInt(KEY_IMPORTANCE, IMPORTANCE_LOW);
+        signals.putInt(KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
+        Adjustment adjustment = new Adjustment(r.sbn.getPackageName(), r.getKey(), signals,
+               "", r.getUser().getIdentifier());
+
+        mBinderService.applyAdjustmentFromAssistant(null, adjustment);
+        r.applyAdjustments();
+
+        assertEquals(IMPORTANCE_LOW, r.getAssistantImportance());
+        assertEquals(USER_SENTIMENT_NEUTRAL, r.getUserSentiment());
+    }
 }
diff --git a/services/usb/java/com/android/server/usb/UsbPortManager.java b/services/usb/java/com/android/server/usb/UsbPortManager.java
index ae05750..96e12ce 100644
--- a/services/usb/java/com/android/server/usb/UsbPortManager.java
+++ b/services/usb/java/com/android/server/usb/UsbPortManager.java
@@ -150,8 +150,8 @@
     private NotificationManager mNotificationManager;
 
     /**
-     * If there currently is a notification about contaminated USB port shown the id of the
-     * notification, or 0 if there is none.
+     * If there currently is a notification related to contaminated USB port management
+     * shown the id of the notification, or 0 if there is none.
      */
     private int mIsPortContaminatedNotificationId;
 
@@ -191,18 +191,24 @@
     private void updateContaminantNotification() {
         PortInfo currentPortInfo = null;
         Resources r = mContext.getResources();
+        int contaminantStatus = UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED;
 
         // Not handling multiple ports here. Showing the notification
         // for the first port that returns CONTAMINANT_PRESENCE_DETECTED.
         for (PortInfo portInfo : mPorts.values()) {
-            if (portInfo.mUsbPortStatus.getContaminantDetectionStatus()
-                    == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED) {
+            contaminantStatus = portInfo.mUsbPortStatus.getContaminantDetectionStatus();
+            if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                    || contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) {
                 currentPortInfo = portInfo;
                 break;
             }
         }
 
-        if (currentPortInfo != null && mIsPortContaminatedNotificationId
+        // Current contminant status is detected while "safe to use usb port"
+        // notification is displayed. Remove safe to use usb port notification
+        // and push contaminant detected notification.
+        if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                    && mIsPortContaminatedNotificationId
                     != SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) {
             if (mIsPortContaminatedNotificationId
                     == SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED) {
@@ -242,32 +248,41 @@
             Notification notification = builder.build();
             mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification,
                     UserHandle.ALL);
-        } else if (currentPortInfo == null && mIsPortContaminatedNotificationId
+        // No contaminant is detected but contaminant detection notification is displayed.
+        // Remove contaminant detection notification and push safe to use USB port notification.
+        } else if (contaminantStatus != UsbPortStatus.CONTAMINANT_DETECTION_DETECTED
+                && mIsPortContaminatedNotificationId
                 == SystemMessage.NOTE_USB_CONTAMINANT_DETECTED) {
             mNotificationManager.cancelAsUser(null, mIsPortContaminatedNotificationId,
                     UserHandle.ALL);
+            mIsPortContaminatedNotificationId = 0;
 
-            mIsPortContaminatedNotificationId = SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED;
-            int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title;
-            CharSequence title = r.getText(titleRes);
-            String channel = SystemNotificationChannels.ALERTS;
-            CharSequence message = r.getText(
-                    com.android.internal.R.string.usb_contaminant_not_detected_message);
+            // Dont show safe to use notification when contaminant detection is disabled.
+            // Show only when the status is changing from detected to not detected.
+            if (contaminantStatus == UsbPortStatus.CONTAMINANT_DETECTION_NOT_DETECTED) {
+                mIsPortContaminatedNotificationId =
+                        SystemMessage.NOTE_USB_CONTAMINANT_NOT_DETECTED;
+                int titleRes = com.android.internal.R.string.usb_contaminant_not_detected_title;
+                CharSequence title = r.getText(titleRes);
+                String channel = SystemNotificationChannels.ALERTS;
+                CharSequence message = r.getText(
+                        com.android.internal.R.string.usb_contaminant_not_detected_message);
 
-            Notification.Builder builder = new Notification.Builder(mContext, channel)
-                    .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp)
-                    .setTicker(title)
-                    .setColor(mContext.getColor(
-                           com.android.internal.R.color
-                           .system_notification_accent_color))
-                    .setContentTitle(title)
-                    .setContentText(message)
-                    .setVisibility(Notification.VISIBILITY_PUBLIC)
-                    .setStyle(new Notification.BigTextStyle()
-                    .bigText(message));
-            Notification notification = builder.build();
-            mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId, notification,
-                    UserHandle.ALL);
+                Notification.Builder builder = new Notification.Builder(mContext, channel)
+                        .setSmallIcon(com.android.internal.R.drawable.ic_usb_48dp)
+                        .setTicker(title)
+                        .setColor(mContext.getColor(
+                               com.android.internal.R.color
+                               .system_notification_accent_color))
+                        .setContentTitle(title)
+                        .setContentText(message)
+                        .setVisibility(Notification.VISIBILITY_PUBLIC)
+                        .setStyle(new Notification.BigTextStyle()
+                        .bigText(message));
+                Notification notification = builder.build();
+                mNotificationManager.notifyAsUser(null, mIsPortContaminatedNotificationId,
+                        notification, UserHandle.ALL);
+            }
         }
     }
 
@@ -319,8 +334,8 @@
         }
 
         try {
-            // Oneway call into the hal
-            android.hardware.usb.V1_2.IUsb proxy = (android.hardware.usb.V1_2.IUsb) mProxy;
+            // Oneway call into the hal. Use the castFrom method from HIDL.
+            android.hardware.usb.V1_2.IUsb proxy = android.hardware.usb.V1_2.IUsb.castFrom(mProxy);
             proxy.enableContaminantPresenceDetection(portId, enable);
         } catch (RemoteException e) {
             logAndPrintException(pw, "Failed to set contaminant detection", e);
@@ -948,22 +963,26 @@
         }
     }
 
+    private void handlePortLocked(PortInfo portInfo, IndentingPrintWriter pw) {
+        sendPortChangedBroadcastLocked(portInfo);
+        enableContaminantDetectionIfNeeded(portInfo, pw);
+        logToStatsd(portInfo, pw);
+        updateContaminantNotification();
+    }
+
     private void handlePortAddedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port added: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     private void handlePortChangedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port changed: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     private void handlePortRemovedLocked(PortInfo portInfo, IndentingPrintWriter pw) {
         logAndPrint(Log.INFO, pw, "USB port removed: " + portInfo);
-        sendPortChangedBroadcastLocked(portInfo);
-        updateContaminantNotification();
+        handlePortLocked(portInfo, pw);
     }
 
     // Constants have to be converted between USB HAL V1.2 ContaminantDetectionStatus
@@ -996,9 +1015,25 @@
         // instead of from within the critical section.
         mHandler.post(() -> mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 Manifest.permission.MANAGE_USB));
+    }
 
-        // Log to statsd
+    private void enableContaminantDetectionIfNeeded(PortInfo portInfo, IndentingPrintWriter pw) {
+        if (!mConnected.containsKey(portInfo.mUsbPort.getId())) {
+            return;
+        }
 
+        if (mConnected.get(portInfo.mUsbPort.getId())
+                && !portInfo.mUsbPortStatus.isConnected()
+                && portInfo.mUsbPortStatus.getContaminantDetectionStatus()
+                == UsbPortStatus.CONTAMINANT_DETECTION_DISABLED) {
+            // Contaminant detection might have been temporarily disabled by the user
+            // through SystemUI.
+            // Re-enable contaminant detection when the accessory is unplugged.
+            enableContaminantDetection(portInfo.mUsbPort.getId(), true, pw);
+        }
+    }
+
+    private void logToStatsd(PortInfo portInfo, IndentingPrintWriter pw) {
         // Port is removed
         if (portInfo.mUsbPortStatus == null) {
             if (mConnected.containsKey(portInfo.mUsbPort.getId())) {
diff --git a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
index 372ffcd..e0b7227 100644
--- a/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
+++ b/tests/net/java/android/net/TcpKeepalivePacketDataTest.java
@@ -48,6 +48,8 @@
         final int ack = 0x22222222;
         final int wnd = 8000;
         final int wndScale = 2;
+        final int tos = 4;
+        final int ttl = 64;
         TcpKeepalivePacketData resultData = null;
         final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
         testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
@@ -58,6 +60,8 @@
         testInfo.ack = ack;
         testInfo.rcvWnd = wnd;
         testInfo.rcvWndScale = wndScale;
+        testInfo.tos = tos;
+        testInfo.ttl = ttl;
         try {
             resultData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
         } catch (InvalidPacketException e) {
@@ -72,16 +76,21 @@
         assertEquals(testInfo.ack, resultData.tcpAck);
         assertEquals(testInfo.rcvWnd, resultData.tcpWnd);
         assertEquals(testInfo.rcvWndScale, resultData.tcpWndScale);
+        assertEquals(testInfo.tos, resultData.ipTos);
+        assertEquals(testInfo.ttl, resultData.ipTtl);
 
         TestUtils.assertParcelingIsLossless(resultData, TcpKeepalivePacketData.CREATOR);
 
         final byte[] packet = resultData.getPacket();
-        // IP version and TOS.
-        ByteBuffer buf = ByteBuffer.wrap(packet);
-        assertEquals(buf.getShort(), 0x4500);
+        // IP version and IHL
+        assertEquals(packet[0], 0x45);
+        // TOS
+        assertEquals(packet[1], tos);
+        // TTL
+        assertEquals(packet[8], ttl);
         // Source IP address.
         byte[] ip = new byte[4];
-        buf = ByteBuffer.wrap(packet, 12, 4);
+        ByteBuffer buf = ByteBuffer.wrap(packet, 12, 4);
         buf.get(ip);
         assertArrayEquals(ip, IPV4_KEEPALIVE_SRC_ADDR);
         // Destination IP address.
@@ -113,6 +122,8 @@
         final int ack = 0x22222222;
         final int wnd = 48_000;
         final int wndScale = 2;
+        final int tos = 4;
+        final int ttl = 64;
         final TcpKeepalivePacketDataParcelable testInfo = new TcpKeepalivePacketDataParcelable();
         testInfo.srcAddress = IPV4_KEEPALIVE_SRC_ADDR;
         testInfo.srcPort = srcPort;
@@ -122,6 +133,8 @@
         testInfo.ack = ack;
         testInfo.rcvWnd = wnd;
         testInfo.rcvWndScale = wndScale;
+        testInfo.tos = tos;
+        testInfo.ttl = ttl;
         TcpKeepalivePacketData testData = null;
         TcpKeepalivePacketDataParcelable resultData = null;
         testData = TcpKeepalivePacketData.tcpKeepalivePacket(testInfo);
@@ -134,5 +147,7 @@
         assertEquals(resultData.ack, ack);
         assertEquals(resultData.rcvWnd, wnd);
         assertEquals(resultData.rcvWndScale, wndScale);
+        assertEquals(resultData.tos, tos);
+        assertEquals(resultData.ttl, ttl);
     }
 }
diff --git a/tests/utils/testutils/Android.bp b/tests/utils/testutils/Android.bp
index 0a9e964..f71be7b 100644
--- a/tests/utils/testutils/Android.bp
+++ b/tests/utils/testutils/Android.bp
@@ -19,7 +19,10 @@
 
     srcs: ["java/**/*.java"],
 
-    static_libs: ["junit"],
+    static_libs: [
+        "junit",
+        "hamcrest-library",
+    ],
 
     libs: [
         "android.test.runner",
diff --git a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java b/tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java
similarity index 100%
rename from core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java
rename to tests/utils/testutils/java/com/android/server/wm/test/filters/CoreTestsFilter.java
diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
index d0350af..d5b14c5 100644
--- a/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
+++ b/tests/utils/testutils/java/com/android/test/filters/SelectTest.java
@@ -26,10 +26,12 @@
 import org.junit.runner.Description;
 import org.junit.runner.manipulation.Filter;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.StringJoiner;
@@ -131,7 +133,8 @@
      *
      * @param testArgs instrumentation test arguments.
      * @param selectTests array of class name to be selected to run.
-     * @return modified instrumentation test arguments.
+     * @return modified instrumentation test arguments. if {@link #OPTION_SELECT_TEST} argument
+     *      already exists in {@code testArgs}, those are prepended before {@code selectTests}.
      */
     @NonNull
     protected static Bundle addSelectTest(
@@ -139,7 +142,13 @@
         if (selectTests.length == 0) {
             return testArgs;
         }
-        testArgs.putString(OPTION_SELECT_TEST, join(Arrays.asList(selectTests)));
+        final List<String> selectedTestList = new ArrayList<>();
+        final String selectTestArgs = testArgs.getString(OPTION_SELECT_TEST);
+        if (selectTestArgs != null) {
+            selectedTestList.addAll(Arrays.asList(selectTestArgs.split(ARGUMENT_ITEM_SEPARATOR)));
+        }
+        selectedTestList.addAll(Arrays.asList(selectTests));
+        testArgs.putString(OPTION_SELECT_TEST, join(selectedTestList));
         return testArgs;
     }
 
diff --git a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
index 163b00a..df18985 100644
--- a/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
+++ b/tests/utils/testutils/java/com/android/test/filters/SelectTestTests.java
@@ -19,7 +19,11 @@
 import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST;
 import static com.android.test.filters.SelectTest.OPTION_SELECT_TEST_VERBOSE;
 
+import static org.hamcrest.collection.IsArrayContaining.hasItemInArray;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
 import android.os.Bundle;
@@ -146,6 +150,45 @@
     }
 
     @Test
+    public void testAddSelectTest() {
+        final Bundle testArgs = new Bundle();
+
+        final Bundle modifiedTestArgs =
+                SelectTest.addSelectTest(testArgs, PACKAGE_A, CLASS_B3, METHOD_C5X);
+        assertSame(testArgs, modifiedTestArgs);
+
+        final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST);
+        assertNotNull(selectTestArgs);
+        final String[] selectedTests = selectTestArgs.split(",");
+        assertThat(selectedTests, hasItemInArray(PACKAGE_A));
+        assertThat(selectedTests, hasItemInArray(CLASS_B3));
+        assertThat(selectedTests, hasItemInArray(METHOD_C5X));
+    }
+
+    @Test
+    public void testAddSelectTest_prependExistingTestArg() {
+        final Bundle testArgs = new Bundle();
+        testArgs.putString(OPTION_SELECT_TEST, new StringJoiner(",")
+                .add(PACKAGE_A)
+                .add(CLASS_B3)
+                .add(METHOD_C5X)
+                .toString());
+
+        final Bundle modifiedTestArgs =
+                SelectTest.addSelectTest(testArgs, PACKAGE_B, CLASS_B4, METHOD_C6Y);
+
+        final String selectTestArgs = modifiedTestArgs.getString(OPTION_SELECT_TEST);
+        assertNotNull(selectTestArgs);
+        final String[] selectedTests = selectTestArgs.split(",");
+        assertThat(selectedTests, hasItemInArray(PACKAGE_A));
+        assertThat(selectedTests, hasItemInArray(CLASS_B3));
+        assertThat(selectedTests, hasItemInArray(METHOD_C5X));
+        assertThat(selectedTests, hasItemInArray(PACKAGE_B));
+        assertThat(selectedTests, hasItemInArray(CLASS_B4));
+        assertThat(selectedTests, hasItemInArray(METHOD_C6Y));
+    }
+
+    @Test
     public void testFilterDisabled() {
         final Filter filter = mBuilder.build();
         acceptTests(filter, TEST_ALL);
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 42dc74c..2ec1ab3 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -678,7 +678,7 @@
 
     } else if (const ResourceType* type = ParseResourceType(path_data.resource_dir)) {
       if (*type != ResourceType::kRaw) {
-        if (path_data.extension == "xml") {
+        if (*type == ResourceType::kXml || path_data.extension == "xml") {
           compile_func = &CompileXml;
         } else if ((!options.no_png_crunch && path_data.extension == "png")
                    || path_data.extension == "9.png") {
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index bdb9cfa..78967e4 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1171,49 +1171,39 @@
          * This network is disabled because EAP-TLS failure
          */
         public static final int DISABLED_TLS_VERSION_MISMATCH = 8;
-        /**
-         * This network is disabled due to WifiManager.disconnect() call.
-         */
-        public static final int DISABLED_BY_WIFI_MANAGER_DISCONNECT = 9;
-
         // Values above are for temporary disablement; values below are for permanent disablement.
         /**
-         * The starting index for permanent network selection disabled reasons
-         */
-        public static final int NETWORK_SELECTION_DISABLED_PERMANENT_STARTING_INDEX = 10;
-        /**
          * This network is disabled due to absence of user credentials
          */
-        public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 10;
+        public static final int DISABLED_AUTHENTICATION_NO_CREDENTIALS = 9;
         /**
          * This network is permanently disabled because it has no Internet access and user does not
          * want to stay connected.
          */
-        public static final int DISABLED_NO_INTERNET_PERMANENT = 11;
+        public static final int DISABLED_NO_INTERNET_PERMANENT = 10;
         /**
-         * This network is disabled due to WifiManager.disable() call.
+         * This network is disabled due to WifiManager disable it explicitly
          */
-        public static final int DISABLED_BY_WIFI_MANAGER = 12;
+        public static final int DISABLED_BY_WIFI_MANAGER = 11;
         /**
          * This network is disabled due to user switching
          */
-        public static final int DISABLED_DUE_TO_USER_SWITCH = 13;
+        public static final int DISABLED_DUE_TO_USER_SWITCH = 12;
         /**
          * This network is disabled due to wrong password
          */
-        public static final int DISABLED_BY_WRONG_PASSWORD = 14;
+        public static final int DISABLED_BY_WRONG_PASSWORD = 13;
         /**
          * This network is disabled because service is not subscribed
          */
-        public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 15;
+        public static final int DISABLED_AUTHENTICATION_NO_SUBSCRIPTION = 14;
         /**
          * This Maximum disable reason value
          */
-        public static final int NETWORK_SELECTION_DISABLED_MAX = 16;
+        public static final int NETWORK_SELECTION_DISABLED_MAX = 15;
 
         /**
-         * Quality network selection disable reason String (for debug purposes & configuration
-         * storage)
+         * Quality network selection disable reason String (for debug purpose)
          */
         public static final String[] QUALITY_NETWORK_SELECTION_DISABLE_REASON = {
                 "NETWORK_SELECTION_ENABLE",
@@ -1225,7 +1215,6 @@
                 "NETWORK_SELECTION_DISABLED_NO_INTERNET_TEMPORARY",
                 "NETWORK_SELECTION_DISABLED_WPS_START",
                 "NETWORK_SELECTION_DISABLED_TLS_VERSION",
-                "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER_DISCONNECT",
                 "NETWORK_SELECTION_DISABLED_AUTHENTICATION_NO_CREDENTIALS",
                 "NETWORK_SELECTION_DISABLED_NO_INTERNET_PERMANENT",
                 "NETWORK_SELECTION_DISABLED_BY_WIFI_MANAGER",