Merge "GraphicsEnvironment: Allow profileable apps to load layers"
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/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
index 0c30302..1f26188 100644
--- a/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
+++ b/apct-tests/perftests/core/src/android/os/KernelCpuThreadReaderPerfTest.java
@@ -47,7 +47,7 @@
         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
         assertNotNull(mKernelCpuThreadReader);
         while (state.keepRunning()) {
-            this.mKernelCpuThreadReader.getCurrentProcessCpuUsage();
+            this.mKernelCpuThreadReader.getProcessCpuUsage();
         }
     }
 }
diff --git a/api/current.txt b/api/current.txt
index 8192762..2a26368 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6963,7 +6963,7 @@
 
   public abstract static class DevicePolicyManager.InstallSystemUpdateCallback {
     ctor public DevicePolicyManager.InstallSystemUpdateCallback();
-    method public void onInstallUpdateError(int, String);
+    method public void onInstallUpdateError(int, @NonNull String);
     field public static final int UPDATE_ERROR_BATTERY_LOW = 5; // 0x5
     field public static final int UPDATE_ERROR_FILE_NOT_FOUND = 4; // 0x4
     field public static final int UPDATE_ERROR_INCORRECT_OS_VERSION = 2; // 0x2
@@ -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();
@@ -13087,10 +13089,10 @@
     method @Deprecated public String buildUnionSubQuery(String, String[], java.util.Set<java.lang.String>, int, String, String, String[], String, String);
     method public int delete(@NonNull android.database.sqlite.SQLiteDatabase, @Nullable String, @Nullable String[]);
     method @Nullable public android.database.sqlite.SQLiteDatabase.CursorFactory getCursorFactory();
-    method public boolean getDistinct();
     method @Nullable public java.util.Map<java.lang.String,java.lang.String> getProjectionMap();
-    method public boolean getStrict();
     method @Nullable public String getTables();
+    method public boolean isDistinct();
+    method public boolean isStrict();
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String);
     method public android.database.Cursor query(android.database.sqlite.SQLiteDatabase, String[], String, String[], String, String, String, String, android.os.CancellationSignal);
@@ -29265,7 +29267,6 @@
     method public abstract boolean isRelative();
     method public android.net.Uri normalizeScheme();
     method public static android.net.Uri parse(String);
-    method @NonNull public String toSafeString();
     method public abstract String toString();
     method public static android.net.Uri withAppendedPath(android.net.Uri, String);
     method public static void writeToParcel(android.os.Parcel, android.net.Uri);
@@ -53046,6 +53047,16 @@
 
 package android.view.contentcapture {
 
+  public final class ContentCaptureCondition implements android.os.Parcelable {
+    ctor public ContentCaptureCondition(@NonNull android.content.LocusId, int);
+    method public int describeContents();
+    method public int getFlags();
+    method @NonNull public android.content.LocusId getLocusId();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.view.contentcapture.ContentCaptureCondition> CREATOR;
+    field public static final int FLAG_IS_REGEX = 2; // 0x2
+  }
+
   public final class ContentCaptureContext implements android.os.Parcelable {
     method public int describeContents();
     method @NonNull public static android.view.contentcapture.ContentCaptureContext forLocusId(@NonNull String);
@@ -53062,6 +53073,7 @@
   }
 
   public final class ContentCaptureManager {
+    method @Nullable public java.util.Set<android.view.contentcapture.ContentCaptureCondition> getContentCaptureConditions();
     method @Nullable public android.content.ComponentName getServiceComponentName();
     method public boolean isContentCaptureEnabled();
     method public void removeUserData(@NonNull android.view.contentcapture.UserDataRemovalRequest);
diff --git a/api/system-current.txt b/api/system-current.txt
index 4b6c537..b47f573 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -491,12 +491,12 @@
     ctor public InstantAppResolverService();
     method public final void attachBaseContext(android.content.Context);
     method public final android.os.IBinder onBind(android.content.Intent);
-    method @Deprecated public void onGetInstantAppIntentFilter(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppIntentFilter(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method public void onGetInstantAppIntentFilter(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppResolveInfo(int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method @Deprecated public void onGetInstantAppResolveInfo(android.content.Intent, int[], String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
-    method public void onGetInstantAppResolveInfo(android.content.Intent, int[], android.os.UserHandle, String, android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppIntentFilter(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppIntentFilter(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppResolveInfo(@Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method @Deprecated public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
+    method public void onGetInstantAppResolveInfo(@NonNull android.content.Intent, @Nullable int[], @NonNull android.os.UserHandle, @NonNull String, @NonNull android.app.InstantAppResolverService.InstantAppResolutionCallback);
   }
 
   public static final class InstantAppResolverService.InstantAppResolutionCallback {
@@ -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);
@@ -4233,6 +4233,10 @@
     field public static final int TAG_SYSTEM_PROBE = -190; // 0xffffff42
   }
 
+  public abstract class Uri implements java.lang.Comparable<android.net.Uri> android.os.Parcelable {
+    method @NonNull public String toSafeString();
+  }
+
   public class VpnService extends android.app.Service {
     method @RequiresPermission(android.Manifest.permission.CONTROL_VPN) public static void prepareAndAuthorize(android.content.Context);
   }
@@ -4436,7 +4440,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
@@ -5664,7 +5668,7 @@
   }
 
   public static interface DynamicSystemClient.OnStatusChangedListener {
-    method public void onStatusChanged(int, int, long);
+    method public void onStatusChanged(int, int, long, @Nullable Throwable);
   }
 
 }
@@ -6322,8 +6326,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 +6339,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);
   }
 
 }
@@ -6444,6 +6448,7 @@
     method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
     method public void onDisconnected();
     method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
     method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
     field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
     field public static final String SERVICE_META_DATA = "android.content_capture";
@@ -6895,6 +6900,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..56c5e98 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 {
@@ -2457,6 +2457,7 @@
     method public void onDestroyContentCaptureSession(@NonNull android.view.contentcapture.ContentCaptureSessionId);
     method public void onDisconnected();
     method public void onUserDataRemovalRequest(@NonNull android.view.contentcapture.UserDataRemovalRequest);
+    method public final void setContentCaptureConditions(@NonNull String, @Nullable java.util.Set<android.view.contentcapture.ContentCaptureCondition>);
     method public final void setContentCaptureWhitelist(@Nullable java.util.Set<java.lang.String>, @Nullable java.util.Set<android.content.ComponentName>);
     field public static final String SERVICE_INTERFACE = "android.service.contentcapture.ContentCaptureService";
     field public static final String SERVICE_META_DATA = "android.content_capture";
@@ -2662,6 +2663,15 @@
     method public void setVoiceRoamingType(int);
   }
 
+  public final class SmsManager {
+    method @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public int checkSmsShortCodeDestination(String, String);
+    field public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1; // 0x1
+    field public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0; // 0x0
+    field public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3; // 0x3
+    field public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4; // 0x4
+    field public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2; // 0x2
+  }
+
   public class TelephonyManager {
     method public int checkCarrierPrivilegesForPackage(String);
     method public int getCarrierIdListVersion();
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index a6c7cae..8e7277c 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -101,7 +101,7 @@
 
 BootAnimation::BootAnimation(sp<Callbacks> callbacks)
         : Thread(false), mClockEnabled(true), mTimeIsAccurate(false),
-        mTimeFormat12Hour(false), mTimeCheckThread(NULL), mCallbacks(callbacks) {
+        mTimeFormat12Hour(false), mTimeCheckThread(nullptr), mCallbacks(callbacks) {
     mSession = new SurfaceComposerClient();
 
     std::string powerCtl = android::base::GetProperty("sys.powerctl", "");
@@ -156,7 +156,7 @@
 status_t BootAnimation::initTexture(Texture* texture, AssetManager& assets,
         const char* name) {
     Asset* asset = assets.open(name, Asset::ACCESS_BUFFER);
-    if (asset == NULL)
+    if (asset == nullptr)
         return NO_INIT;
     SkBitmap bitmap;
     sk_sp<SkData> data = SkData::MakeWithoutCopy(asset->getBuffer(false),
@@ -234,7 +234,7 @@
         case kN32_SkColorType:
             if (!mUseNpotTextures && (tw != w || th != h)) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tw, th, 0, GL_RGBA,
-                        GL_UNSIGNED_BYTE, 0);
+                        GL_UNSIGNED_BYTE, nullptr);
                 glTexSubImage2D(GL_TEXTURE_2D, 0,
                         0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p);
             } else {
@@ -246,7 +246,7 @@
         case kRGB_565_SkColorType:
             if (!mUseNpotTextures && (tw != w || th != h)) {
                 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_RGB,
-                        GL_UNSIGNED_SHORT_5_6_5, 0);
+                        GL_UNSIGNED_SHORT_5_6_5, nullptr);
                 glTexSubImage2D(GL_TEXTURE_2D, 0,
                         0, 0, w, h, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, p);
             } else {
@@ -304,10 +304,10 @@
 
     EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 
-    eglInitialize(display, 0, 0);
+    eglInitialize(display, nullptr, nullptr);
     eglChooseConfig(display, attribs, &config, 1, &numConfigs);
-    surface = eglCreateWindowSurface(display, config, s.get(), NULL);
-    context = eglCreateContext(display, config, NULL, NULL);
+    surface = eglCreateWindowSurface(display, config, s.get(), nullptr);
+    context = eglCreateContext(display, config, nullptr, nullptr);
     eglQuerySurface(display, surface, EGL_WIDTH, &w);
     eglQuerySurface(display, surface, EGL_HEIGHT, &h);
 
@@ -671,7 +671,7 @@
     // Parse the description file
     for (;;) {
         const char* endl = strstr(s, "\n");
-        if (endl == NULL) break;
+        if (endl == nullptr) break;
         String8 line(s, endl - s);
         const char* l = line.string();
         int fps = 0;
@@ -699,8 +699,8 @@
             part.count = count;
             part.pause = pause;
             part.path = path;
-            part.audioData = NULL;
-            part.animation = NULL;
+            part.audioData = nullptr;
+            part.animation = nullptr;
             if (!parseColor(color, part.backgroundColor)) {
                 SLOGE("> invalid color '#%s'", color);
                 part.backgroundColor[0] = 0.0f;
@@ -716,9 +716,9 @@
             part.playUntilComplete = false;
             part.count = 1;
             part.pause = 0;
-            part.audioData = NULL;
+            part.audioData = nullptr;
             part.animation = loadAnimation(String8(SYSTEM_BOOTANIMATION_FILE));
-            if (part.animation != NULL)
+            if (part.animation != nullptr)
                 animation.parts.add(part);
         }
         s = ++endl;
@@ -731,7 +731,7 @@
 {
     // read all the data structures
     const size_t pcount = animation.parts.size();
-    void *cookie = NULL;
+    void *cookie = nullptr;
     ZipFileRO* zip = animation.zip;
     if (!zip->startIteration(&cookie)) {
         return false;
@@ -739,7 +739,7 @@
 
     ZipEntryRO entry;
     char name[ANIM_ENTRY_NAME_MAX];
-    while ((entry = zip->nextEntry(cookie)) != NULL) {
+    while ((entry = zip->nextEntry(cookie)) != nullptr) {
         const int foundEntryName = zip->getEntryFileName(entry, name, ANIM_ENTRY_NAME_MAX);
         if (foundEntryName > ANIM_ENTRY_NAME_MAX || foundEntryName == -1) {
             SLOGE("Error fetching entry file name");
@@ -762,7 +762,7 @@
                 if (path == animation.parts[j].path) {
                     uint16_t method;
                     // supports only stored png files
-                    if (zip->getEntryInfo(entry, &method, NULL, NULL, NULL, NULL, NULL)) {
+                    if (zip->getEntryInfo(entry, &method, nullptr, nullptr, nullptr, nullptr, nullptr)) {
                         if (method == ZipFileRO::kCompressStored) {
                             FileMap* map = zip->createEntryFileMap(entry);
                             if (map) {
@@ -800,7 +800,7 @@
         for (size_t frameIdx = 0; frameIdx < part.frames.size(); frameIdx++) {
             const char* endl = strstr(trimDataStr, "\n");
             // No more trimData for this part.
-            if (endl == NULL) {
+            if (endl == nullptr) {
                 break;
             }
             String8 line(trimDataStr, endl - trimDataStr);
@@ -927,7 +927,7 @@
         glBindTexture(GL_TEXTURE_2D, 0);
 
         // Handle animation package
-        if (part.animation != NULL) {
+        if (part.animation != nullptr) {
             playAnimation(*part.animation);
             if (exitPending())
                 break;
@@ -1001,7 +1001,7 @@
                     spec.tv_nsec = (now + delay) % 1000000000;
                     int err;
                     do {
-                        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+                        err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, nullptr);
                     } while (err<0 && errno == EINTR);
                 }
 
@@ -1090,13 +1090,13 @@
     if (mLoadedFiles.indexOf(fn) >= 0) {
         SLOGE("File \"%s\" is already loaded. Cyclic ref is not allowed",
             fn.string());
-        return NULL;
+        return nullptr;
     }
     ZipFileRO *zip = ZipFileRO::open(fn);
-    if (zip == NULL) {
+    if (zip == nullptr) {
         SLOGE("Failed to open animation zip \"%s\": %s",
             fn.string(), strerror(errno));
-        return NULL;
+        return nullptr;
     }
 
     Animation *animation =  new Animation;
@@ -1107,7 +1107,7 @@
 
     parseAnimationDesc(*animation);
     if (!preloadZip(*animation)) {
-        return NULL;
+        return nullptr;
     }
 
 
@@ -1135,7 +1135,7 @@
     }
 
     FILE* file = fopen(LAST_TIME_CHANGED_FILE_PATH, "r");
-    if (file != NULL) {
+    if (file != nullptr) {
       long long lastChangedTime = 0;
       fscanf(file, "%lld", &lastChangedTime);
       fclose(file);
diff --git a/cmds/bootanimation/audioplay.cpp b/cmds/bootanimation/audioplay.cpp
index 874aab0..c5e16c6 100644
--- a/cmds/bootanimation/audioplay.cpp
+++ b/cmds/bootanimation/audioplay.cpp
@@ -39,14 +39,14 @@
 using namespace android;
 
 // engine interfaces
-static SLObjectItf engineObject = NULL;
+static SLObjectItf engineObject = nullptr;
 static SLEngineItf engineEngine;
 
 // output mix interfaces
-static SLObjectItf outputMixObject = NULL;
+static SLObjectItf outputMixObject = nullptr;
 
 // buffer queue player interfaces
-static SLObjectItf bqPlayerObject = NULL;
+static SLObjectItf bqPlayerObject = nullptr;
 static SLPlayItf bqPlayerPlay;
 static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
 static SLMuteSoloItf bqPlayerMuteSolo;
@@ -89,7 +89,7 @@
 }
 
 bool hasPlayer() {
-    return (engineObject != NULL && bqPlayerObject != NULL);
+    return (engineObject != nullptr && bqPlayerObject != nullptr);
 }
 
 // create the engine and output mix objects
@@ -97,7 +97,7 @@
     SLresult result;
 
     // create engine
-    result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+    result = slCreateEngine(&engineObject, 0, nullptr, 0, nullptr, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("slCreateEngine failed with result %d", result);
         return false;
@@ -121,7 +121,7 @@
     (void)result;
 
     // create output mix
-    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
+    result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, nullptr, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("sl engine CreateOutputMix failed with result %d", result);
         return false;
@@ -173,7 +173,7 @@
 
     // configure audio sink
     SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
-    SLDataSink audioSnk = {&loc_outmix, NULL};
+    SLDataSink audioSnk = {&loc_outmix, nullptr};
 
     // create audio player
     const SLInterfaceID ids[3] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME, SL_IID_ANDROIDCONFIGURATION};
@@ -236,7 +236,7 @@
     (void)result;
 
     // register callback on the buffer queue
-    result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
+    result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, nullptr);
     if (result != SL_RESULT_SUCCESS) {
         ALOGE("sl bqPlayerBufferQueue RegisterCallback failed with result %d", result);
         return false;
@@ -261,7 +261,7 @@
                   const uint8_t** oSoundBuf, unsigned* oSoundBufSize) {
     *oSoundBuf = clipBuf;
     *oSoundBufSize = clipBufSize;
-    *oChunkFormat = NULL;
+    *oChunkFormat = nullptr;
     const RiffWaveHeader* wavHeader = (const RiffWaveHeader*)*oSoundBuf;
     if (*oSoundBufSize < sizeof(*wavHeader) || (wavHeader->riff_id != ID_RIFF) ||
         (wavHeader->wave_id != ID_WAVE)) {
@@ -303,7 +303,7 @@
         }
     }
 
-    if (*oChunkFormat == NULL) {
+    if (*oChunkFormat == nullptr) {
         ALOGE("format not found in WAV file");
         return false;
     }
@@ -435,7 +435,7 @@
 
     SLresult result;
 
-    if (NULL != bqPlayerPlay) {
+    if (nullptr != bqPlayerPlay) {
         // set the player's state
         result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay,
             isPlaying ? SL_PLAYSTATE_PLAYING : SL_PLAYSTATE_STOPPED);
@@ -445,28 +445,28 @@
 
 void destroy() {
     // destroy buffer queue audio player object, and invalidate all associated interfaces
-    if (bqPlayerObject != NULL) {
+    if (bqPlayerObject != nullptr) {
         CHATTY("destroying audio player");
         (*bqPlayerObject)->Destroy(bqPlayerObject);
-        bqPlayerObject = NULL;
-        bqPlayerPlay = NULL;
-        bqPlayerBufferQueue = NULL;
-        bqPlayerMuteSolo = NULL;
-        bqPlayerVolume = NULL;
+        bqPlayerObject = nullptr;
+        bqPlayerPlay = nullptr;
+        bqPlayerBufferQueue = nullptr;
+        bqPlayerMuteSolo = nullptr;
+        bqPlayerVolume = nullptr;
     }
 
     // destroy output mix object, and invalidate all associated interfaces
-    if (outputMixObject != NULL) {
+    if (outputMixObject != nullptr) {
         (*outputMixObject)->Destroy(outputMixObject);
-        outputMixObject = NULL;
+        outputMixObject = nullptr;
     }
 
     // destroy engine object, and invalidate all associated interfaces
-    if (engineObject != NULL) {
+    if (engineObject != nullptr) {
         CHATTY("destroying audio engine");
         (*engineObject)->Destroy(engineObject);
-        engineObject = NULL;
-        engineEngine = NULL;
+        engineObject = nullptr;
+        engineEngine = nullptr;
     }
 }
 
diff --git a/cmds/bootanimation/iot/iotbootanimation_main.cpp b/cmds/bootanimation/iot/iotbootanimation_main.cpp
index 2a3d376..ae35297 100644
--- a/cmds/bootanimation/iot/iotbootanimation_main.cpp
+++ b/cmds/bootanimation/iot/iotbootanimation_main.cpp
@@ -60,7 +60,7 @@
 
         mBootAction = new BootAction();
         if (!mBootAction->init(library_path, mBootParameters)) {
-            mBootAction = NULL;
+            mBootAction = nullptr;
         }
     };
 
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/app/InstantAppResolverService.java b/core/java/android/app/InstantAppResolverService.java
index b1541c6..a7be542 100644
--- a/core/java/android/app/InstantAppResolverService.java
+++ b/core/java/android/app/InstantAppResolverService.java
@@ -16,6 +16,8 @@
 
 package android.app;
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.content.Context;
 import android.content.Intent;
@@ -61,8 +63,8 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppResolveInfo(
-            int digestPrefix[], String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@Nullable int[] digestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         throw new IllegalStateException("Must define onGetInstantAppResolveInfo");
     }
 
@@ -75,8 +77,8 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppIntentFilter(
-            int digestPrefix[], String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@Nullable int[] digestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         throw new IllegalStateException("Must define onGetInstantAppIntentFilter");
     }
 
@@ -105,8 +107,9 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
-            String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull String token,
+            @NonNull InstantAppResolutionCallback callback) {
         // if not overridden, forward to old methods and filter out non-web intents
         if (sanitizedIntent.isWebIntent()) {
             onGetInstantAppResolveInfo(hostDigestPrefix, token, callback);
@@ -135,8 +138,9 @@
      *             String, InstantAppResolutionCallback)}.
      */
     @Deprecated
-    public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
-            String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         Log.e(TAG, "New onGetInstantAppIntentFilter is not overridden");
         // if not overridden, forward to old methods and filter out non-web intents
         if (sanitizedIntent.isWebIntent()) {
@@ -167,8 +171,9 @@
      *
      * @see InstantAppResolveInfo
      */
-    public void onGetInstantAppResolveInfo(Intent sanitizedIntent, int[] hostDigestPrefix,
-            UserHandle userHandle, String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppResolveInfo(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull UserHandle userHandle,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         // If not overridden, forward to the old method.
         onGetInstantAppResolveInfo(sanitizedIntent, hostDigestPrefix, token, callback);
     }
@@ -189,8 +194,9 @@
      *              to the currently visible installer via {@link Intent#EXTRA_INSTANT_APP_TOKEN}.
      * @param callback The {@link InstantAppResolutionCallback} to provide results to.
      */
-    public void onGetInstantAppIntentFilter(Intent sanitizedIntent, int[] hostDigestPrefix,
-            UserHandle userHandle, String token, InstantAppResolutionCallback callback) {
+    public void onGetInstantAppIntentFilter(@NonNull Intent sanitizedIntent,
+            @Nullable int[] hostDigestPrefix, @NonNull UserHandle userHandle,
+            @NonNull String token, @NonNull InstantAppResolutionCallback callback) {
         // If not overridden, forward to the old method.
         onGetInstantAppIntentFilter(sanitizedIntent, hostDigestPrefix, token, callback);
     }
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 4c05497..4b0c05f 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2166,7 +2166,7 @@
          * reported back to the IT admin to be read.
          */
         public void onInstallUpdateError(
-                @InstallUpdateCallbackErrorConstants int errorCode, String errorMessage) {
+                @InstallUpdateCallbackErrorConstants int errorCode, @NonNull String errorMessage) {
         }
     }
 
diff --git a/core/java/android/app/role/RoleControllerManager.java b/core/java/android/app/role/RoleControllerManager.java
index e96c9a5..bd98117 100644
--- a/core/java/android/app/role/RoleControllerManager.java
+++ b/core/java/android/app/role/RoleControllerManager.java
@@ -167,7 +167,7 @@
         RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
                 @NonNull Handler handler, @UserIdInt int userId) {
             super(context, RoleControllerService.SERVICE_INTERFACE, componentName, userId,
-                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, false,
+                    service -> Log.e(LOG_TAG, "RemoteService " + service + " died"), handler, 0,
                     false, 1);
         }
 
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/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index b480939..35d1eac 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -166,6 +166,9 @@
     private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
     private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
 
+    private static final int DEFAULT_MIN_SDK_VERSION = 1;
+    private static final int DEFAULT_TARGET_SDK_VERSION = 0;
+
     // TODO: switch outError users to PackageParserException
     // TODO: refactor "codePath" to "apkPath"
 
@@ -466,6 +469,8 @@
         public final int versionCodeMajor;
         public final int revisionCode;
         public final int installLocation;
+        public final int minSdkVersion;
+        public final int targetSdkVersion;
         public final VerifierInfo[] verifiers;
         public final SigningDetails signingDetails;
         public final boolean coreApp;
@@ -484,7 +489,8 @@
                 int revisionCode, int installLocation, List<VerifierInfo> verifiers,
                 SigningDetails signingDetails, boolean coreApp,
                 boolean debuggable, boolean multiArch, boolean use32bitAbi,
-                boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits) {
+                boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits,
+                int minSdkVersion, int targetSdkVersion) {
             this.codePath = codePath;
             this.packageName = packageName;
             this.splitName = splitName;
@@ -505,6 +511,8 @@
             this.extractNativeLibs = extractNativeLibs;
             this.isolatedSplits = isolatedSplits;
             this.isSplitRequired = isSplitRequired;
+            this.minSdkVersion = minSdkVersion;
+            this.targetSdkVersion = targetSdkVersion;
         }
 
         public long getLongVersionCode() {
@@ -1712,6 +1720,8 @@
         int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
         int versionCode = 0;
         int versionCodeMajor = 0;
+        int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION;
+        int minSdkVersion = DEFAULT_MIN_SDK_VERSION;
         int revisionCode = 0;
         boolean coreApp = false;
         boolean debuggable = false;
@@ -1749,7 +1759,7 @@
             }
         }
 
-        // Only search the tree when the tag is directly below <manifest>
+        // Only search the tree when the tag is the direct child of <manifest> tag
         int type;
         final int searchDepth = parser.getDepth() + 1;
 
@@ -1800,13 +1810,25 @@
                             PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                             "<uses-split> tag requires 'android:name' attribute");
                 }
+            } else if (TAG_USES_SDK.equals(parser.getName())) {
+                for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+                    final String attr = attrs.getAttributeName(i);
+                    if ("targetSdkVersion".equals(attr)) {
+                        targetSdkVersion = attrs.getAttributeIntValue(i,
+                                DEFAULT_TARGET_SDK_VERSION);
+                    }
+                    if ("minSdkVersion".equals(attr)) {
+                        minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
+                    }
+                }
             }
         }
 
         return new ApkLite(codePath, packageSplit.first, packageSplit.second, isFeatureSplit,
                 configForSplit, usesSplitName, isSplitRequired, versionCode, versionCodeMajor,
                 revisionCode, installLocation, verifiers, signingDetails, coreApp, debuggable,
-                multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, isolatedSplits);
+                multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs, isolatedSplits,
+                minSdkVersion, targetSdkVersion);
     }
 
     /**
@@ -8350,6 +8372,7 @@
         }
     }
 
+    // TODO(b/129261524): Clean up API
     public static PackageInfo generatePackageInfoFromApex(File apexFile, boolean collectCerts)
             throws PackageParserException {
         PackageInfo pi = new PackageInfo();
@@ -8369,25 +8392,27 @@
             }
         }
 
-        // TODO(b/123086053) properly fill in the ApplicationInfo with data from AndroidManifest
+        PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags);
+
+        // Properly fill in the ApplicationInfo with data from AndroidManifest
         // Add ApplicationInfo to the PackageInfo.
+        // TODO(b/129267599)
         ApplicationInfo ai = new ApplicationInfo();
+        ai.packageName = apk.packageName;
         ai.sourceDir = apexFile.getPath();
         ai.flags = ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_INSTALLED;
         ai.enabled = true;
-        ai.targetSdkVersion = 28;
-        ai.targetSandboxVersion = 0;
-        pi.applicationInfo = ai;
-
-
-        // TODO(b/123052859): We should avoid these repeated calls to parseApkLite each time
-        // we want to generate information for APEX modules.
-        PackageParser.ApkLite apk = PackageParser.parseApkLite(apexFile, parseFlags);
+        ai.minSdkVersion = apk.minSdkVersion;
+        ai.targetSdkVersion = apk.targetSdkVersion;
+        ai.targetSandboxVersion = PARSE_DEFAULT_TARGET_SANDBOX;
+        ai.setVersionCode(apk.getLongVersionCode());
 
         pi.packageName = apk.packageName;
-        ai.packageName = apk.packageName;
+        pi.splitNames = new String[]{apk.splitName};
         pi.setLongVersionCode(apk.getLongVersionCode());
-        ai.setVersionCode(apk.getLongVersionCode());
+        pi.applicationInfo = ai;
+        pi.coreApp = apk.coreApp;
+
 
         if (collectCerts) {
             if (apk.signingDetails.hasPastSigningCertificates()) {
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/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index a73a719..bad80b8 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -80,7 +80,7 @@
      * Get if the query is marked as {@code DISTINCT}, as last configured by
      * {@link #setDistinct(boolean)}.
      */
-    public boolean getDistinct() {
+    public boolean isDistinct() {
         return mDistinct;
     }
 
@@ -215,7 +215,7 @@
     }
 
     /**
-     * Sets the cursor factory to be used for the query, as last configured by
+     * Gets the cursor factory to be used for the query, as last configured by
      * {@link #setCursorFactory(android.database.sqlite.SQLiteDatabase.CursorFactory)}.
      */
     public @Nullable SQLiteDatabase.CursorFactory getCursorFactory() {
@@ -251,7 +251,7 @@
      * Get if the query is marked as strict, as last configured by
      * {@link #setStrict(boolean)}.
      */
-    public boolean getStrict() {
+    public boolean isStrict() {
         return mStrict;
     }
 
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index b122f19..c45b8ed 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -48,7 +48,10 @@
         return pulseOnNotificationEnabled(user)
                 || pulseOnLongPressEnabled(user)
                 || alwaysOnEnabled(user)
-                || wakeScreenGestureEnabled(user);
+                || wakeScreenGestureEnabled(user)
+                || pickupGestureEnabled(user)
+                || tapGestureEnabled(user)
+                || doubleTapGestureEnabled(user);
     }
 
     /** {@hide} */
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/Uri.java b/core/java/android/net/Uri.java
index 9e0d95b..c3166e9 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -18,6 +18,7 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.content.Intent;
 import android.os.Environment;
@@ -380,9 +381,10 @@
      * returned as {@code tel:xxx-xxx-xxxx} and {@code http://example.com/path/to/item/} is
      * returned as {@code http://example.com/...}.
      * @return the common forms PII redacted string of this URI
+     * @hide
      */
-    @NonNull
-    public String toSafeString() {
+    @SystemApi
+    public @NonNull String toSafeString() {
         String scheme = getScheme();
         String ssp = getSchemeSpecificPart();
         if (scheme != null) {
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/image/DynamicSystemClient.java b/core/java/android/os/image/DynamicSystemClient.java
index 33a6ee8..87367ac 100644
--- a/core/java/android/os/image/DynamicSystemClient.java
+++ b/core/java/android/os/image/DynamicSystemClient.java
@@ -19,6 +19,7 @@
 import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
 import android.content.ComponentName;
@@ -31,6 +32,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.ParcelableException;
 import android.os.RemoteException;
 import android.util.Slog;
 
@@ -100,9 +102,10 @@
          * @param status status code, also defined in {@code DynamicSystemClient}.
          * @param cause cause code, also defined in {@code DynamicSystemClient}.
          * @param progress number of bytes installed.
+         * @param detail additional detail about the error if available, otherwise null.
          */
         void onStatusChanged(@InstallationStatus int status, @StatusChangedCause int cause,
-                @BytesLong long progress);
+                @BytesLong long progress, @Nullable Throwable detail);
     }
 
     /*
@@ -177,6 +180,12 @@
      */
     public static final String KEY_INSTALLED_SIZE = "KEY_INSTALLED_SIZE";
 
+    /**
+     * Message key, used when the service is sending exception detail to the client.
+     * @hide
+     */
+    public static final String KEY_EXCEPTION_DETAIL = "KEY_EXCEPTION_DETAIL";
+
     /*
      * Intent Actions
      */
@@ -248,7 +257,7 @@
             } catch (RemoteException e) {
                 Slog.e(TAG, "Unable to get status from installation service");
                 mExecutor.execute(() -> {
-                    mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0);
+                    mListener.onStatusChanged(STATUS_UNKNOWN, CAUSE_ERROR_IPC, 0, e);
                 });
             }
         }
@@ -396,14 +405,19 @@
                 int status = msg.arg1;
                 int cause = msg.arg2;
                 // obj is non-null
-                long progress = ((Bundle) msg.obj).getLong(KEY_INSTALLED_SIZE);
+                Bundle bundle = (Bundle) msg.obj;
+                long progress = bundle.getLong(KEY_INSTALLED_SIZE);
+                ParcelableException t = (ParcelableException) bundle.getSerializable(
+                        KEY_EXCEPTION_DETAIL);
+
+                Throwable detail = t == null ? null : t.getCause();
 
                 if (mExecutor != null) {
                     mExecutor.execute(() -> {
-                        mListener.onStatusChanged(status, cause, progress);
+                        mListener.onStatusChanged(status, cause, progress, detail);
                     });
                 } else {
-                    mListener.onStatusChanged(status, cause, progress);
+                    mListener.onStatusChanged(status, cause, progress, detail);
                 }
                 break;
             default:
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/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 3e60d51..f6fcdb0 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -16,7 +16,21 @@
 
 package android.os.storage;
 
+import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
+import static android.Manifest.permission.READ_MEDIA_AUDIO;
+import static android.Manifest.permission.READ_MEDIA_IMAGES;
+import static android.Manifest.permission.READ_MEDIA_VIDEO;
+import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_READ_MEDIA_AUDIO;
+import static android.app.AppOpsManager.OP_READ_MEDIA_IMAGES;
+import static android.app.AppOpsManager.OP_READ_MEDIA_VIDEO;
+import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_AUDIO;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_IMAGES;
+import static android.app.AppOpsManager.OP_WRITE_MEDIA_VIDEO;
 import static android.content.ContentResolver.DEPRECATE_DATA_PREFIX;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 
 import android.annotation.BytesLong;
 import android.annotation.IntDef;
@@ -33,6 +47,7 @@
 import android.app.Activity;
 import android.app.ActivityThread;
 import android.app.AppGlobals;
+import android.app.AppOpsManager;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
@@ -1635,6 +1650,108 @@
         }
     }
 
+    /**
+     * Check that given app holds both permission and appop.
+     *
+     * @return {@code null} if the permission and appop are held, otherwise
+     *         returns a string indicating why access was denied.
+     */
+    private boolean checkPermissionAndAppOp(boolean enforce, int pid, int uid, String packageName,
+            String permission, int op) {
+        if (mContext.checkPermission(permission, pid, uid) != PERMISSION_GRANTED) {
+            if (enforce) {
+                throw new SecurityException(
+                        "Permission " + permission + " denied for package " + packageName);
+            } else {
+                return false;
+            }
+        }
+
+        final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+        final int mode = appOps.noteOpNoThrow(op, uid, packageName);
+        switch (mode) {
+            case AppOpsManager.MODE_ALLOWED:
+                return true;
+            case AppOpsManager.MODE_DEFAULT:
+            case AppOpsManager.MODE_IGNORED:
+            case AppOpsManager.MODE_ERRORED:
+                if (enforce) {
+                    throw new SecurityException("Op " + AppOpsManager.opToName(op) + " "
+                            + AppOpsManager.modeToName(mode) + " for package " + packageName);
+                } else {
+                    return false;
+                }
+            default:
+                throw new IllegalStateException(
+                        AppOpsManager.opToName(op) + " has unknown mode "
+                                + AppOpsManager.modeToName(mode));
+        }
+    }
+
+    // Callers must hold both the old and new permissions, so that we can
+    // handle obscure cases like when an app targets Q but was installed on
+    // a device that was originally running on P before being upgraded to Q.
+
+    /** {@hide} */
+    public boolean checkPermissionReadAudio(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_AUDIO, OP_READ_MEDIA_AUDIO)) return false;
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteAudio(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_AUDIO, OP_WRITE_MEDIA_AUDIO)) return false;
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionReadVideo(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_VIDEO, OP_READ_MEDIA_VIDEO)) return false;
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteVideo(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_VIDEO, OP_WRITE_MEDIA_VIDEO)) return false;
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionReadImages(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_IMAGES, OP_READ_MEDIA_IMAGES)) return false;
+        return true;
+    }
+
+    /** {@hide} */
+    public boolean checkPermissionWriteImages(boolean enforce,
+            int pid, int uid, String packageName) {
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
+        if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
+                READ_MEDIA_IMAGES, OP_WRITE_MEDIA_IMAGES)) return false;
+        return true;
+    }
+
     /** {@hide} */
     @VisibleForTesting
     public @NonNull ParcelFileDescriptor openProxyFileDescriptor(
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index 61511aa..55fae30 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -472,7 +472,7 @@
                 @NonNull UserHandle user) {
             super(context, SERVICE_INTERFACE, componentName, user.getIdentifier(),
                     service -> Log.e(TAG, "RemoteService " + service + " died"),
-                    context.getMainThreadHandler(), false, false, 1);
+                    context.getMainThreadHandler(), 0, false, 1);
         }
 
         /**
diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java
index 015146466..9085fa2 100644
--- a/core/java/android/preference/SeekBarVolumizer.java
+++ b/core/java/android/preference/SeekBarVolumizer.java
@@ -111,7 +111,7 @@
 
     @UnsupportedAppUsage
     public SeekBarVolumizer(Context context, int streamType, Uri defaultUri, Callback callback) {
-        this(context, streamType, defaultUri, callback, false /* playSample */);
+        this(context, streamType, defaultUri, callback, true /* playSample */);
     }
 
     public SeekBarVolumizer(
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/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java
index c351d89..aeb186b 100644
--- a/core/java/android/service/carrier/CarrierService.java
+++ b/core/java/android/service/carrier/CarrierService.java
@@ -114,9 +114,7 @@
      * this UX, so a carrier app must be sure to call with active set to false
      * sometime after calling with it set to true.
      * <p>
-     * Requires Permission:
-     *   {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
-     * or the calling app has carrier privileges.
+     * Requires Permission: calling app has carrier privileges.
      *
      * @param active Whether the carrier network change is or shortly will be
      *               active. Set this value to true to begin showing
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
index fb07aba..7a35b9e 100644
--- a/core/java/android/service/contentcapture/ContentCaptureService.java
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -39,6 +39,7 @@
 import android.util.ArrayMap;
 import android.util.Log;
 import android.util.Slog;
+import android.view.contentcapture.ContentCaptureCondition;
 import android.view.contentcapture.ContentCaptureContext;
 import android.view.contentcapture.ContentCaptureEvent;
 import android.view.contentcapture.ContentCaptureManager;
@@ -216,6 +217,32 @@
         }
     }
 
+    /**
+     * Explicitly sets the conditions for which content capture should be available by an app.
+     *
+     * <p>Typically used to restrict content capture to a few websites on browser apps. Example:
+     *
+     * <code>
+     *   ArraySet<ContentCaptureCondition> conditions = new ArraySet<>(1);
+     *   conditions.add(new ContentCaptureCondition(new LocusId("^https://.*\\.example\\.com$"),
+     *       ContentCaptureCondition.FLAG_IS_REGEX));
+     *   service.setContentCaptureConditions("com.example.browser_app", conditions);
+     *
+     * </code>
+     *
+     * <p>NOTE: </p> this method doesn't automatically disable content capture for the given
+     * conditions; it's up to the {@code packageName} implementation to call
+     * {@link ContentCaptureManager#getContentCaptureConditions()} and disable it accordingly.
+     *
+     * @param packageName name of the packages where the restrictions are set.
+     * @param conditions list of conditions, or {@code null} to reset the conditions for the
+     * package.
+     */
+    public final void setContentCaptureConditions(@NonNull String packageName,
+            @Nullable Set<ContentCaptureCondition> conditions) {
+        // TODO(b/129267994): implement
+    }
+
     private <T> ArrayList<T> toList(@Nullable Set<T> set) {
         return set == null ? null : new ArrayList<T>(set);
     }
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/android/view/accessibility/AccessibilityCache.java b/core/java/android/view/accessibility/AccessibilityCache.java
index df8690d..f9e601f 100644
--- a/core/java/android/view/accessibility/AccessibilityCache.java
+++ b/core/java/android/view/accessibility/AccessibilityCache.java
@@ -105,11 +105,7 @@
                 Log.i(LOG_TAG, "Caching window: " + window.getId());
             }
             final int windowId = window.getId();
-            AccessibilityWindowInfo oldWindow = mWindowCache.get(windowId);
-            if (oldWindow != null) {
-                oldWindow.recycle();
-            }
-            mWindowCache.put(windowId, AccessibilityWindowInfo.obtain(window));
+            mWindowCache.put(windowId, new AccessibilityWindowInfo(window));
         }
     }
 
@@ -225,7 +221,7 @@
             if (info != null) {
                 // Return a copy since the client calls to AccessibilityNodeInfo#recycle()
                 // will wipe the data of the cached info.
-                info = AccessibilityNodeInfo.obtain(info);
+                info = new AccessibilityNodeInfo(info);
             }
             if (DEBUG) {
                 Log.i(LOG_TAG, "get(" + accessibilityNodeId + ") = " + info);
@@ -257,7 +253,7 @@
                 List<AccessibilityWindowInfo> windows = new ArrayList<>(sortedWindowCount);
                 for (int i = sortedWindowCount - 1; i >= 0; i--) {
                     AccessibilityWindowInfo window = sortedWindows.valueAt(i);
-                    windows.add(AccessibilityWindowInfo.obtain(window));
+                    windows.add(new AccessibilityWindowInfo(window));
                     sortedWindows.removeAt(i);
                 }
 
@@ -271,7 +267,7 @@
         synchronized (mLock) {
             AccessibilityWindowInfo window = mWindowCache.get(windowId);
             if (window != null) {
-               return AccessibilityWindowInfo.obtain(window);
+                return new AccessibilityWindowInfo(window);
             }
             return null;
         }
@@ -326,14 +322,12 @@
                 final long oldParentId = oldInfo.getParentNodeId();
                 if (info.getParentNodeId() != oldParentId) {
                     clearSubTreeLocked(windowId, oldParentId);
-                } else {
-                    oldInfo.recycle();
                 }
            }
 
             // Cache a copy since the client calls to AccessibilityNodeInfo#recycle()
             // will wipe the data of the cached info.
-            AccessibilityNodeInfo clone = AccessibilityNodeInfo.obtain(info);
+            AccessibilityNodeInfo clone = new AccessibilityNodeInfo(info);
             nodes.put(sourceId, clone);
             if (clone.isAccessibilityFocused()) {
                 if (mAccessibilityFocus != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
@@ -371,12 +365,7 @@
     }
 
     private void clearWindowCache() {
-        final int windowCount = mWindowCache.size();
-        for (int i = windowCount - 1; i >= 0; i--) {
-            AccessibilityWindowInfo window = mWindowCache.valueAt(i);
-            window.recycle();
-            mWindowCache.removeAt(i);
-        }
+        mWindowCache.clear();
         mIsAllWindowsCached = false;
     }
 
@@ -391,13 +380,6 @@
         if (nodes == null) {
             return;
         }
-        // Recycle the nodes before clearing the cache.
-        final int nodeCount = nodes.size();
-        for (int i = nodeCount - 1; i >= 0; i--) {
-            AccessibilityNodeInfo info = nodes.valueAt(i);
-            nodes.removeAt(i);
-            info.recycle();
-        }
         mNodeCache.remove(windowId);
     }
 
@@ -440,11 +422,9 @@
         for (int i = 0; i < childCount; i++) {
             final long childNodeId = current.getChildId(i);
             if (clearSubTreeRecursiveLocked(nodes, childNodeId)) {
-                current.recycle();
                 return true;
             }
         }
-        current.recycle();
         return false;
     }
 
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index a8a787e..385d491 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -654,6 +654,7 @@
      */
     private static final int VIRTUAL_DESCENDANT_ID_SHIFT = 32;
 
+    // TODO(b/129300068): Remove sNumInstancesInUse.
     private static AtomicInteger sNumInstancesInUse;
 
     /**
@@ -766,6 +767,11 @@
         /* do nothing */
     }
 
+    /** @hide */
+    AccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        init(info);
+    }
+
     /**
      * Sets the source.
      * <p>
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 4383f8a..1e2321c 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -96,6 +96,7 @@
     private static final int MAX_POOL_SIZE = 10;
     private static final SynchronizedPool<AccessibilityWindowInfo> sPool =
             new SynchronizedPool<AccessibilityWindowInfo>(MAX_POOL_SIZE);
+    // TODO(b/129300068): Remove sNumInstancesInUse.
     private static AtomicInteger sNumInstancesInUse;
 
     // Data.
@@ -115,6 +116,11 @@
         /* do nothing - hide constructor */
     }
 
+    /** @hide */
+    AccessibilityWindowInfo(AccessibilityWindowInfo info) {
+        init(info);
+    }
+
     /**
      * Gets the title of the window.
      *
@@ -448,26 +454,7 @@
      */
     public static AccessibilityWindowInfo obtain(AccessibilityWindowInfo info) {
         AccessibilityWindowInfo infoClone = obtain();
-
-        infoClone.mType = info.mType;
-        infoClone.mLayer = info.mLayer;
-        infoClone.mBooleanProperties = info.mBooleanProperties;
-        infoClone.mId = info.mId;
-        infoClone.mParentId = info.mParentId;
-        infoClone.mBoundsInScreen.set(info.mBoundsInScreen);
-        infoClone.mTitle = info.mTitle;
-        infoClone.mAnchorId = info.mAnchorId;
-
-        if (info.mChildIds != null && info.mChildIds.size() > 0) {
-            if (infoClone.mChildIds == null) {
-                infoClone.mChildIds = info.mChildIds.clone();
-            } else {
-                infoClone.mChildIds.addAll(info.mChildIds);
-            }
-        }
-
-        infoClone.mConnectionId = info.mConnectionId;
-
+        infoClone.init(info);
         return infoClone;
     }
 
@@ -529,6 +516,32 @@
         parcel.writeInt(mConnectionId);
     }
 
+    /**
+     * Initializes this instance from another one.
+     *
+     * @param other The other instance.
+     */
+    private void init(AccessibilityWindowInfo other) {
+        mType = other.mType;
+        mLayer = other.mLayer;
+        mBooleanProperties = other.mBooleanProperties;
+        mId = other.mId;
+        mParentId = other.mParentId;
+        mBoundsInScreen.set(other.mBoundsInScreen);
+        mTitle = other.mTitle;
+        mAnchorId = other.mAnchorId;
+
+        if (other.mChildIds != null && other.mChildIds.size() > 0) {
+            if (mChildIds == null) {
+                mChildIds = other.mChildIds.clone();
+            } else {
+                mChildIds.addAll(other.mChildIds);
+            }
+        }
+
+        mConnectionId = other.mConnectionId;
+    }
+
     private void initFromParcel(Parcel parcel) {
         mType = parcel.readInt();
         mLayer = parcel.readInt();
diff --git a/core/java/android/view/contentcapture/ContentCaptureCondition.java b/core/java/android/view/contentcapture/ContentCaptureCondition.java
new file mode 100644
index 0000000..ed87257
--- /dev/null
+++ b/core/java/android/view/contentcapture/ContentCaptureCondition.java
@@ -0,0 +1,106 @@
+/*
+ * 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.view.contentcapture;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.LocusId;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Defines a condition for when content capture should be allowed.
+ *
+ * <p>See {@link ContentCaptureManager#getContentCaptureConditions()} for more.
+ */
+public final class ContentCaptureCondition implements Parcelable {
+
+    /**
+     * When set, package should use the {@link LocusId#getId()} as a regular expression.
+     */
+    public static final int FLAG_IS_REGEX = 0x2;
+
+    /** @hide */
+    @IntDef(prefix = { "FLAG" }, flag = true, value = {
+            FLAG_IS_REGEX
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface Flags {}
+
+    private final @NonNull LocusId mLocusId;
+    private final @Flags int mFlags;
+
+    /**
+     * Default constructor.
+     *
+     * @param locusId id of the condition, as defined by
+     * {@link ContentCaptureContext#getLocusId()}.
+     * @param flags either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
+     */
+    public ContentCaptureCondition(@NonNull LocusId locusId, @Flags int flags) {
+        this.mLocusId = Preconditions.checkNotNull(locusId);
+        this.mFlags = flags;
+        // TODO(b/129267994): check flags, add test case for null and invalid flags
+    }
+
+    /**
+     * Gets the {@code LocusId} per se.
+     */
+    @NonNull
+    public LocusId getLocusId() {
+        return mLocusId;
+    }
+
+    /**
+     * Gets the flags associates with this condition.
+     *
+     * @return either {@link ContentCaptureCondition#FLAG_IS_REGEX} or {@code 0}.
+     */
+    public @Flags int getFlags() {
+        return mFlags;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int flags) {
+        parcel.writeParcelable(mLocusId, flags);
+        parcel.writeInt(mFlags);
+    }
+
+    public static final @NonNull Parcelable.Creator<ContentCaptureCondition> CREATOR =
+            new Parcelable.Creator<ContentCaptureCondition>() {
+
+                @Override
+                public ContentCaptureCondition createFromParcel(@NonNull Parcel parcel) {
+                    return new ContentCaptureCondition(parcel.readParcelable(null),
+                            parcel.readInt());
+                }
+
+                @Override
+                public ContentCaptureCondition[] newArray(int size) {
+                    return new ContentCaptureCondition[size];
+                }
+    };
+}
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 9e546a8..817b130 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -43,6 +43,7 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.Set;
 
 /**
  * TODO(b/123577059): add javadocs / mention it can be null
@@ -362,6 +363,20 @@
     }
 
     /**
+     * Gets the list of conditions for when content capture should be allowed.
+     *
+     * <p>This method is typically used by web browsers so they don't generate unnecessary content
+     * capture events for websites the content capture service is not interested on.
+     *
+     * @return list of conditions, or {@code null} if the service didn't set any restriction
+     * (in which case content capture events should always be generated).
+     */
+    @Nullable
+    public Set<ContentCaptureCondition> getContentCaptureConditions() {
+        return null; // TODO(b/129267994): implement
+    }
+
+    /**
      * Called by apps to explicitly enable or disable content capture.
      *
      * <p><b>Note: </b> this call is not persisted accross reboots, so apps should typically call
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index b5020ce..5be0e3f 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -133,10 +133,11 @@
     void readColor(int id, @ColorInt int value);
 
     /**
-     * Read a color packed into a {@link ColorLong} as a property.
+     * Read a color packed into a {@code ColorLong} as a property.
      *
      * @param id Identifier of the property from a {@link PropertyMapper}
-     * @param value Value of the property
+     * @param value Value of the property packed as a {@code ColorLong}. See the
+     *              {@link Color} class for details of the packing.
      * @throws PropertyTypeMismatchException If the property ID is not mapped as a color
      */
     void readColor(int id, @ColorLong long value);
diff --git a/core/java/com/android/internal/app/AbstractResolverComparator.java b/core/java/com/android/internal/app/AbstractResolverComparator.java
index 3576b6b..e091aac 100644
--- a/core/java/com/android/internal/app/AbstractResolverComparator.java
+++ b/core/java/com/android/internal/app/AbstractResolverComparator.java
@@ -1,7 +1,15 @@
 package com.android.internal.app;
 
+import android.app.usage.UsageStatsManager;
 import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.UserHandle;
+import android.util.Log;
 import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
+import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 
@@ -10,20 +18,102 @@
  */
 abstract class AbstractResolverComparator implements Comparator<ResolvedComponentInfo> {
 
+    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;
+
     protected AfterCompute mAfterCompute;
+    protected final PackageManager mPm;
+    protected final UsageStatsManager mUsm;
+    protected String[] mAnnotations;
+    protected String mContentType;
+
+    // True if the current share is a link.
+    private final boolean mHttp;
+    // can be null if mHttp == false or current user has no default browser package
+    private final String mDefaultBrowserPackageName;
+
+    AbstractResolverComparator(Context context, Intent intent) {
+        String scheme = intent.getScheme();
+        mHttp = "http".equals(scheme) || "https".equals(scheme);
+        mContentType = intent.getType();
+        getContentAnnotations(intent);
+
+        mPm = context.getPackageManager();
+        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
+        mDefaultBrowserPackageName = mHttp
+                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
+                : null;
+    }
+
+    // get annotations of content from intent.
+    private void getContentAnnotations(Intent intent) {
+        ArrayList<String> annotations = intent.getStringArrayListExtra(
+                Intent.EXTRA_CONTENT_ANNOTATIONS);
+        if (annotations != null) {
+            int size = annotations.size();
+            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
+                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
+            }
+            mAnnotations = new String[size];
+            for (int i = 0; i < size; i++) {
+                mAnnotations[i] = annotations.get(i);
+            }
+        }
+    }
 
     /**
      * Callback to be called when {@link #compute(List)} finishes. This signals to stop waiting.
      */
-    public interface AfterCompute {
+    interface AfterCompute {
 
-        public void afterCompute();
+        void afterCompute();
     }
 
-    public void setCallBack(AfterCompute afterCompute) {
+    void setCallBack(AfterCompute afterCompute) {
         mAfterCompute = afterCompute;
     }
 
+    @Override
+    public final int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
+        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
+        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
+
+        // We want to put the one targeted to another user at the end of the dialog.
+        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
+            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
+        }
+        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
+            return -1;
+        }
+
+        if (mHttp) {
+            // Special case: we want filters that match URI paths/schemes to be
+            // ordered before others.  This is for the case when opening URIs,
+            // to make native apps go above browsers - except for 1 even more special case
+            // which is the default browser, as we want that to go above them all.
+            if (isDefaultBrowser(lhs)) {
+                return -1;
+            }
+
+            if (isDefaultBrowser(rhs)) {
+                return 1;
+            }
+            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
+            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
+            if (lhsSpecific != rhsSpecific) {
+                return lhsSpecific ? -1 : 1;
+            }
+        }
+        return compare(lhs, rhs);
+    }
+
+    /**
+     * Delegated to when used as a {@link Comparator<ResolvedComponentInfo>} if there is not a
+     * special case. The {@link ResolveInfo ResolveInfos} are the first {@link ResolveInfo} in
+     * {@link ResolvedComponentInfo#getResolveInfoAt(int)} from the parameters of {@link
+     * #compare(ResolvedComponentInfo, ResolvedComponentInfo)}
+     */
+    abstract int compare(ResolveInfo lhs, ResolveInfo rhs);
+
     /**
      * Computes features for each target. This will be called before calls to {@link
      * #getScore(ComponentName)} or {@link #compare(Object, Object)}, in order to prepare the
@@ -31,19 +121,22 @@
      * ComponentName}, so the implementation will have to be prepared to identify a {@link
      * ResolvedComponentInfo} by {@link ComponentName}.
      */
-    public abstract void compute(List<ResolvedComponentInfo> targets);
+    abstract void compute(List<ResolvedComponentInfo> targets);
 
     /**
      * Returns the score that was calculated for the corresponding {@link ResolvedComponentInfo}
      * when {@link #compute(List)} was called before this.
      */
-    public abstract float getScore(ComponentName name);
+    abstract float getScore(ComponentName name);
 
     /**
      * Reports to UsageStats what was chosen.
      */
-    // TODO(b/129014961) Move implemetation here and make final.
-    public abstract void updateChooserCounts(String packageName, int userId, String action);
+    final void updateChooserCounts(String packageName, int userId, String action) {
+        if (mUsm != null) {
+            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
+        }
+    }
 
     /**
      * Updates the model used to rank the componentNames.
@@ -53,11 +146,25 @@
      *
      * @param componentName the component that the user clicked
      */
-    public void updateModel(ComponentName componentName) {
+    void updateModel(ComponentName componentName) {
     }
 
     /**
      * Called when the {@link ResolverActivity} is destroyed.
      */
-    public abstract void destroy();
+    abstract void destroy();
+
+    private boolean isDefaultBrowser(ResolveInfo ri) {
+        // It makes sense to prefer the default browser
+        // only if the targeted user is the current user
+        if (ri.targetUserId != UserHandle.USER_CURRENT) {
+            return false;
+        }
+
+        if (ri.activityInfo.packageName != null
+                    && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
+            return true;
+        }
+        return false;
+    }
 }
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/ResolverRankerServiceResolverComparator.java b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
index a88a80f..9bf4f01 100644
--- a/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
+++ b/core/java/com/android/internal/app/ResolverRankerServiceResolverComparator.java
@@ -60,8 +60,6 @@
 
     private static final boolean DEBUG = false;
 
-    private static final int NUM_OF_TOP_ANNOTATIONS_TO_USE = 3;
-
     // One week
     private static final long USAGE_STATS_PERIOD = 1000 * 60 * 60 * 24 * 7;
 
@@ -80,11 +78,6 @@
     private static final int WATCHDOG_TIMEOUT_MILLIS = 500;
 
     private final Collator mCollator;
-    private final boolean mHttp;
-    // can be null if mHttp == false or current user has no default browser package
-    private final String mDefaultBrowserPackageName;
-    private final PackageManager mPm;
-    private final UsageStatsManager mUsm;
     private final Map<String, UsageStats> mStats;
     private final long mCurrentTime;
     private final long mSinceTime;
@@ -92,8 +85,6 @@
     private final String mReferrerPackage;
     private final Object mLock = new Object();
     private ArrayList<ResolverTarget> mTargets;
-    private String mContentType;
-    private String[] mAnnotations;
     private String mAction;
     private ComponentName mResolvedRankerName;
     private ComponentName mRankerServiceName;
@@ -155,43 +146,17 @@
 
     public ResolverRankerServiceResolverComparator(Context context, Intent intent,
                 String referrerPackage, AfterCompute afterCompute) {
+        super(context, intent);
         mCollator = Collator.getInstance(context.getResources().getConfiguration().locale);
-        String scheme = intent.getScheme();
-        mHttp = "http".equals(scheme) || "https".equals(scheme);
         mReferrerPackage = referrerPackage;
         mAfterCompute = afterCompute;
         mContext = context;
 
-        mPm = context.getPackageManager();
-        mUsm = (UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
-
         mCurrentTime = System.currentTimeMillis();
         mSinceTime = mCurrentTime - USAGE_STATS_PERIOD;
         mStats = mUsm.queryAndAggregateUsageStats(mSinceTime, mCurrentTime);
-        mContentType = intent.getType();
-        getContentAnnotations(intent);
         mAction = intent.getAction();
         mRankerServiceName = new ComponentName(mContext, this.getClass());
-
-        mDefaultBrowserPackageName = mHttp
-                ? mPm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId())
-                : null;
-    }
-
-    // get annotations of content from intent.
-    private void getContentAnnotations(Intent intent) {
-        ArrayList<String> annotations = intent.getStringArrayListExtra(
-                Intent.EXTRA_CONTENT_ANNOTATIONS);
-        if (annotations != null) {
-            int size = annotations.size();
-            if (size > NUM_OF_TOP_ANNOTATIONS_TO_USE) {
-                size = NUM_OF_TOP_ANNOTATIONS_TO_USE;
-            }
-            mAnnotations = new String[size];
-            for (int i = 0; i < size; i++) {
-                mAnnotations[i] = annotations.get(i);
-            }
-        }
     }
 
     // compute features for each target according to usage stats of targets.
@@ -286,36 +251,7 @@
     }
 
     @Override
-    public int compare(ResolvedComponentInfo lhsp, ResolvedComponentInfo rhsp) {
-        final ResolveInfo lhs = lhsp.getResolveInfoAt(0);
-        final ResolveInfo rhs = rhsp.getResolveInfoAt(0);
-
-        // We want to put the one targeted to another user at the end of the dialog.
-        if (lhs.targetUserId != UserHandle.USER_CURRENT) {
-            return rhs.targetUserId != UserHandle.USER_CURRENT ? 0 : 1;
-        }
-        if (rhs.targetUserId != UserHandle.USER_CURRENT) {
-            return -1;
-        }
-
-        if (mHttp) {
-            // Special case: we want filters that match URI paths/schemes to be
-            // ordered before others.  This is for the case when opening URIs,
-            // to make native apps go above browsers - except for 1 even more special case
-            // which is the default browser, as we want that to go above them all.
-            if (isDefaultBrowser(lhs)) {
-                return -1;
-            }
-            if (isDefaultBrowser(rhs)) {
-                return 1;
-            }
-            final boolean lhsSpecific = ResolverActivity.isSpecificUriMatch(lhs.match);
-            final boolean rhsSpecific = ResolverActivity.isSpecificUriMatch(rhs.match);
-            if (lhsSpecific != rhsSpecific) {
-                return lhsSpecific ? -1 : 1;
-            }
-        }
-
+    public int compare(ResolveInfo lhs, ResolveInfo rhs) {
         if (mStats != null) {
             final ResolverTarget lhsTarget = mTargetsDict.get(new ComponentName(
                     lhs.activityInfo.packageName, lhs.activityInfo.name));
@@ -349,13 +285,6 @@
         return 0;
     }
 
-    @Override
-    public void updateChooserCounts(String packageName, int userId, String action) {
-        if (mUsm != null) {
-            mUsm.reportChooserSelection(packageName, userId, mContentType, mAnnotations, action);
-        }
-    }
-
     // update ranking model when the connection to it is valid.
     @Override
     public void updateModel(ComponentName componentName) {
@@ -407,20 +336,6 @@
         }
     }
 
-    private boolean isDefaultBrowser(ResolveInfo ri) {
-        // It makes sense to prefer the default browser
-        // only if the targeted user is the current user
-        if (ri.targetUserId != UserHandle.USER_CURRENT) {
-            return false;
-        }
-
-        if (ri.activityInfo.packageName != null
-                && ri.activityInfo.packageName.equals(mDefaultBrowserPackageName)) {
-            return true;
-        }
-        return false;
-    }
-
     // records metrics for evaluation.
     private void logMetrics(int selectedPos) {
         if (mRankerServiceName != null) {
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/infra/AbstractMultiplePendingRequestsRemoteService.java b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
index 37f61bf..206efa9 100644
--- a/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractMultiplePendingRequestsRemoteService.java
@@ -45,9 +45,9 @@
     public AbstractMultiplePendingRequestsRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
             @NonNull VultureCallback<S> callback, @NonNull Handler handler,
-            boolean bindInstantServiceAllowed, boolean verbose, int initialCapacity) {
-        super(context, serviceInterface, componentName, userId, callback, handler,
-                bindInstantServiceAllowed, verbose);
+            int bindingFlags, boolean verbose, int initialCapacity) {
+        super(context, serviceInterface, componentName, userId, callback, handler, bindingFlags,
+                verbose);
         mInitialCapacity = initialCapacity;
     }
 
diff --git a/core/java/com/android/internal/infra/AbstractRemoteService.java b/core/java/com/android/internal/infra/AbstractRemoteService.java
index 0a83fcc..1155854 100644
--- a/core/java/com/android/internal/infra/AbstractRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractRemoteService.java
@@ -82,7 +82,7 @@
     private final VultureCallback<S> mVultureCallback;
     private final int mUserId;
     private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
-    private final boolean mBindInstantServiceAllowed;
+    private final int mBindingFlags;
     protected I mService;
 
     private boolean mBinding;
@@ -113,7 +113,7 @@
     // NOTE: must be package-protected so this class is not extended outside
     AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
             @NonNull ComponentName componentName, int userId, @NonNull VultureCallback<S> callback,
-            @NonNull Handler handler, boolean bindInstantServiceAllowed, boolean verbose) {
+            @NonNull Handler handler, int bindingFlags, boolean verbose) {
         mContext = context;
         mVultureCallback = callback;
         mVerbose = verbose;
@@ -121,7 +121,7 @@
         mIntent = new Intent(serviceInterface).setComponent(mComponentName);
         mUserId = userId;
         mHandler = new Handler(handler.getLooper());
-        mBindInstantServiceAllowed = bindInstantServiceAllowed;
+        mBindingFlags = bindingFlags;
     }
 
     /**
@@ -264,7 +264,7 @@
             }
         }
         pw.println();
-        pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
+        pw.append(prefix).append("mBindingFlags=").println(mBindingFlags);
         pw.append(prefix).append("idleTimeout=")
             .append(Long.toString(idleTimeout / 1000)).append("s\n");
         pw.append(prefix).append("requestTimeout=");
@@ -407,10 +407,8 @@
         if (mVerbose) Slog.v(mTag, "ensureBound()");
         mBinding = true;
 
-        int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
-        if (mBindInstantServiceAllowed) {
-            flags |= Context.BIND_ALLOW_INSTANT;
-        }
+        final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
+                | mBindingFlags;
 
         final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
                 mHandler, new UserHandle(mUserId));
diff --git a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
index a70fc3e..66bee95 100644
--- a/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
+++ b/core/java/com/android/internal/infra/AbstractSinglePendingRequestRemoteService.java
@@ -44,9 +44,9 @@
     public AbstractSinglePendingRequestRemoteService(@NonNull Context context,
             @NonNull String serviceInterface, @NonNull ComponentName componentName, int userId,
             @NonNull VultureCallback<S> callback, @NonNull Handler handler,
-            boolean bindInstantServiceAllowed, boolean verbose) {
-        super(context, serviceInterface, componentName, userId, callback, handler,
-                bindInstantServiceAllowed, verbose);
+            int bindingFlags, boolean verbose) {
+        super(context, serviceInterface, componentName, userId, callback, handler, bindingFlags,
+                verbose);
     }
 
     @Override // from AbstractRemoteService
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/KernelCpuThreadReader.java b/core/java/com/android/internal/os/KernelCpuThreadReader.java
index 248e026..e4de158 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReader.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReader.java
@@ -32,15 +32,18 @@
 import java.util.function.Predicate;
 
 /**
- * Given a process, will iterate over the child threads of the process, and return the CPU usage
- * statistics for each child thread. The CPU usage statistics contain the amount of time spent in a
- * frequency band.
+ * Iterates over processes, and all threads owned by those processes, and return the CPU usage for
+ * each thread. The CPU usage statistics contain the amount of time spent in a frequency band. CPU
+ * usage is collected using {@link ProcTimeInStateReader}.
+ *
+ * <p>We only collect CPU data for processes and threads that are owned by certain UIDs. These UIDs
+ * are configured via {@link #setUidPredicate}.
  *
  * <p>Frequencies are bucketed together to reduce the amount of data created. This means that we
- * return less frequencies than provided by {@link ProcTimeInStateReader}. The number of
- * frequencies is configurable by {@link #setNumBuckets}. Frequencies are reported as the lowest
- * frequency in that range. Frequencies are spread as evenly as possible across the buckets. The
- * buckets do not cross over the little/big frequencies reported.
+ * return less frequencies than provided by {@link ProcTimeInStateReader}. The number of frequencies
+ * is configurable by {@link #setNumBuckets}. Frequencies are reported as the lowest frequency in
+ * that range. Frequencies are spread as evenly as possible across the buckets. The buckets do not
+ * cross over the little/big frequencies reported.
  *
  * <p>N.B.: In order to bucket across little/big frequencies correctly, we assume that the {@code
  * time_in_state} file contains every little core frequency in ascending order, followed by every
@@ -60,56 +63,39 @@
     private static final String CPU_STATISTICS_FILENAME = "time_in_state";
 
     /**
-     * The name of the file to read process command line invocation from, must be found in
-     * {@code /proc/$PID/}
+     * The name of the file to read process command line invocation from, must be found in {@code
+     * /proc/$PID/}
      */
     private static final String PROCESS_NAME_FILENAME = "cmdline";
 
     /**
-     * The name of the file to read thread name from, must be found in
-     * {@code /proc/$PID/task/$TID}
+     * The name of the file to read thread name from, must be found in {@code /proc/$PID/task/$TID}
      */
     private static final String THREAD_NAME_FILENAME = "comm";
 
-    /**
-     * Glob pattern for the process directory names under {@code proc}
-     */
+    /** Glob pattern for the process directory names under {@code proc} */
     private static final String PROCESS_DIRECTORY_FILTER = "[0-9]*";
 
-    /**
-     * Default process name when the name can't be read
-     */
+    /** Default process name when the name can't be read */
     private static final String DEFAULT_PROCESS_NAME = "unknown_process";
 
-    /**
-     * Default thread name when the name can't be read
-     */
+    /** Default thread name when the name can't be read */
     private static final String DEFAULT_THREAD_NAME = "unknown_thread";
 
-    /**
-     * Default mount location of the {@code proc} filesystem
-     */
+    /** Default mount location of the {@code proc} filesystem */
     private static final Path DEFAULT_PROC_PATH = Paths.get("/proc");
 
-    /**
-     * The initial {@code time_in_state} file for {@link ProcTimeInStateReader}
-     */
+    /** The initial {@code time_in_state} file for {@link ProcTimeInStateReader} */
     private static final Path DEFAULT_INITIAL_TIME_IN_STATE_PATH =
             DEFAULT_PROC_PATH.resolve("self/time_in_state");
 
-    /**
-     * Value returned when there was an error getting an integer ID value (e.g. PID, UID)
-     */
+    /** Value returned when there was an error getting an integer ID value (e.g. PID, UID) */
     private static final int ID_ERROR = -1;
 
-    /**
-     * Thread ID used when reporting CPU used by other threads
-     */
+    /** Thread ID used when reporting CPU used by other threads */
     private static final int OTHER_THREADS_ID = -1;
 
-    /**
-     * Thread name used when reporting CPU used by other threads
-     */
+    /** Thread name used when reporting CPU used by other threads */
     private static final String OTHER_THREADS_NAME = "__OTHER_THREADS";
 
     /**
@@ -124,9 +110,7 @@
      */
     private int mMinimumTotalCpuUsageMillis;
 
-    /**
-     * Where the proc filesystem is mounted
-     */
+    /** Where the proc filesystem is mounted */
     private final Path mProcPath;
 
     /**
@@ -135,14 +119,10 @@
      */
     private int[] mFrequenciesKhz;
 
-    /**
-     * Used to read and parse {@code time_in_state} files
-     */
+    /** Used to read and parse {@code time_in_state} files */
     private final ProcTimeInStateReader mProcTimeInStateReader;
 
-    /**
-     * Used to sort frequencies and usage times into buckets
-     */
+    /** Used to sort frequencies and usage times into buckets */
     private FrequencyBucketCreator mFrequencyBucketCreator;
 
     private final Injector mInjector;
@@ -150,10 +130,9 @@
     /**
      * Create with a path where `proc` is mounted. Used primarily for testing
      *
-     * @param procPath               where `proc` is mounted (to find, see {@code mount | grep
-     *                               ^proc})
+     * @param procPath where `proc` is mounted (to find, see {@code mount | grep ^proc})
      * @param initialTimeInStatePath where the initial {@code time_in_state} file exists to define
-     *                               format
+     *     format
      */
     @VisibleForTesting
     public KernelCpuThreadReader(
@@ -162,7 +141,8 @@
             int minimumTotalCpuUsageMillis,
             Path procPath,
             Path initialTimeInStatePath,
-            Injector injector) throws IOException {
+            Injector injector)
+            throws IOException {
         mUidPredicate = uidPredicate;
         mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
         mProcPath = procPath;
@@ -205,7 +185,7 @@
      * #setUidPredicate}.
      */
     @Nullable
-    public ArrayList<ProcessCpuUsage> getProcessCpuUsageByUids() {
+    public ArrayList<ProcessCpuUsage> getProcessCpuUsage() {
         if (DEBUG) {
             Slog.d(TAG, "Reading CPU thread usages for processes owned by UIDs");
         }
@@ -213,7 +193,7 @@
         final ArrayList<ProcessCpuUsage> processCpuUsages = new ArrayList<>();
 
         try (DirectoryStream<Path> processPaths =
-                     Files.newDirectoryStream(mProcPath, PROCESS_DIRECTORY_FILTER)) {
+                Files.newDirectoryStream(mProcPath, PROCESS_DIRECTORY_FILTER)) {
             for (Path processPath : processPaths) {
                 final int processId = getProcessId(processPath);
                 final int uid = mInjector.getUidForPid(processId);
@@ -231,7 +211,7 @@
                 }
             }
         } catch (IOException e) {
-            Slog.w("Failed to iterate over process paths", e);
+            Slog.w(TAG, "Failed to iterate over process paths", e);
             return null;
         }
 
@@ -248,30 +228,68 @@
     }
 
     /**
-     * Read all of the CPU usage statistics for each child thread of the current process
-     *
-     * @return process CPU usage containing usage of all child threads
+     * Get the CPU frequencies that correspond to the times reported in {@link
+     * ThreadCpuUsage#usageTimesMillis}
      */
     @Nullable
-    public ProcessCpuUsage getCurrentProcessCpuUsage() {
-        return getProcessCpuUsage(mProcPath.resolve("self"), mInjector.myPid(), mInjector.myUid());
+    public int[] getCpuFrequenciesKhz() {
+        return mFrequenciesKhz;
+    }
+
+    /** Set the number of frequency buckets to use */
+    void setNumBuckets(int numBuckets) {
+        if (numBuckets < 1) {
+            Slog.w(TAG, "Number of buckets must be at least 1, but was " + numBuckets);
+            return;
+        }
+        // If `numBuckets` hasn't changed since the last set, do nothing
+        if (mFrequenciesKhz != null && mFrequenciesKhz.length == numBuckets) {
+            return;
+        }
+        mFrequencyBucketCreator =
+                new FrequencyBucketCreator(mProcTimeInStateReader.getFrequenciesKhz(), numBuckets);
+        mFrequenciesKhz =
+                mFrequencyBucketCreator.getBucketMinFrequencies(
+                        mProcTimeInStateReader.getFrequenciesKhz());
+    }
+
+    /** Set the UID predicate for {@link #getProcessCpuUsage} */
+    void setUidPredicate(Predicate<Integer> uidPredicate) {
+        mUidPredicate = uidPredicate;
+    }
+
+    /**
+     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
+     * will not be reported
+     */
+    void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) {
+        if (minimumTotalCpuUsageMillis < 0) {
+            Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis);
+            return;
+        }
+        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
     }
 
     /**
      * Read all of the CPU usage statistics for each child thread of a process
      *
      * @param processPath the {@code /proc} path of the thread
-     * @param processId   the ID of the process
-     * @param uid         the ID of the user who owns the process
+     * @param processId the ID of the process
+     * @param uid the ID of the user who owns the process
      * @return process CPU usage containing usage of all child threads. Null if the process exited
-     * and its {@code proc} directory was removed while collecting information
+     *     and its {@code proc} directory was removed while collecting information
      */
     @Nullable
     private ProcessCpuUsage getProcessCpuUsage(Path processPath, int processId, int uid) {
         if (DEBUG) {
-            Slog.d(TAG, "Reading CPU thread usages with directory " + processPath
-                    + " process ID " + processId
-                    + " and user ID " + uid);
+            Slog.d(
+                    TAG,
+                    "Reading CPU thread usages with directory "
+                            + processPath
+                            + " process ID "
+                            + processId
+                            + " and user ID "
+                            + uid);
         }
 
         int[] filteredThreadsCpuUsage = null;
@@ -305,64 +323,15 @@
 
         // Add the filtered out thread CPU usage under an "other threads" ThreadCpuUsage
         if (filteredThreadsCpuUsage != null) {
-            threadCpuUsages.add(new ThreadCpuUsage(
-                    OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage));
+            threadCpuUsages.add(
+                    new ThreadCpuUsage(
+                            OTHER_THREADS_ID, OTHER_THREADS_NAME, filteredThreadsCpuUsage));
         }
 
         if (DEBUG) {
             Slog.d(TAG, "Read CPU usage of " + threadCpuUsages.size() + " threads");
         }
-        return new ProcessCpuUsage(
-                processId,
-                getProcessName(processPath),
-                uid,
-                threadCpuUsages);
-    }
-
-    /**
-     * Set the number of frequency buckets to use
-     */
-    void setNumBuckets(int numBuckets) {
-        if (numBuckets < 1) {
-            Slog.w(TAG, "Number of buckets must be at least 1, but was " + numBuckets);
-            return;
-        }
-        // If `numBuckets` hasn't changed since the last set, do nothing
-        if (mFrequenciesKhz != null && mFrequenciesKhz.length == numBuckets) {
-            return;
-        }
-        mFrequencyBucketCreator = new FrequencyBucketCreator(
-                mProcTimeInStateReader.getFrequenciesKhz(), numBuckets);
-        mFrequenciesKhz = mFrequencyBucketCreator.getBucketMinFrequencies(
-                mProcTimeInStateReader.getFrequenciesKhz());
-    }
-
-    /**
-     * Set the UID predicate for {@link #getProcessCpuUsageByUids}
-     */
-    void setUidPredicate(Predicate<Integer> uidPredicate) {
-        mUidPredicate = uidPredicate;
-    }
-
-    /**
-     * If a thread has strictly less than {@code minimumTotalCpuUsageMillis} total CPU usage, it
-     * will not be reported
-     */
-    void setMinimumTotalCpuUsageMillis(int minimumTotalCpuUsageMillis) {
-        if (minimumTotalCpuUsageMillis < 0) {
-            Slog.w(TAG, "Negative minimumTotalCpuUsageMillis: " + minimumTotalCpuUsageMillis);
-            return;
-        }
-        mMinimumTotalCpuUsageMillis = minimumTotalCpuUsageMillis;
-    }
-
-    /**
-     * Get the CPU frequencies that correspond to the times reported in
-     * {@link ThreadCpuUsage#usageTimesMillis}
-     */
-    @Nullable
-    public int[] getCpuFrequenciesKhz() {
-        return mFrequenciesKhz;
+        return new ProcessCpuUsage(processId, getProcessName(processPath), uid, threadCpuUsages);
     }
 
     /**
@@ -370,7 +339,7 @@
      *
      * @param threadDirectory the {@code /proc} directory of the thread
      * @return thread CPU usage. Null if the thread exited and its {@code proc} directory was
-     * removed while collecting information
+     *     removed while collecting information
      */
     @Nullable
     private ThreadCpuUsage getThreadCpuUsage(Path threadDirectory) {
@@ -398,27 +367,21 @@
         return new ThreadCpuUsage(threadId, threadName, cpuUsages);
     }
 
-    /**
-     * Get the command used to start a process
-     */
+    /** Get the command used to start a process */
     private String getProcessName(Path processPath) {
         final Path processNamePath = processPath.resolve(PROCESS_NAME_FILENAME);
 
-        final String processName =
-                ProcStatsUtil.readSingleLineProcFile(processNamePath.toString());
+        final String processName = ProcStatsUtil.readSingleLineProcFile(processNamePath.toString());
         if (processName != null) {
             return processName;
         }
         return DEFAULT_PROCESS_NAME;
     }
 
-    /**
-     * Get the name of a thread, given the {@code /proc} path of the thread
-     */
+    /** Get the name of a thread, given the {@code /proc} path of the thread */
     private String getThreadName(Path threadPath) {
         final Path threadNamePath = threadPath.resolve(THREAD_NAME_FILENAME);
-        final String threadName =
-                ProcStatsUtil.readNullSeparatedFile(threadNamePath.toString());
+        final String threadName = ProcStatsUtil.readNullSeparatedFile(threadNamePath.toString());
         if (threadName == null) {
             return DEFAULT_THREAD_NAME;
         }
@@ -441,9 +404,8 @@
         }
     }
 
-    /**
-     * Get the sum of all CPU usage across all frequencies
-     */
+    /** Get the sum of all CPU usage across all frequencies */
+    @SuppressWarnings("ForLoopReplaceableByForEach")
     private static int totalCpuUsage(int[] cpuUsage) {
         int total = 0;
         for (int i = 0; i < cpuUsage.length; i++) {
@@ -452,9 +414,7 @@
         return total;
     }
 
-    /**
-     * Add two CPU frequency usages together
-     */
+    /** Add two CPU frequency usages together */
     private static int[] sumCpuUsage(int[] a, int[] b) {
         int[] summed = new int[a.length];
         for (int i = 0; i < a.length; i++) {
@@ -463,9 +423,7 @@
         return summed;
     }
 
-    /**
-     * Puts frequencies and usage times into buckets
-     */
+    /** Puts frequencies and usage times into buckets */
     @VisibleForTesting
     public static class FrequencyBucketCreator {
         private final int mNumBuckets;
@@ -480,7 +438,7 @@
          * Buckets based of a list of frequencies
          *
          * @param frequencies the frequencies to base buckets off
-         * @param numBuckets  how many buckets to create
+         * @param numBuckets how many buckets to create
          */
         @VisibleForTesting
         public FrequencyBucketCreator(long[] frequencies, int numBuckets) {
@@ -502,20 +460,20 @@
 
             // Ensure that we don't have more buckets than frequencies
             mLittleNumBuckets = Math.min(littleNumBuckets, mBigFrequenciesStartIndex);
-            mBigNumBuckets = Math.min(
-                    bigNumBuckets, frequencies.length - mBigFrequenciesStartIndex);
+            mBigNumBuckets =
+                    Math.min(bigNumBuckets, frequencies.length - mBigFrequenciesStartIndex);
             mNumBuckets = mLittleNumBuckets + mBigNumBuckets;
 
             // Set the size of each little and big bucket. If they have no buckets, the size is zero
-            mLittleBucketSize = mLittleNumBuckets == 0 ? 0 :
-                    mBigFrequenciesStartIndex / mLittleNumBuckets;
-            mBigBucketSize = mBigNumBuckets == 0 ? 0 :
-                    (frequencies.length - mBigFrequenciesStartIndex) / mBigNumBuckets;
+            mLittleBucketSize =
+                    mLittleNumBuckets == 0 ? 0 : mBigFrequenciesStartIndex / mLittleNumBuckets;
+            mBigBucketSize =
+                    mBigNumBuckets == 0
+                            ? 0
+                            : (frequencies.length - mBigFrequenciesStartIndex) / mBigNumBuckets;
         }
 
-        /**
-         * Find the index where frequencies change from little core to big core
-         */
+        /** Find the index where frequencies change from little core to big core */
         @VisibleForTesting
         public static int getBigFrequenciesStartIndex(long[] frequenciesKhz) {
             for (int i = 0; i < frequenciesKhz.length - 1; i++) {
@@ -527,16 +485,14 @@
             return frequenciesKhz.length;
         }
 
-        /**
-         * Get the minimum frequency in each bucket
-         */
+        /** Get the minimum frequency in each bucket */
         @VisibleForTesting
         public int[] getBucketMinFrequencies(long[] frequenciesKhz) {
             Preconditions.checkArgument(frequenciesKhz.length == mNumFrequencies);
             // If there's only one bucket, we bucket everything together so the first bucket is the
             // min frequency
             if (mNumBuckets == 1) {
-                return new int[]{(int) frequenciesKhz[0]};
+                return new int[] {(int) frequenciesKhz[0]};
             }
 
             final int[] bucketMinFrequencies = new int[mNumBuckets];
@@ -561,6 +517,7 @@
          * @return the bucketed usage times
          */
         @VisibleForTesting
+        @SuppressWarnings("ForLoopReplaceableByForEach")
         public int[] getBucketedValues(long[] values) {
             Preconditions.checkArgument(values.length == mNumFrequencies);
             final int[] bucketed = new int[mNumBuckets];
@@ -580,18 +537,18 @@
             }
             // Initialize the big buckets
             for (int i = mBigFrequenciesStartIndex; i < values.length; i++) {
-                final int bucketIndex = Math.min(
-                        mLittleNumBuckets + (i - mBigFrequenciesStartIndex) / mBigBucketSize,
-                        mNumBuckets - 1);
+                final int bucketIndex =
+                        Math.min(
+                                mLittleNumBuckets
+                                        + (i - mBigFrequenciesStartIndex) / mBigBucketSize,
+                                mNumBuckets - 1);
                 bucketed[bucketIndex] += values[i];
             }
             return bucketed;
         }
     }
 
-    /**
-     * CPU usage of a process
-     */
+    /** CPU usage of a process */
     public static class ProcessCpuUsage {
         public final int processId;
         public final String processName;
@@ -610,46 +567,23 @@
         }
     }
 
-    /**
-     * CPU usage of a thread
-     */
+    /** CPU usage of a thread */
     public static class ThreadCpuUsage {
         public final int threadId;
         public final String threadName;
         public final int[] usageTimesMillis;
 
-        ThreadCpuUsage(
-                int threadId,
-                String threadName,
-                int[] usageTimesMillis) {
+        ThreadCpuUsage(int threadId, String threadName, int[] usageTimesMillis) {
             this.threadId = threadId;
             this.threadName = threadName;
             this.usageTimesMillis = usageTimesMillis;
         }
     }
 
-    /**
-     * Used to inject static methods from {@link Process}
-     */
+    /** Used to inject static methods from {@link Process} */
     @VisibleForTesting
     public static class Injector {
-        /**
-         * Get the PID of the current process
-         */
-        public int myPid() {
-            return Process.myPid();
-        }
-
-        /**
-         * Get the UID that owns the current process
-         */
-        public int myUid() {
-            return Process.myUid();
-        }
-
-        /**
-         * Get the UID for the process with ID {@code pid}
-         */
+        /** Get the UID for the process with ID {@code pid} */
         public int getUidForPid(int pid) {
             return Process.getUidForPid(pid);
         }
diff --git a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
index b8dfe0d..3851ce6 100644
--- a/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
+++ b/core/java/com/android/internal/os/KernelCpuThreadReaderSettingsObserver.java
@@ -47,33 +47,29 @@
 public class KernelCpuThreadReaderSettingsObserver extends ContentObserver {
     private static final String TAG = "KernelCpuThreadReaderSettingsObserver";
 
-    /**
-     * The number of frequency buckets to report
-     */
+    /** The number of frequency buckets to report */
     private static final String NUM_BUCKETS_SETTINGS_KEY = "num_buckets";
+
     private static final int NUM_BUCKETS_DEFAULT = 8;
 
-    /**
-     * List of UIDs to report data for
-     */
+    /** List of UIDs to report data for */
     private static final String COLLECTED_UIDS_SETTINGS_KEY = "collected_uids";
+
     private static final String COLLECTED_UIDS_DEFAULT = "0-0;1000-1000";
 
-    /**
-     * Minimum total CPU usage to report
-     */
+    /** Minimum total CPU usage to report */
     private static final String MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY =
             "minimum_total_cpu_usage_millis";
+
     private static final int MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT = 10000;
 
     private final Context mContext;
 
-    @Nullable
-    private final KernelCpuThreadReader mKernelCpuThreadReader;
+    @Nullable private final KernelCpuThreadReader mKernelCpuThreadReader;
 
     /**
-     * @return returns a created {@link KernelCpuThreadReader} that will be modified by any
-     * change in settings, returns null if creation failed
+     * @return returns a created {@link KernelCpuThreadReader} that will be modified by any change
+     *     in settings, returns null if creation failed
      */
     @Nullable
     public static KernelCpuThreadReader getSettingsModifiedReader(Context context) {
@@ -81,10 +77,10 @@
         KernelCpuThreadReaderSettingsObserver settingsObserver =
                 new KernelCpuThreadReaderSettingsObserver(context);
         // Register the observer to listen for setting changes
-        Uri settingsUri =
-                Settings.Global.getUriFor(Settings.Global.KERNEL_CPU_THREAD_READER);
-        context.getContentResolver().registerContentObserver(
-                settingsUri, false, settingsObserver, UserHandle.USER_SYSTEM);
+        Uri settingsUri = Settings.Global.getUriFor(Settings.Global.KERNEL_CPU_THREAD_READER);
+        context.getContentResolver()
+                .registerContentObserver(
+                        settingsUri, false, settingsObserver, UserHandle.USER_SYSTEM);
         // Return the observer's reader
         return settingsObserver.mKernelCpuThreadReader;
     }
@@ -92,10 +88,11 @@
     private KernelCpuThreadReaderSettingsObserver(Context context) {
         super(BackgroundThread.getHandler());
         mContext = context;
-        mKernelCpuThreadReader = KernelCpuThreadReader.create(
-                NUM_BUCKETS_DEFAULT,
-                UidPredicate.fromString(COLLECTED_UIDS_DEFAULT),
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
+        mKernelCpuThreadReader =
+                KernelCpuThreadReader.create(
+                        NUM_BUCKETS_DEFAULT,
+                        UidPredicate.fromString(COLLECTED_UIDS_DEFAULT),
+                        MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT);
     }
 
     @Override
@@ -103,9 +100,7 @@
         updateReader();
     }
 
-    /**
-     * Update the reader with new settings
-     */
+    /** Update the reader with new settings */
     private void updateReader() {
         if (mKernelCpuThreadReader == null) {
             return;
@@ -113,8 +108,10 @@
 
         final KeyValueListParser parser = new KeyValueListParser(',');
         try {
-            parser.setString(Settings.Global.getString(
-                    mContext.getContentResolver(), Settings.Global.KERNEL_CPU_THREAD_READER));
+            parser.setString(
+                    Settings.Global.getString(
+                            mContext.getContentResolver(),
+                            Settings.Global.KERNEL_CPU_THREAD_READER));
         } catch (IllegalArgumentException e) {
             Slog.e(TAG, "Bad settings", e);
             return;
@@ -122,8 +119,9 @@
 
         final UidPredicate uidPredicate;
         try {
-            uidPredicate = UidPredicate.fromString(
-                    parser.getString(COLLECTED_UIDS_SETTINGS_KEY, COLLECTED_UIDS_DEFAULT));
+            uidPredicate =
+                    UidPredicate.fromString(
+                            parser.getString(COLLECTED_UIDS_SETTINGS_KEY, COLLECTED_UIDS_DEFAULT));
         } catch (NumberFormatException e) {
             Slog.w(TAG, "Failed to get UID predicate", e);
             return;
@@ -132,14 +130,13 @@
         mKernelCpuThreadReader.setNumBuckets(
                 parser.getInt(NUM_BUCKETS_SETTINGS_KEY, NUM_BUCKETS_DEFAULT));
         mKernelCpuThreadReader.setUidPredicate(uidPredicate);
-        mKernelCpuThreadReader.setMinimumTotalCpuUsageMillis(parser.getInt(
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY,
-                MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT));
+        mKernelCpuThreadReader.setMinimumTotalCpuUsageMillis(
+                parser.getInt(
+                        MINIMUM_TOTAL_CPU_USAGE_MILLIS_SETTINGS_KEY,
+                        MINIMUM_TOTAL_CPU_USAGE_MILLIS_DEFAULT));
     }
 
-    /**
-     * Check whether a UID belongs to a set of UIDs
-     */
+    /** Check whether a UID belongs to a set of UIDs */
     @VisibleForTesting
     public static class UidPredicate implements Predicate<Integer> {
         private static final Pattern UID_RANGE_PATTERN = Pattern.compile("([0-9]+)-([0-9]+)");
@@ -150,14 +147,14 @@
          * Create a UID predicate from a string representing a list of UID ranges
          *
          * <p>UID ranges are a pair of integers separated by a '-'. If you want to specify a single
-         * UID (e.g. UID 1000), you can use {@code 1000-1000}. Lists of ranges are separated by
-         * a single ';'. For example, this would be a valid string representation: {@code
+         * UID (e.g. UID 1000), you can use {@code 1000-1000}. Lists of ranges are separated by a
+         * single ';'. For example, this would be a valid string representation: {@code
          * "1000-1999;2003-2003;2004-2004;2050-2060"}.
          *
          * <p>We do not use ',' to delimit as it is already used in separating different setting
          * arguments.
          *
-         * @throws NumberFormatException    if the input string is incorrectly formatted
+         * @throws NumberFormatException if the input string is incorrectly formatted
          * @throws IllegalArgumentException if an UID range has a lower end than start
          */
         @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -169,9 +166,10 @@
                     throw new NumberFormatException(
                             "Failed to recognize as number range: " + uidSpecifier);
                 }
-                acceptedUidRanges.add(Range.create(
-                        Integer.parseInt(uidRangeMatcher.group(1)),
-                        Integer.parseInt(uidRangeMatcher.group(2))));
+                acceptedUidRanges.add(
+                        Range.create(
+                                Integer.parseInt(uidRangeMatcher.group(1)),
+                                Integer.parseInt(uidRangeMatcher.group(2))));
             }
             return new UidPredicate(acceptedUidRanges);
         }
@@ -181,6 +179,7 @@
         }
 
         @Override
+        @SuppressWarnings("ForLoopReplaceableByForEach")
         public boolean test(Integer uid) {
             for (int i = 0; i < mAcceptedUidRanges.size(); i++) {
                 if (mAcceptedUidRanges.get(i).contains(uid)) {
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/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 992ddd8..8ca0bd1 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -24,6 +24,7 @@
 import android.net.Credentials;
 import android.net.LocalServerSocket;
 import android.net.LocalSocket;
+import android.os.Build;
 import android.os.FactoryTest;
 import android.os.IVold;
 import android.os.Process;
@@ -236,7 +237,7 @@
     public static int forkAndSpecialize(int uid, int gid, int[] gids, int runtimeFlags,
             int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
             int[] fdsToIgnore, boolean startChildZygote, String instructionSet, String appDataDir,
-            String packageName, String[] packagesForUID, String sandboxId) {
+            String packageName, String[] packagesForUID, String sandboxId, int targetSdkVersion) {
         ZygoteHooks.preFork();
         // Resets nice priority for zygote process.
         resetNicePriority();
@@ -246,6 +247,7 @@
                 packagesForUID, sandboxId);
         // Enable tracing as soon as possible for the child process.
         if (pid == 0) {
+            Zygote.disableExecuteOnly(targetSdkVersion);
             Trace.setTracingEnabled(true, runtimeFlags);
 
             // Note that this event ends at the end of handleChildProc,
@@ -514,6 +516,7 @@
     private static Runnable usapMain(LocalServerSocket usapPoolSocket,
                                      FileDescriptor writePipe) {
         final int pid = Process.myPid();
+        Process.setArgV0(Process.is64Bit() ? "usap64" : "usap32");
 
         LocalSocket sessionSocket = null;
         DataOutputStream usapOutputStream = null;
@@ -599,6 +602,8 @@
                            args.mInstructionSet, args.mAppDataDir, args.mPackageName,
                            args.mPackagesForUid, args.mSandboxId);
 
+        disableExecuteOnly(args.mTargetSdkVersion);
+
         if (args.mNiceName != null) {
             Process.setArgV0(args.mNiceName);
         }
@@ -650,6 +655,17 @@
     }
 
     /**
+     * Mark execute-only segments of libraries read+execute for apps with targetSdkVersion<Q.
+     */
+    protected static void disableExecuteOnly(int targetSdkVersion) {
+        if ((targetSdkVersion < Build.VERSION_CODES.Q) && !nativeDisableExecuteOnly()) {
+            Log.e("Zygote", "Failed to set libraries to read+execute.");
+        }
+    }
+
+    private static native boolean nativeDisableExecuteOnly();
+
+    /**
      * @return  Raw file descriptors for the read-end of USAP reporting pipes.
      */
     protected static int[] getUsapPipeFDs() {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 87adce7..dd6fb72 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;
@@ -264,7 +268,7 @@
                 parsedArgs.mRuntimeFlags, rlimits, parsedArgs.mMountExternal, parsedArgs.mSeInfo,
                 parsedArgs.mNiceName, fdsToClose, fdsToIgnore, parsedArgs.mStartChildZygote,
                 parsedArgs.mInstructionSet, parsedArgs.mAppDataDir, parsedArgs.mPackageName,
-                parsedArgs.mPackagesForUid, parsedArgs.mSandboxId);
+                parsedArgs.mPackagesForUid, parsedArgs.mSandboxId, parsedArgs.mTargetSdkVersion);
 
         try {
             if (pid == 0) {
@@ -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/jni/android_hardware_input_InputApplicationHandle.cpp b/core/jni/android_hardware_input_InputApplicationHandle.cpp
index b9301d4..71edfd5 100644
--- a/core/jni/android_hardware_input_InputApplicationHandle.cpp
+++ b/core/jni/android_hardware_input_InputApplicationHandle.cpp
@@ -56,30 +56,25 @@
     JNIEnv* env = AndroidRuntime::getJNIEnv();
     jobject obj = env->NewLocalRef(mObjWeak);
     if (!obj) {
-        releaseInfo();
         return false;
     }
 
-    if (!mInfo) {
-        mInfo = new InputApplicationInfo();
-    }
+    mInfo.name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
 
-    mInfo->name = getStringField(env, obj, gInputApplicationHandleClassInfo.name, "<null>");
-
-    mInfo->dispatchingTimeout = env->GetLongField(obj,
+    mInfo.dispatchingTimeout = env->GetLongField(obj,
             gInputApplicationHandleClassInfo.dispatchingTimeoutNanos);
 
     jobject tokenObj = env->GetObjectField(obj,
             gInputApplicationHandleClassInfo.token);
     if (tokenObj) {
-        mInfo->token = ibinderForJavaObject(env, tokenObj);
+        mInfo.token = ibinderForJavaObject(env, tokenObj);
         env->DeleteLocalRef(tokenObj);
     } else {
-        mInfo->token.clear();
+        mInfo.token.clear();
     }
 
     env->DeleteLocalRef(obj);
-    return true;
+    return mInfo.token.get() != nullptr;
 }
 
 
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index cde1884..70b3436 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -46,6 +46,7 @@
 #include <fcntl.h>
 #include <grp.h>
 #include <inttypes.h>
+#include <link.h>
 #include <malloc.h>
 #include <mntent.h>
 #include <paths.h>
@@ -54,6 +55,7 @@
 #include <sys/capability.h>
 #include <sys/cdefs.h>
 #include <sys/eventfd.h>
+#include <sys/mman.h>
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
@@ -69,6 +71,7 @@
 #include <android-base/properties.h>
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <cutils/fs.h>
 #include <cutils/multiuser.h>
@@ -1975,6 +1978,26 @@
   }
 }
 
+static int disable_execute_only(struct dl_phdr_info *info, size_t size, void *data) {
+  // Search for any execute-only segments and mark them read+execute.
+  for (int i = 0; i < info->dlpi_phnum; i++) {
+    if ((info->dlpi_phdr[i].p_type == PT_LOAD) && (info->dlpi_phdr[i].p_flags == PF_X)) {
+      mprotect(reinterpret_cast<void*>(info->dlpi_addr + info->dlpi_phdr[i].p_vaddr),
+              info->dlpi_phdr[i].p_memsz, PROT_READ | PROT_EXEC);
+    }
+  }
+  // Return non-zero to exit dl_iterate_phdr.
+  return 0;
+}
+
+/**
+ * @param env  Managed runtime environment
+ * @return  True if disable was successful.
+ */
+static jboolean com_android_internal_os_Zygote_nativeDisableExecuteOnly(JNIEnv* env, jclass) {
+  return dl_iterate_phdr(disable_execute_only, nullptr) == 0;
+}
+
 static const JNINativeMethod gMethods[] = {
     { "nativeSecurityInit", "()V",
       (void *) com_android_internal_os_Zygote_nativeSecurityInit },
@@ -2007,7 +2030,9 @@
     { "nativeGetUsapPoolCount", "()I",
       (void *) com_android_internal_os_Zygote_nativeGetUsapPoolCount },
     { "nativeEmptyUsapPool", "()V",
-      (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool }
+      (void *) com_android_internal_os_Zygote_nativeEmptyUsapPool },
+    { "nativeDisableExecuteOnly", "()Z",
+      (void *) com_android_internal_os_Zygote_nativeDisableExecuteOnly }
 };
 
 int register_com_android_internal_os_Zygote(JNIEnv* env) {
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index b4be3f5..0c53fb2 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2319,4 +2319,10 @@
 
     // Settings > Display > Theme
     DARK_UI_SETTINGS = 1698;
+
+    // Settings > global bubble settings
+    BUBBLE_SETTINGS = 1699;
+
+    // Settings > app > bubble settings
+    APP_BUBBLE_SETTINGS = 1700;
 }
diff --git a/core/proto/android/net/OWNERS b/core/proto/android/net/OWNERS
index a845dcb..509699b 100644
--- a/core/proto/android/net/OWNERS
+++ b/core/proto/android/net/OWNERS
@@ -1,5 +1,3 @@
-set noparent
-
 ek@google.com
 lorenzo@google.com
 satk@google.com
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/drawable/ic_bluetooth_share_icon.xml b/core/res/res/drawable/ic_bluetooth_share_icon.xml
new file mode 100644
index 0000000..2446402
--- /dev/null
+++ b/core/res/res/drawable/ic_bluetooth_share_icon.xml
@@ -0,0 +1,27 @@
+<!--
+     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.
+-->
+<!-- This drawable should only be used by the Bluetooth application for its share target icon. -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24"
+    android:tint="@android:color/accent_device_default">
+
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M17.71,7.71L12,2h-1v7.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L11,14.41V22h1l5.71-5.71L13.41,12L17.71,7.71z M13,5.83 l1.88,1.88L13,9.59V5.83z M14.88,16.29L13,18.17v-3.76L14.88,16.29z" />
+</vector>
\ No newline at end of file
diff --git a/core/res/res/drawable/perm_group_aural.xml b/core/res/res/drawable/perm_group_aural.xml
index 0465e98..b2737f2 100644
--- a/core/res/res/drawable/perm_group_aural.xml
+++ b/core/res/res/drawable/perm_group_aural.xml
@@ -19,6 +19,12 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M20,2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2V4c0,-1.1 -0.9,-2 -2,-2zm-2,5h-3v5.5c0,1.38 -1.12,2.5 -2.5,2.5S10,13.88 10,12.5s1.12,-2.5 2.5,-2.5c0.57,0 1.08,0.19 1.5,0.51V5h4v2zM4,6H2v14c0,1.1 0.9,2 2,2h14v-2H4V6z"/>
+        android:fillColor="#000000"
+        android:pathData="M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2z M20,16H8V4h12V16z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M12.5,15c1.38,0,2.5-1.12,2.5-2.5V7h3V5h-4v5.51C13.58,10.19,13.07,10,12.5,10c-1.38,0-2.5,1.12-2.5,2.5S11.12,15,12.5,15z" />
+    <path
+        android:fillColor="#000000"
+        android:pathData="M4,6H2v14c0,1.1,0.9,2,2,2h14v-2H4V6z" />
 </vector>
diff --git a/core/res/res/drawable/perm_group_visual.xml b/core/res/res/drawable/perm_group_visual.xml
index bf9a0b1..9b21c27 100644
--- a/core/res/res/drawable/perm_group_visual.xml
+++ b/core/res/res/drawable/perm_group_visual.xml
@@ -19,6 +19,8 @@
         android:viewportWidth="24.0"
         android:viewportHeight="24.0">
     <path
-        android:fillColor="#FF000000"
-        android:pathData="M22,16V4c0,-1.1 -0.9,-2 -2,-2H8c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2zm-11,-4l2.03,2.71L16,11l4,5H8l3,-4zM2,6v14c0,1.1 0.9,2 2,2h14v-2H4V6H2z"/>
+        android:fillColor="#000000"
+        android:pathData="M20,4v12H8V4H20 M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2L20,2z M2,6v14 c0,1.1,0.9,2,2,2h14v-2H4V6H2z M15.67,11l-2.5,2.98L11.5,11.8L9,15h10L15.67,11z" />
+    <path
+        android:pathData="M0,0h24v24H0V0z" />
 </vector>
diff --git a/core/res/res/values-night/colors_device_defaults.xml b/core/res/res/values-night/colors_device_defaults.xml
new file mode 100644
index 0000000..08ad492
--- /dev/null
+++ b/core/res/res/values-night/colors_device_defaults.xml
@@ -0,0 +1,19 @@
+<?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>
+    <color name="accent_device_default">@color/accent_device_default_dark</color>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 0721f6f..8640510 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -63,9 +63,11 @@
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
     <style name="Theme.DeviceDefault.Dialog.AppError" parent="Theme.DeviceDefault.Dialog.Alert" />
+    <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Dialog.Alert" />
 
     <style name="Theme.DeviceDefault.DayNight" parent="Theme.DeviceDefault" />
 
     <style name="ThemeOverlay.DeviceDefault.Accent.DayNight"
            parent="@style/ThemeOverlay.DeviceDefault.Accent" />
+
 </resources>
\ No newline at end of file
diff --git a/core/res/res/values/colors_device_defaults.xml b/core/res/res/values/colors_device_defaults.xml
index 7209103..5af3c2a 100644
--- a/core/res/res/values/colors_device_defaults.xml
+++ b/core/res/res/values/colors_device_defaults.xml
@@ -35,6 +35,7 @@
 
     <color name="accent_device_default_light">@color/accent_material_light</color>
     <color name="accent_device_default_dark">@color/accent_material_dark</color>
+    <color name="accent_device_default">@color/accent_device_default_light</color>
 
     <color name="background_device_default_dark">@color/background_material_dark</color>
     <color name="background_device_default_light">@color/background_material_light</color>
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/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 9a95ecc..9f20ee6 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -1390,6 +1390,8 @@
         <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
     </style>
 
+    <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
+
     <style name="Theme.DeviceDefault.Light.SearchBar" parent="Theme.Material.Light.SearchBar">
         <!-- Color palette -->
         <item name="colorPrimary">@color/primary_device_default_light</item>
diff --git a/core/tests/coretests/res/raw/com_android_tzdata.apex b/core/tests/coretests/res/raw/com_android_tzdata.apex
index 72294de..06ea8fa 100644
--- a/core/tests/coretests/res/raw/com_android_tzdata.apex
+++ b/core/tests/coretests/res/raw/com_android_tzdata.apex
Binary files differ
diff --git a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
index 52b2658..3d252fb 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ClientTransactionTests.java
@@ -30,6 +30,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link ClientTransaction}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:ClientTransactionTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
index ad28d13..447f28e 100644
--- a/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/ObjectPoolTests.java
@@ -42,6 +42,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link ObjectPool}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:ObjectPoolTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
index f730a24..1cca799 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionExecutorTests.java
@@ -26,9 +26,8 @@
 import static android.app.servertransaction.ActivityLifecycleItem.PRE_ON_CREATE;
 import static android.app.servertransaction.ActivityLifecycleItem.UNDEFINED;
 
-import static junit.framework.Assert.assertEquals;
-
 import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.inOrder;
@@ -61,7 +60,15 @@
 import java.util.Map;
 import java.util.stream.Collectors;
 
-/** Test {@link TransactionExecutor} logic. */
+/**
+ * Test {@link TransactionExecutor} logic.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:TransactionExecutorTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
index d73c174..d117b40 100644
--- a/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
+++ b/core/tests/coretests/src/android/app/servertransaction/TransactionParcelTests.java
@@ -21,8 +21,8 @@
 import static android.app.servertransaction.TestUtils.referrerIntentList;
 import static android.app.servertransaction.TestUtils.resultInfoList;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.app.IApplicationThread;
 import android.app.IInstrumentationWatcher;
@@ -64,7 +64,15 @@
 import java.util.List;
 import java.util.Map;
 
-/** Test parcelling and unparcelling of transactions and transaction items. */
+/**
+ * Test parcelling and unparcelling of transactions and transaction items.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:TransactionParcelTests
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index aa0e0cd..0798c0c 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -500,18 +500,30 @@
         File apexFile = copyRawResourceToFile("com.android.tzdata.apex",
                 R.raw.com_android_tzdata);
         PackageInfo pi = PackageParser.generatePackageInfoFromApex(apexFile, false);
-        assertEquals("com.google.android.tzdata", pi.packageName);
         assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
-        assertEquals(1, pi.getLongVersionCode());
+        assertTrue(pi.applicationInfo.enabled);
+        assertEquals(28, pi.applicationInfo.targetSdkVersion);
         assertEquals(1, pi.applicationInfo.longVersionCode);
+
+        assertEquals("com.google.android.tzdata", pi.packageName);
+        assertTrue(pi.splitNames.length > 0);
+        assertEquals(1, pi.getLongVersionCode());
         assertNull(pi.signingInfo);
+        assertNull(pi.signatures);
+        assertTrue(pi.isApex);
 
         pi = PackageParser.generatePackageInfoFromApex(apexFile, true);
-        assertEquals("com.google.android.tzdata", pi.packageName);
         assertEquals("com.google.android.tzdata", pi.applicationInfo.packageName);
-        assertEquals(1, pi.getLongVersionCode());
+        assertTrue(pi.applicationInfo.enabled);
+        assertEquals(28, pi.applicationInfo.targetSdkVersion);
         assertEquals(1, pi.applicationInfo.longVersionCode);
+
+        assertEquals("com.google.android.tzdata", pi.packageName);
+        assertTrue(pi.splitNames.length > 0);
+        assertEquals(1, pi.getLongVersionCode());
         assertNotNull(pi.signingInfo);
+        assertNotNull(pi.signatures);
         assertTrue(pi.signingInfo.getApkContentsSigners().length > 0);
+        assertTrue(pi.isApex);
     }
 }
diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
index dd50af877..182fe78 100644
--- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java
+++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java
@@ -44,6 +44,15 @@
 import java.util.Arrays;
 import java.util.Collections;
 
+/**
+ * Tests for {@link DisplayCutout}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:DisplayCutoutTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 @Presubmit
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 23ab05e..ebbbdec 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -18,18 +18,15 @@
 
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
 import static android.view.WindowInsets.Type.sideBars;
 import static android.view.WindowInsets.Type.systemBars;
-import static android.view.WindowInsets.Type.topBar;
-import static junit.framework.Assert.assertEquals;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -55,6 +52,15 @@
 
 import java.util.List;
 
+/**
+ * Tests for {@link InsetsAnimationControlImpl}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsAnimationControlImplTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index d71bde83..4d8d3f6 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -19,13 +19,13 @@
 import static android.view.InsetsState.TYPE_IME;
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.WindowInsets.Type.topBar;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.mock;
@@ -53,6 +53,15 @@
 
 import java.util.concurrent.CountDownLatch;
 
+/**
+ * Tests for {@link InsetsController}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsControllerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index 4266ba9f..a32fa77 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -43,6 +43,15 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
+/**
+ * Tests for {@link InsetsSourceConsumer}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsSourceConsumerTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsSourceTest.java b/core/tests/coretests/src/android/view/InsetsSourceTest.java
index 98ab3e7..b55a9c6 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceTest.java
@@ -18,7 +18,7 @@
 
 import static android.view.InsetsState.TYPE_NAVIGATION_BAR;
 
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertEquals;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -31,6 +31,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link InsetsSource}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsSourceTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/InsetsStateTest.java b/core/tests/coretests/src/android/view/InsetsStateTest.java
index bd036b0..8e167da 100644
--- a/core/tests/coretests/src/android/view/InsetsStateTest.java
+++ b/core/tests/coretests/src/android/view/InsetsStateTest.java
@@ -24,14 +24,13 @@
 import static android.view.InsetsState.TYPE_SIDE_BAR_2;
 import static android.view.InsetsState.TYPE_SIDE_BAR_3;
 import static android.view.InsetsState.TYPE_TOP_BAR;
-
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
 
 import android.graphics.Insets;
 import android.graphics.Rect;
@@ -47,6 +46,15 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+/**
+ * Tests for {@link InsetsState}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsStateTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
 @Presubmit
 @FlakyTest(detail = "Promote once confirmed non-flaky")
 @RunWith(AndroidJUnit4.class)
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
index 1cb71f9..1a22a70 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityCacheTest.java
@@ -45,7 +45,6 @@
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
 
 @LargeTest
 @RunWith(AndroidJUnit4.class)
@@ -61,16 +60,12 @@
 
     AccessibilityCache mAccessibilityCache;
     AccessibilityCache.AccessibilityNodeRefresher mAccessibilityNodeRefresher;
-    AtomicInteger mNumA11yNodeInfosInUse = new AtomicInteger(0);
-    AtomicInteger mNumA11yWinInfosInUse = new AtomicInteger(0);
 
     @Before
     public void setUp() {
         mAccessibilityNodeRefresher = mock(AccessibilityCache.AccessibilityNodeRefresher.class);
         when(mAccessibilityNodeRefresher.refreshNode(anyObject(), anyBoolean())).thenReturn(true);
         mAccessibilityCache = new AccessibilityCache(mAccessibilityNodeRefresher);
-        AccessibilityNodeInfo.setNumInstancesInUseCounter(mNumA11yNodeInfosInUse);
-        AccessibilityWindowInfo.setNumInstancesInUseCounter(mNumA11yWinInfosInUse);
     }
 
     @After
@@ -78,8 +73,6 @@
         // Make sure we're recycling all of our window and node infos
         mAccessibilityCache.clear();
         AccessibilityInteractionClient.getInstance().clearCache();
-        assertEquals(0, mNumA11yWinInfosInUse.get());
-        assertEquals(0, mNumA11yNodeInfosInUse.get());
     }
 
     @Test
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
index 1c84829..e9cad0a 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
@@ -35,6 +35,7 @@
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Optional;
 import java.util.OptionalDouble;
 import java.util.concurrent.CountDownLatch;
 import java.util.function.Consumer;
@@ -126,17 +127,21 @@
         final KernelCpuThreadReader kernelCpuThreadReader =
                 KernelCpuThreadReader.create(8, uid -> uid == Process.myUid(), 0);
         assertNotNull(kernelCpuThreadReader);
-        final ProcessCpuUsage currentProcessCpuUsage =
-                kernelCpuThreadReader.getCurrentProcessCpuUsage();
+        kernelCpuThreadReader.setUidPredicate(uid -> uid == Process.myUid());
+        final Optional<ProcessCpuUsage> currentProcessCpuUsage =
+                kernelCpuThreadReader.getProcessCpuUsage().stream()
+                        .filter(p -> p.processId == Process.myPid())
+                        .findFirst();
+        assertTrue(currentProcessCpuUsage.isPresent());
 
         // Threads can terminate, as we've finished crawling them from /proc
         threadFinishedLatch.countDown();
 
         // Check that we've got times for every thread we spawned
-        final List<ThreadCpuUsage> threadCpuUsages = currentProcessCpuUsage.threadCpuUsages
-                .stream()
-                .filter((thread) -> thread.threadName.startsWith(tag))
-                .collect(Collectors.toList());
+        final List<ThreadCpuUsage> threadCpuUsages =
+                currentProcessCpuUsage.get().threadCpuUsages.stream()
+                        .filter((thread) -> thread.threadName.startsWith(tag))
+                        .collect(Collectors.toList());
         assertEquals(
                 "Incorrect number of threads returned by KernelCpuThreadReader",
                 numSamples, threadCpuUsages.size());
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
index e6e7a85..61209e2 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
@@ -25,6 +25,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
+import android.platform.test.annotations.Presubmit;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
@@ -44,27 +45,10 @@
 import java.util.Comparator;
 import java.util.function.Predicate;
 
+@Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class KernelCpuThreadReaderTest {
-
-    private static final int UID = 1000;
-    private static final int PROCESS_ID = 1234;
-    private static final int[] THREAD_IDS = {0, 1000, 1235, 4321};
-    private static final String PROCESS_NAME = "test_process";
-    private static final String[] THREAD_NAMES = {
-            "test_thread_1", "test_thread_2", "test_thread_3", "test_thread_4"
-    };
-    private static final int[] THREAD_CPU_FREQUENCIES = {
-            1000, 2000, 3000, 4000,
-    };
-    private static final int[][] THREAD_CPU_TIMES = {
-            {1, 0, 0, 1},
-            {0, 0, 0, 0},
-            {1000, 1000, 1000, 1000},
-            {0, 1, 2, 3},
-    };
-
     private File mProcDirectory;
 
     @Before
@@ -79,41 +63,6 @@
     }
 
     @Test
-    public void testReader_currentProcess() throws IOException {
-        KernelCpuThreadReader.Injector processUtils =
-                new KernelCpuThreadReader.Injector() {
-                    @Override
-                    public int myPid() {
-                        return PROCESS_ID;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return UID;
-                    }
-
-                    @Override
-                    public int getUidForPid(int pid) {
-                        return 0;
-                    }
-                };
-        setupDirectory(mProcDirectory.toPath().resolve("self"), THREAD_IDS, PROCESS_NAME,
-                THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
-
-        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
-                8,
-                uid -> 1000 <= uid && uid < 2000,
-                0,
-                mProcDirectory.toPath(),
-                mProcDirectory.toPath().resolve("self/task/" + THREAD_IDS[0] + "/time_in_state"),
-                processUtils);
-        final KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
-                kernelCpuThreadReader.getCurrentProcessCpuUsage();
-        checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(), UID, PROCESS_ID,
-                THREAD_IDS, PROCESS_NAME, THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
-    }
-
-    @Test
     public void testReader_byUids() throws IOException {
         int[] uids = new int[]{0, 2, 3, 4, 5, 6000};
         Predicate<Integer> uidPredicate = uid -> uid == 0 || uid >= 4;
@@ -121,16 +70,6 @@
         KernelCpuThreadReader.Injector processUtils =
                 new KernelCpuThreadReader.Injector() {
                     @Override
-                    public int myPid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
                     public int getUidForPid(int pid) {
                         return pid;
                     }
@@ -150,7 +89,7 @@
                 mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
                 processUtils);
         ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
-                kernelCpuThreadReader.getProcessCpuUsageByUids();
+                kernelCpuThreadReader.getProcessCpuUsage();
         processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.processId));
 
         assertEquals(expectedUids.length, processCpuUsageByUids.size());
@@ -173,16 +112,6 @@
         KernelCpuThreadReader.Injector processUtils =
                 new KernelCpuThreadReader.Injector() {
                     @Override
-                    public int myPid() {
-                        return 0;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
                     public int getUidForPid(int pid) {
                         return pid;
                     }
@@ -206,7 +135,7 @@
                 mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
                 processUtils);
         ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
-                kernelCpuThreadReader.getProcessCpuUsageByUids();
+                kernelCpuThreadReader.getProcessCpuUsage();
         processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.uid));
 
         assertEquals(expectedUids.length, processCpuUsageByUids.size());
@@ -220,7 +149,7 @@
 
     @Test
     public void testReader_otherThreads() throws IOException {
-        final Path processPath = mProcDirectory.toPath().resolve("self");
+        final Path processPath = mProcDirectory.toPath().resolve("1000");
         setupDirectory(
                 processPath,
                 new int[]{1, 2, 3},
@@ -228,39 +157,34 @@
                 new String[]{"thread1", "thread2", "thread3"},
                 new int[]{1000, 2000},
                 new int[][]{{0, 100}, {10, 0}, {0, 300}});
-        final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
-                8,
-                i -> true,
-                2000,
-                mProcDirectory.toPath(),
-                processPath.resolve("task/1/time_in_state"),
+        KernelCpuThreadReader.Injector injector =
                 new KernelCpuThreadReader.Injector() {
                     @Override
-                    public int myPid() {
-                        return 1000;
-                    }
-
-                    @Override
-                    public int myUid() {
-                        return 0;
-                    }
-
-                    @Override
                     public int getUidForPid(int pid) {
                         return 0;
                     }
-                });
+                };
+        final KernelCpuThreadReader kernelCpuThreadReader =
+                new KernelCpuThreadReader(
+                        8,
+                        uid -> true,
+                        2000,
+                        mProcDirectory.toPath(),
+                        processPath.resolve("task/1/time_in_state"),
+                        injector);
+        ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
+                kernelCpuThreadReader.getProcessCpuUsage();
+        assertEquals(1, processCpuUsages.size());
         checkResults(
-                kernelCpuThreadReader.getCurrentProcessCpuUsage(),
+                processCpuUsages.get(0),
                 kernelCpuThreadReader.getCpuFrequenciesKhz(),
                 0,
                 1000,
-                new int[]{-1, 3},
+                new int[] {-1, 3},
                 "process",
-                new String[]{"__OTHER_THREADS", "thread3"},
-                new int[]{1000, 2000},
-                new int[][]{{100, 1000}, {0, 3000}}
-        );
+                new String[] {"__OTHER_THREADS", "thread3"},
+                new int[] {1000, 2000},
+                new int[][] {{10, 100}, {0, 300}});
     }
 
     private void setupDirectory(Path processPath, int[] threadIds, String processName,
@@ -289,8 +213,7 @@
             final OutputStream timeInStateStream =
                     Files.newOutputStream(threadPath.resolve("time_in_state"));
             for (int j = 0; j < cpuFrequencies.length; j++) {
-                final String line = String.valueOf(cpuFrequencies[j]) + " "
-                        + String.valueOf(cpuTimes[i][j]) + "\n";
+                final String line = cpuFrequencies[j] + " " + cpuTimes[i][j] + "\n";
                 timeInStateStream.write(line.getBytes());
             }
             timeInStateStream.close();
diff --git a/data/etc/Android.bp b/data/etc/Android.bp
index bb47658..3968f84 100644
--- a/data/etc/Android.bp
+++ b/data/etc/Android.bp
@@ -66,6 +66,14 @@
 }
 
 prebuilt_etc {
+    name: "privapp_whitelist_com.android.emergency",
+    product_specific: true,
+    sub_dir: "permissions",
+    src: "com.android.emergency.xml",
+    filename_from_src: true,
+}
+
+prebuilt_etc {
     name: "privapp_whitelist_com.android.launcher3",
     product_specific: true,
     sub_dir: "permissions",
diff --git a/data/etc/com.android.emergency.xml b/data/etc/com.android.emergency.xml
new file mode 100644
index 0000000..28f99dd
--- /dev/null
+++ b/data/etc/com.android.emergency.xml
@@ -0,0 +1,23 @@
+<?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
+  -->
+<permissions>
+    <privapp-permissions package="com.android.emergency">
+        <!-- Required to place emergency calls from emergency info screen. -->
+        <permission name="android.permission.CALL_PRIVILEGED"/>
+        <permission name="android.permission.MANAGE_USERS"/>
+    </privapp-permissions>
+</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index afb5071..347edc5 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -50,12 +50,6 @@
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
     </privapp-permissions>
 
-    <privapp-permissions package="com.android.emergency">
-        <!-- Required to place emergency calls from emergency info screen. -->
-        <permission name="android.permission.CALL_PRIVILEGED"/>
-        <permission name="android.permission.MANAGE_USERS"/>
-    </privapp-permissions>
-
     <privapp-permissions package="com.android.externalstorage">
         <permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
         <permission name="android.permission.WRITE_MEDIA_STORAGE"/>
@@ -124,6 +118,7 @@
         <permission name="android.permission.REQUEST_INCIDENT_REPORT_APPROVAL"/>
         <permission name="android.permission.APPROVE_INCIDENT_REPORTS"/>
         <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
+        <permission name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
     </privapp-permissions>
 
     <privapp-permissions package="com.android.phone">
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 4bd344f..170dec2 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1813,21 +1813,22 @@
     }
 
     /**
-     * Fills the bitmap's pixels with the specified {@link Color}.
+     * Fills the bitmap's pixels with the specified {@code ColorLong}.
      *
+     * @param color The color to fill as packed by the {@link Color} class.
      * @throws IllegalStateException if the bitmap is not mutable.
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *                                  is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *                                  {@code ColorLong} is invalid or unknown.
      *
      */
-    public void eraseColor(@ColorLong long c) {
+    public void eraseColor(@ColorLong long color) {
         checkRecycled("Can't erase a recycled bitmap");
         if (!isMutable()) {
             throw new IllegalStateException("cannot erase immutable bitmaps");
         }
 
-        ColorSpace cs = Color.colorSpace(c);
-        nativeErase(mNativePtr, cs.getNativeInstance(), c);
+        ColorSpace cs = Color.colorSpace(color);
+        nativeErase(mNativePtr, cs.getNativeInstance(), color);
     }
 
     /**
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 7b3f3da..df64204 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1683,8 +1683,9 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color,
      * using srcover porterduff mode.
      *
-     * @param color the color to draw onto the canvas
-     * @throws IllegalArgumentException if the color space encoded in the long
+     * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+     *              class for details about {@code ColorLong}s.
+     * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
      *                                  is invalid or unknown.
      */
     public void drawColor(@ColorLong long color) {
@@ -1695,7 +1696,7 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * porter-duff xfermode.
      *
-     * @param color the color to draw with
+     * @param color the color to draw onto the canvas
      * @param mode the porter-duff mode to apply to the color
      *
      * @deprecated use {@link #drawColor(int, BlendMode)} instead
@@ -1709,7 +1710,7 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * blendmode.
      *
-     * @param color the color to draw with
+     * @param color the color to draw onto the canvas
      * @param mode the blendmode to apply to the color
      */
     public void drawColor(@ColorInt int color, @NonNull BlendMode mode) {
@@ -1720,9 +1721,10 @@
      * Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
      * blendmode.
      *
-     * @param color the color to draw with
+     * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+     *              class for details about {@code ColorLong}s.
      * @param mode the blendmode to apply to the color
-     * @throws IllegalArgumentException if the color space encoded in the long
+     * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
      *                                  is invalid or unknown.
      */
     public void drawColor(@ColorLong long color, @NonNull BlendMode mode) {
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index c485461..db5f065 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1029,9 +1029,8 @@
      * premultiplied, meaning that alpha can be any value, regardless of the
      * values of r,g,b. See the {@link Color} class for more details.
      *
-     * @see Color for APIs that help manipulate a color long.
-     *
-     * @return the paint's color (and alpha).
+     * @return the paint's color, alpha, and {@code ColorSpace} encoded as a
+     *      {@code ColorLong}
      */
     @ColorLong
     public long getColorLong() {
@@ -1052,7 +1051,7 @@
     }
 
     /**
-     * Set the paint's color with a {@link ColorLong}. Note that the color is
+     * Set the paint's color with a {@code ColorLong}. Note that the color is
      * a long with an encoded {@link ColorSpace} as well as alpha and r,g,b.
      * These values are not premultiplied, meaning that alpha can be any value,
      * regardless of the values of r,g,b. See the {@link Color} class for more
@@ -1060,8 +1059,8 @@
      *
      * @param color The new color (including alpha and {@link ColorSpace})
      *      to set in the paint.
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *      is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *      {@code ColorLong} is invalid or unknown.
      */
     public void setColor(@ColorLong long color) {
         ColorSpace cs = Color.colorSpace(color);
@@ -1491,8 +1490,8 @@
      * The alpha of the shadow will be the paint's alpha if the shadow color is
      * opaque, or the alpha from the shadow color if not.
      *
-     * @throws IllegalArgumentException if the color space encoded in the long
-     *      is invalid or unknown.
+     * @throws IllegalArgumentException if the color space encoded in the
+     *      {@code ColorLong} is invalid or unknown.
      */
     public void setShadowLayer(float radius, float dx, float dy, @ColorLong long shadowColor) {
         ColorSpace cs = Color.colorSpace(shadowColor);
@@ -1559,8 +1558,11 @@
 
     /**
      * Returns the color of the shadow layer.
+     *
+     * @return the shadow layer's color encoded as a {@link ColorLong}.
      * @see #setShadowLayer(float,float,float,int)
      * @see #setShadowLayer(float,float,float,long)
+     * @see Color
      */
     public @ColorLong long getShadowLayerColorLong() {
         return mShadowLayerColor;
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 9b4f2c1..ae7fe6c 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -284,9 +284,10 @@
 
     private static final class CompositePositionUpdateListener implements PositionUpdateListener {
         private final PositionUpdateListener[] mListeners;
+        private static final PositionUpdateListener[] sEmpty = new PositionUpdateListener[0];
 
         CompositePositionUpdateListener(PositionUpdateListener... listeners) {
-            mListeners = listeners;
+            mListeners = listeners != null ? listeners : sEmpty;
         }
 
         public CompositePositionUpdateListener with(PositionUpdateListener listener) {
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/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRoute2Callback.aidl
similarity index 81%
rename from media/java/android/media/session/ControllerCallbackLink.aidl
rename to media/java/android/media/IMediaRoute2Callback.aidl
index 8ee8c7d..f03c8ab 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRoute2Callback.aidl
@@ -13,6 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+/**
+ * @hide
+ */
+oneway interface IMediaRoute2Callback {
+    void onRouteSelected(int uid, String routeId);
+}
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRoute2Provider.aidl
similarity index 72%
copy from media/java/android/media/session/ControllerCallbackLink.aidl
copy to media/java/android/media/IMediaRoute2Provider.aidl
index 8ee8c7d..b97dcc5 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRoute2Provider.aidl
@@ -13,6 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+import android.media.IMediaRoute2Callback;
+
+/**
+ * {@hide}
+ */
+oneway interface IMediaRoute2Provider {
+    void setCallback(IMediaRoute2Callback callback);
+    void selectRoute(int uid, String id);
+}
diff --git a/media/java/android/media/session/ControllerCallbackLink.aidl b/media/java/android/media/IMediaRouter2ManagerClient.aidl
similarity index 73%
copy from media/java/android/media/session/ControllerCallbackLink.aidl
copy to media/java/android/media/IMediaRouter2ManagerClient.aidl
index 8ee8c7d..234551b 100644
--- a/media/java/android/media/session/ControllerCallbackLink.aidl
+++ b/media/java/android/media/IMediaRouter2ManagerClient.aidl
@@ -13,6 +13,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package android.media.session;
 
-parcelable ControllerCallbackLink;
+package android.media;
+
+/**
+ * {@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/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java
index e0e657b..fefb0d7 100644
--- a/media/java/android/media/RingtoneManager.java
+++ b/media/java/android/media/RingtoneManager.java
@@ -29,7 +29,6 @@
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.UserInfo;
 import android.content.res.AssetFileDescriptor;
@@ -40,7 +39,6 @@
 import android.os.FileUtils;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
-import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.UserHandle;
@@ -597,24 +595,14 @@
 
     @UnsupportedAppUsage
     private Cursor getMediaRingtones(Context context) {
-        if (PackageManager.PERMISSION_GRANTED != context.checkPermission(
-                android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                Process.myPid(), Process.myUid())) {
-            Log.w(TAG, "No READ_EXTERNAL_STORAGE permission, ignoring ringtones on ext storage");
-            return null;
-        }
-         // Get the external media cursor. First check to see if it is mounted.
-        final String status = Environment.getExternalStorageState();
-        
-        return (status.equals(Environment.MEDIA_MOUNTED) ||
-                    status.equals(Environment.MEDIA_MOUNTED_READ_ONLY))
-                ? query(
-                    MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
-                    constructBooleanTrueWhereClause(mFilterColumns), null,
-                    MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context)
-                : null;
+        // MediaStore now returns ringtones on other storage devices, even when
+        // we don't have storage or audio permissions
+        return query(
+                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
+                constructBooleanTrueWhereClause(mFilterColumns), null,
+                MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context);
     }
-    
+
     private void setFilterColumnsList(int type) {
         List<String> columns = mFilterColumns;
         columns.clear();
diff --git a/media/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java
deleted file mode 100644
index 67d849a..0000000
--- a/media/java/android/media/session/ControllerCallbackLink.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * 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.session;
-
-import android.Manifest;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.session.MediaController.PlaybackInfo;
-import android.media.session.MediaSession.QueueItem;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.RemoteException;
-
-import java.util.List;
-
-/**
- * Handles incoming commands to {@link MediaController.Callback}.
- * @hide
- */
-public final class ControllerCallbackLink implements Parcelable {
-    final Context mContext;
-    final CallbackStub mCallbackStub;
-    final ISessionControllerCallback mIControllerCallback;
-
-    /**
-     * Constructor for stub (Callee)
-     */
-    public ControllerCallbackLink(@NonNull Context context, @NonNull CallbackStub callbackStub) {
-        mContext = context;
-        mCallbackStub = callbackStub;
-        mIControllerCallback = new CallbackStubProxy();
-    }
-
-    /**
-     * Constructor for interface (Caller)
-     */
-    public ControllerCallbackLink(IBinder binder) {
-        mContext = null;
-        mCallbackStub = null;
-        mIControllerCallback = ISessionControllerCallback.Stub.asInterface(binder);
-    }
-
-    /**
-     * Notify controller that the connected session is destroyed.
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifySessionDestroyed() {
-        try {
-            mIControllerCallback.notifySessionDestroyed();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the connected session sends an event.
-     *
-     * @param event the name of the event
-     * @param extras the extras included with the event
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyEvent(@NonNull String event, @Nullable Bundle extras) {
-        try {
-            mIControllerCallback.notifyEvent(event, extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current playback state is changed.
-     *
-     * @param state the new playback state
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyPlaybackStateChanged(@Nullable PlaybackState state) {
-        try {
-            mIControllerCallback.notifyPlaybackStateChanged(state);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current metadata is changed.
-     *
-     * @param metadata the new metadata
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyMetadataChanged(@Nullable MediaMetadata metadata) {
-        try {
-            mIControllerCallback.notifyMetadataChanged(metadata);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current queue is changed.
-     *
-     * @param queue the new queue
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyQueueChanged(@Nullable List<QueueItem> queue) {
-        try {
-            mIControllerCallback.notifyQueueChanged(queue == null ? null :
-                    new MediaParceledListSlice(queue));
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the current queue title is changed.
-     *
-     * @param title the new queue title
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyQueueTitleChanged(@Nullable CharSequence title) {
-        try {
-            mIControllerCallback.notifyQueueTitleChanged(title);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the extras are changed.
-     *
-     * @param extras the new extras
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyExtrasChanged(@Nullable Bundle extras) {
-        try {
-            mIControllerCallback.notifyExtrasChanged(extras);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Notify controller that the playback info is changed.
-     *
-     * @param info the new playback info
-     */
-    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
-    public void notifyVolumeInfoChanged(@NonNull PlaybackInfo info) {
-        try {
-            mIControllerCallback.notifyVolumeInfoChanged(info);
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /** Gets the binder */
-    @NonNull
-    public IBinder getBinder() {
-        return mIControllerCallback.asBinder();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeStrongBinder(mIControllerCallback.asBinder());
-    }
-
-    public static final @android.annotation.NonNull Parcelable.Creator<ControllerCallbackLink> CREATOR =
-            new Parcelable.Creator<ControllerCallbackLink>() {
-        @Override
-        public ControllerCallbackLink createFromParcel(Parcel in) {
-            return new ControllerCallbackLink(in.readStrongBinder());
-        }
-
-        @Override
-        public ControllerCallbackLink[] newArray(int size) {
-            return new ControllerCallbackLink[size];
-        }
-    };
-
-    /**
-     * Class for Stub implementation
-     */
-    public abstract static class CallbackStub {
-        /** Stub method for ISessionControllerCallback.notifySessionDestroyed */
-        public void onSessionDestroyed() {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyEvent */
-        public void onEvent(@NonNull String event, @Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyPlaybackStateChanged */
-        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyMetadataChanged */
-        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyQueueChanged */
-        public void onQueueChanged(@Nullable List<QueueItem> queue) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyQueueTitleChanged */
-        public void onQueueTitleChanged(@Nullable CharSequence title) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyExtrasChanged */
-        public void onExtrasChanged(@Nullable Bundle extras) {
-        }
-
-        /** Stub method for ISessionControllerCallback.notifyVolumeInfoChanged */
-        public void onVolumeInfoChanged(@NonNull PlaybackInfo info) {
-        }
-    }
-
-    private class CallbackStubProxy extends ISessionControllerCallback.Stub {
-        @Override
-        public void notifyEvent(String event, Bundle extras) {
-            mCallbackStub.onEvent(event, extras);
-        }
-
-        @Override
-        public void notifySessionDestroyed() {
-            mCallbackStub.onSessionDestroyed();
-        }
-
-        @Override
-        public void notifyPlaybackStateChanged(PlaybackState state) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onPlaybackStateChanged(state);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyMetadataChanged(MediaMetadata metadata) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onMetadataChanged(metadata);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyQueueChanged(MediaParceledListSlice queue) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onQueueChanged(queue == null ? null : queue.getList());
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyQueueTitleChanged(CharSequence title) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onQueueTitleChanged(title);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        @Override
-        public void notifyExtrasChanged(Bundle extras) {
-            mCallbackStub.onExtrasChanged(extras);
-        }
-
-        @Override
-        public void notifyVolumeInfoChanged(PlaybackInfo info) {
-            ensureMediaControlPermission();
-            final long token = Binder.clearCallingIdentity();
-            try {
-                mCallbackStub.onVolumeInfoChanged(info);
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
-        }
-
-        private void ensureMediaControlPermission() {
-            // Check if it's system server or has MEDIA_CONTENT_CONTROL.
-            // Note that system server doesn't have MEDIA_CONTENT_CONTROL, so we need extra
-            // check here.
-            if (getCallingUid() == Process.SYSTEM_UID || mContext.checkCallingPermission(
-                    android.Manifest.permission.MEDIA_CONTENT_CONTROL)
-                    == PackageManager.PERMISSION_GRANTED) {
-                return;
-            }
-            throw new SecurityException("Must hold the MEDIA_CONTENT_CONTROL permission.");
-        }
-    }
-}
diff --git a/media/java/android/media/session/ISessionCallback.aidl b/media/java/android/media/session/ISessionCallback.aidl
index 0add1b4..a294088d 100644
--- a/media/java/android/media/session/ISessionCallback.aidl
+++ b/media/java/android/media/session/ISessionCallback.aidl
@@ -17,7 +17,7 @@
 
 import android.content.Intent;
 import android.media.Rating;
-import android.media.session.ControllerCallbackLink;
+import android.media.session.ISessionControllerCallback;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ResultReceiver;
@@ -26,48 +26,48 @@
  * @hide
  */
 oneway interface ISessionCallback {
-    void onCommand(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onCommand(String packageName, int pid, int uid, ISessionControllerCallback caller,
             String command, in Bundle args, in ResultReceiver cb);
     void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent,
             int sequenceNumber, in ResultReceiver cb);
     void onMediaButtonFromController(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, in Intent mediaButtonIntent);
+            ISessionControllerCallback caller, in Intent mediaButtonIntent);
 
     // These callbacks are for the TransportControls
-    void onPrepare(String packageName, int pid, int uid, in ControllerCallbackLink caller);
+    void onPrepare(String packageName, int pid, int uid, ISessionControllerCallback caller);
     void onPrepareFromMediaId(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String mediaId, in Bundle extras);
+            ISessionControllerCallback caller, String mediaId, in Bundle extras);
     void onPrepareFromSearch(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String query, in Bundle extras);
+            ISessionControllerCallback caller, String query, in Bundle extras);
     void onPrepareFromUri(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, in Uri uri, in Bundle extras);
-    void onPlay(String packageName, int pid, int uid, in ControllerCallbackLink caller);
+            ISessionControllerCallback caller, in Uri uri, in Bundle extras);
+    void onPlay(String packageName, int pid, int uid, ISessionControllerCallback caller);
     void onPlayFromMediaId(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String mediaId, in Bundle extras);
+            ISessionControllerCallback caller, String mediaId, in Bundle extras);
     void onPlayFromSearch(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, String query, in Bundle extras);
-    void onPlayFromUri(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+            ISessionControllerCallback caller, String query, in Bundle extras);
+    void onPlayFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void onSkipToTrack(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onSkipToTrack(String packageName, int pid, int uid, ISessionControllerCallback caller,
             long id);
-    void onPause(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onStop(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onNext(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onPrevious(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onFastForward(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onRewind(String packageName, int pid, int uid, in ControllerCallbackLink caller);
-    void onSeekTo(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onPause(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onStop(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onNext(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onPrevious(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onFastForward(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onRewind(String packageName, int pid, int uid, ISessionControllerCallback caller);
+    void onSeekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
             long pos);
-    void onRate(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
             in Rating rating);
     void onSetPlaybackSpeed(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, float speed);
-    void onCustomAction(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+            ISessionControllerCallback caller, float speed);
+    void onCustomAction(String packageName, int pid, int uid, ISessionControllerCallback caller,
             String action, in Bundle args);
 
     // These callbacks are for volume handling
-    void onAdjustVolume(String packageName, int pid, int uid, in ControllerCallbackLink caller,
+    void onAdjustVolume(String packageName, int pid, int uid, ISessionControllerCallback caller,
             int direction);
     void onSetVolumeTo(String packageName, int pid, int uid,
-            in ControllerCallbackLink caller, int value);
+            ISessionControllerCallback caller, int value);
 }
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 298085f..9b1223c 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -20,7 +20,7 @@
 import android.media.MediaMetadata;
 import android.media.MediaParceledListSlice;
 import android.media.Rating;
-import android.media.session.ControllerCallbackLink;
+import android.media.session.ISessionControllerCallback;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState;
@@ -36,12 +36,12 @@
  * @hide
  */
 interface ISessionController {
-    void sendCommand(String packageName, in ControllerCallbackLink caller,
+    void sendCommand(String packageName, in ISessionControllerCallback caller,
             String command, in Bundle args, in ResultReceiver cb);
-    boolean sendMediaButton(String packageName, in ControllerCallbackLink caller,
+    boolean sendMediaButton(String packageName, in ISessionControllerCallback caller,
             in KeyEvent mediaButton);
-    void registerCallback(String packageName, in ControllerCallbackLink cb);
-    void unregisterCallback(in ControllerCallbackLink cb);
+    void registerCallback(String packageName, in ISessionControllerCallback cb);
+    void unregisterCallback(in ISessionControllerCallback cb);
     String getPackageName();
     String getTag();
     Bundle getSessionInfo();
@@ -49,36 +49,36 @@
     long getFlags();
     MediaController.PlaybackInfo getVolumeAttributes();
     void adjustVolume(String packageName, String opPackageName,
-            in ControllerCallbackLink caller, int direction, int flags);
-    void setVolumeTo(String packageName, String opPackageName, in ControllerCallbackLink caller,
+            in ISessionControllerCallback caller, int direction, int flags);
+    void setVolumeTo(String packageName, String opPackageName, in ISessionControllerCallback caller,
             int value, int flags);
 
     // These commands are for the TransportControls
-    void prepare(String packageName, in ControllerCallbackLink caller);
-    void prepareFromMediaId(String packageName, in ControllerCallbackLink caller,
+    void prepare(String packageName, in ISessionControllerCallback caller);
+    void prepareFromMediaId(String packageName, in ISessionControllerCallback caller,
             String mediaId, in Bundle extras);
-    void prepareFromSearch(String packageName, in ControllerCallbackLink caller,
+    void prepareFromSearch(String packageName, in ISessionControllerCallback caller,
             String string, in Bundle extras);
-    void prepareFromUri(String packageName, in ControllerCallbackLink caller,
+    void prepareFromUri(String packageName, in ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void play(String packageName, in ControllerCallbackLink caller);
-    void playFromMediaId(String packageName, in ControllerCallbackLink caller,
+    void play(String packageName, in ISessionControllerCallback caller);
+    void playFromMediaId(String packageName, in ISessionControllerCallback caller,
             String mediaId, in Bundle extras);
-    void playFromSearch(String packageName, in ControllerCallbackLink caller,
+    void playFromSearch(String packageName, in ISessionControllerCallback caller,
             String string, in Bundle extras);
-    void playFromUri(String packageName, in ControllerCallbackLink caller,
+    void playFromUri(String packageName, in ISessionControllerCallback caller,
             in Uri uri, in Bundle extras);
-    void skipToQueueItem(String packageName, in ControllerCallbackLink caller, long id);
-    void pause(String packageName, in ControllerCallbackLink caller);
-    void stop(String packageName, in ControllerCallbackLink caller);
-    void next(String packageName, in ControllerCallbackLink caller);
-    void previous(String packageName, in ControllerCallbackLink caller);
-    void fastForward(String packageName, in ControllerCallbackLink caller);
-    void rewind(String packageName, in ControllerCallbackLink caller);
-    void seekTo(String packageName, in ControllerCallbackLink caller, long pos);
-    void rate(String packageName, in ControllerCallbackLink caller, in Rating rating);
-    void setPlaybackSpeed(String packageName, in ControllerCallbackLink caller, float speed);
-    void sendCustomAction(String packageName, in ControllerCallbackLink caller,
+    void skipToQueueItem(String packageName, in ISessionControllerCallback caller, long id);
+    void pause(String packageName, in ISessionControllerCallback caller);
+    void stop(String packageName, in ISessionControllerCallback caller);
+    void next(String packageName, in ISessionControllerCallback caller);
+    void previous(String packageName, in ISessionControllerCallback caller);
+    void fastForward(String packageName, in ISessionControllerCallback caller);
+    void rewind(String packageName, in ISessionControllerCallback caller);
+    void seekTo(String packageName, in ISessionControllerCallback caller, long pos);
+    void rate(String packageName, in ISessionControllerCallback caller, in Rating rating);
+    void setPlaybackSpeed(String packageName, in ISessionControllerCallback caller, float speed);
+    void sendCustomAction(String packageName, in ISessionControllerCallback caller,
             String action, in Bundle args);
     MediaMetadata getMetadata();
     PlaybackState getPlaybackState();
diff --git a/media/java/android/media/session/ISessionControllerCallback.aidl b/media/java/android/media/session/ISessionControllerCallback.aidl
index 56ae852..f284133 100644
--- a/media/java/android/media/session/ISessionControllerCallback.aidl
+++ b/media/java/android/media/session/ISessionControllerCallback.aidl
@@ -25,14 +25,14 @@
  * @hide
  */
 oneway interface ISessionControllerCallback {
-    void notifyEvent(String event, in Bundle extras);
-    void notifySessionDestroyed();
+    void onEvent(String event, in Bundle extras);
+    void onSessionDestroyed();
 
     // These callbacks are for the TransportController
-    void notifyPlaybackStateChanged(in PlaybackState state);
-    void notifyMetadataChanged(in MediaMetadata metadata);
-    void notifyQueueChanged(in MediaParceledListSlice queue);
-    void notifyQueueTitleChanged(CharSequence title);
-    void notifyExtrasChanged(in Bundle extras);
-    void notifyVolumeInfoChanged(in MediaController.PlaybackInfo info);
+    void onPlaybackStateChanged(in PlaybackState state);
+    void onMetadataChanged(in MediaMetadata metadata);
+    void onQueueChanged(in MediaParceledListSlice queue);
+    void onQueueTitleChanged(CharSequence title);
+    void onExtrasChanged(in Bundle extras);
+    void onVolumeInfoChanged(in MediaController.PlaybackInfo info);
 }
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 036cd78..79d8be1 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -73,7 +73,7 @@
 
     private final MediaSession.Token mToken;
     private final Context mContext;
-    private final ControllerCallbackLink mCbStub;
+    private final CallbackStub mCbStub = new CallbackStub(this);
     private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
     private final Object mLock = new Object();
 
@@ -104,7 +104,6 @@
         mTransportControls = new TransportControls();
         mToken = token;
         mContext = context;
-        mCbStub = new ControllerCallbackLink(context, new CallbackStub(this));
     }
 
     /**
@@ -1065,7 +1064,7 @@
         };
     }
 
-    private static final class CallbackStub extends ControllerCallbackLink.CallbackStub {
+    private static final class CallbackStub extends ISessionControllerCallback.Stub {
         private final WeakReference<MediaController> mController;
 
         CallbackStub(MediaController controller) {
@@ -1105,7 +1104,7 @@
         }
 
         @Override
-        public void onQueueChanged(List<QueueItem> queue) {
+        public void onQueueChanged(MediaParceledListSlice queue) {
             MediaController controller = mController.get();
             if (controller != null) {
                 controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
@@ -1162,7 +1161,8 @@
                     mCallback.onMetadataChanged((MediaMetadata) msg.obj);
                     break;
                 case MSG_UPDATE_QUEUE:
-                    mCallback.onQueueChanged((List<MediaSession.QueueItem>) msg.obj);
+                    mCallback.onQueueChanged(msg.obj == null ? null :
+                            (List<QueueItem>) ((MediaParceledListSlice) msg.obj).getList());
                     break;
                 case MSG_UPDATE_QUEUE_TITLE:
                     mCallback.onQueueTitleChanged((CharSequence) msg.obj);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index aa61a01..c577469 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -1120,7 +1120,7 @@
 
         @Override
         public void onCommand(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
+                ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid),
@@ -1146,7 +1146,7 @@
 
         @Override
         public void onMediaButtonFromController(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Intent mediaButtonIntent) {
+                ISessionControllerCallback caller, Intent mediaButtonIntent) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
@@ -1156,7 +1156,7 @@
 
         @Override
         public void onPrepare(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid));
@@ -1165,7 +1165,7 @@
 
         @Override
         public void onPrepareFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
+                ISessionControllerCallback caller, String mediaId,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1176,7 +1176,7 @@
 
         @Override
         public void onPrepareFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
+                ISessionControllerCallback caller, String query,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1187,7 +1187,7 @@
 
         @Override
         public void onPrepareFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid),
@@ -1197,7 +1197,7 @@
 
         @Override
         public void onPlay(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid));
@@ -1206,7 +1206,7 @@
 
         @Override
         public void onPlayFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
+                ISessionControllerCallback caller, String mediaId,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1217,7 +1217,7 @@
 
         @Override
         public void onPlayFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
+                ISessionControllerCallback caller, String query,
                 Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1228,7 +1228,7 @@
 
         @Override
         public void onPlayFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid),
@@ -1238,7 +1238,7 @@
 
         @Override
         public void onSkipToTrack(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long id) {
+                ISessionControllerCallback caller, long id) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid), id);
@@ -1247,7 +1247,7 @@
 
         @Override
         public void onPause(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPause(createRemoteUserInfo(packageName, pid, uid));
@@ -1256,7 +1256,7 @@
 
         @Override
         public void onStop(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchStop(createRemoteUserInfo(packageName, pid, uid));
@@ -1265,7 +1265,7 @@
 
         @Override
         public void onNext(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchNext(createRemoteUserInfo(packageName, pid, uid));
@@ -1274,7 +1274,7 @@
 
         @Override
         public void onPrevious(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid));
@@ -1283,7 +1283,7 @@
 
         @Override
         public void onFastForward(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid));
@@ -1292,7 +1292,7 @@
 
         @Override
         public void onRewind(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid));
@@ -1301,7 +1301,7 @@
 
         @Override
         public void onSeekTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long pos) {
+                ISessionControllerCallback caller, long pos) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid), pos);
@@ -1309,7 +1309,7 @@
         }
 
         @Override
-        public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 Rating rating) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
@@ -1319,7 +1319,7 @@
 
         @Override
         public void onSetPlaybackSpeed(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, float speed) {
+                ISessionControllerCallback caller, float speed) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSetPlaybackSpeed(
@@ -1329,7 +1329,7 @@
 
         @Override
         public void onCustomAction(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String action, Bundle args) {
+                ISessionControllerCallback caller, String action, Bundle args) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid),
@@ -1339,7 +1339,7 @@
 
         @Override
         public void onAdjustVolume(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int direction) {
+                ISessionControllerCallback caller, int direction) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid),
@@ -1349,7 +1349,7 @@
 
         @Override
         public void onSetVolumeTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int value) {
+                ISessionControllerCallback caller, int value) {
             MediaSession session = mMediaSession.get();
             if (session != null) {
                 session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid),
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/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
index 48cb55b..2e2f3b7 100644
--- a/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
+++ b/packages/CarSystemUI/src/com/android/systemui/notifications/NotificationsUI.java
@@ -54,6 +54,7 @@
 import com.android.systemui.R;
 import com.android.systemui.SystemUI;
 import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.car.CarStatusBar;
 import com.android.systemui.statusbar.policy.ConfigurationController;
 
 /**
@@ -90,6 +91,7 @@
     private FlingAnimationUtils mFlingAnimationUtils;
     private static int sSettleOpenPercentage;
     private static int sSettleClosePercentage;
+    private CarStatusBar mCarStatusBar;
 
     /**
      * Inits the window that hosts the notifications and establishes the connections
@@ -230,6 +232,10 @@
         inflateNotificationContent();
     }
 
+    public void setStatusBar(CarStatusBar carStatusBar) {
+        mCarStatusBar = carStatusBar;
+    }
+
     public View.OnTouchListener getDragDownListener() {
         return mOnTouchListener;
     }
@@ -328,6 +334,9 @@
         @Override
         public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                 float distanceY) {
+            if (mCarStatusBar == null || !mCarStatusBar.getIsUserSetup()) {
+                return true;
+            }
             boolean isDown = event1.getY() - event2.getY() < 0;
             // CarStatusBar and NavigationBar are identical so avoid the touch if it
             // starts from NavigationBar to open.
@@ -442,6 +451,9 @@
      * Sets the notifications to visible
      */
     public void openCarNotifications(float velocityY) {
+        if (mCarStatusBar == null || !mCarStatusBar.getIsUserSetup()) {
+            return;
+        }
         mCarNotificationWindow.setVisibility(View.VISIBLE);
 
         ValueAnimator animator = ValueAnimator.ofFloat(mContent.getTranslationY(), 0);
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 45459fc..abe9be8 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -262,6 +262,7 @@
         topBar.setStatusBar(this);
         CarNavigationBarView qsTopBar = mStatusBarWindow.findViewById(R.id.qs_car_top_bar);
         qsTopBar.setStatusBar(this);
+        getComponent(NotificationsUI.class).setStatusBar(this);
     }
 
     @Override
@@ -614,6 +615,11 @@
         return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
     }
 
+    /** Returns true if the current user makes it through the setup wizard, false otherwise. */
+    public boolean getIsUserSetup(){
+        return mUserSetup;
+    }
+
     public void toggleCarNotifications() {
         getComponent(NotificationsUI.class).toggleShowingCarNotifications();
     }
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
index df2c571..e479e38 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/DynamicSystemInstallationService.java
@@ -49,6 +49,7 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Messenger;
+import android.os.ParcelableException;
 import android.os.PowerManager;
 import android.os.RemoteException;
 import android.os.image.DynamicSystemClient;
@@ -170,13 +171,13 @@
     @Override
     public void onProgressUpdate(long installedSize) {
         mInstalledSize = installedSize;
-        postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED);
+        postStatus(STATUS_IN_PROGRESS, CAUSE_NOT_SPECIFIED, null);
     }
 
     @Override
-    public void onResult(int result) {
+    public void onResult(int result, Throwable detail) {
         if (result == RESULT_OK) {
-            postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED);
+            postStatus(STATUS_READY, CAUSE_INSTALL_COMPLETED, null);
             return;
         }
 
@@ -185,15 +186,15 @@
 
         switch (result) {
             case RESULT_ERROR_IO:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_IO);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_IO, detail);
                 break;
 
             case RESULT_ERROR_INVALID_URL:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_INVALID_URL);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_INVALID_URL, detail);
                 break;
 
             case RESULT_ERROR_EXCEPTION:
-                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_EXCEPTION);
+                postStatus(STATUS_NOT_STARTED, CAUSE_ERROR_EXCEPTION, detail);
                 break;
         }
     }
@@ -201,7 +202,7 @@
     @Override
     public void onCancelled() {
         resetTaskAndStop();
-        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
     }
 
     private void executeInstallCommand(Intent intent) {
@@ -266,7 +267,7 @@
                 Toast.LENGTH_LONG).show();
 
         resetTaskAndStop();
-        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED);
+        postStatus(STATUS_NOT_STARTED, CAUSE_INSTALL_CANCELLED, null);
 
         mDynSystem.remove();
     }
@@ -414,7 +415,7 @@
         return VerificationActivity.isVerified(url);
     }
 
-    private void postStatus(int status, int cause) {
+    private void postStatus(int status, int cause, Throwable detail) {
         Log.d(TAG, "postStatus(): statusCode=" + status + ", causeCode=" + cause);
 
         boolean notifyOnNotificationBar = true;
@@ -433,18 +434,24 @@
 
         for (int i = mClients.size() - 1; i >= 0; i--) {
             try {
-                notifyOneClient(mClients.get(i), status, cause);
+                notifyOneClient(mClients.get(i), status, cause, detail);
             } catch (RemoteException e) {
                 mClients.remove(i);
             }
         }
     }
 
-    private void notifyOneClient(Messenger client, int status, int cause) throws RemoteException {
+    private void notifyOneClient(Messenger client, int status, int cause, Throwable detail)
+            throws RemoteException {
         Bundle bundle = new Bundle();
 
         bundle.putLong(DynamicSystemClient.KEY_INSTALLED_SIZE, mInstalledSize);
 
+        if (detail != null) {
+            bundle.putSerializable(DynamicSystemClient.KEY_EXCEPTION_DETAIL,
+                    new ParcelableException(detail));
+        }
+
         client.send(Message.obtain(null,
                   DynamicSystemClient.MSG_POST_STATUS, status, cause, bundle));
     }
@@ -496,7 +503,7 @@
                     int status = getStatus();
 
                     // tell just registered client my status, but do not specify cause
-                    notifyOneClient(client, status, CAUSE_NOT_SPECIFIED);
+                    notifyOneClient(client, status, CAUSE_NOT_SPECIFIED, null);
 
                     mClients.add(client);
                 } catch (RemoteException e) {
diff --git a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
index 052fc0a..aee5de5 100644
--- a/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
+++ b/packages/DynamicSystemInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
@@ -31,7 +31,7 @@
 import java.util.zip.GZIPInputStream;
 
 
-class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
+class InstallationAsyncTask extends AsyncTask<String, Long, Throwable> {
 
     private static final String TAG = "InstallationAsyncTask";
 
@@ -43,7 +43,6 @@
         }
     }
 
-
     /** Not completed, including being cancelled */
     static final int NO_RESULT = 0;
     static final int RESULT_OK = 1;
@@ -53,7 +52,7 @@
 
     interface InstallStatusListener {
         void onProgressUpdate(long installedSize);
-        void onResult(int resultCode);
+        void onResult(int resultCode, Throwable detail);
         void onCancelled();
     }
 
@@ -84,7 +83,7 @@
     }
 
     @Override
-    protected Integer doInBackground(String... voids) {
+    protected Throwable doInBackground(String... voids) {
         Log.d(TAG, "Start doInBackground(), URL: " + mUrl);
 
         try {
@@ -108,7 +107,7 @@
                 if (isCancelled()) {
                     boolean aborted = mDynSystem.abort();
                     Log.d(TAG, "Called DynamicSystemManager.abort(), result = " + aborted);
-                    return RESULT_OK;
+                    return null;
                 }
 
                 GsiProgress progress = mDynSystem.getInstallationProgress();
@@ -124,10 +123,8 @@
 
 
             if (mInstallationSession == null) {
-                Log.e(TAG, "Failed to start installation with requested size: "
+                throw new IOException("Failed to start installation with requested size: "
                         + (mSystemSize + mUserdataSize));
-
-                return RESULT_ERROR_IO;
             }
 
             installedSize = mUserdataSize;
@@ -157,20 +154,11 @@
                 }
             }
 
-            return RESULT_OK;
-
-        } catch (IOException e) {
-            e.printStackTrace();
-            return RESULT_ERROR_IO;
-
-        } catch (InvalidImageUrlException e) {
-            e.printStackTrace();
-            return RESULT_ERROR_INVALID_URL;
+            return null;
 
         } catch (Exception e) {
             e.printStackTrace();
-            return RESULT_ERROR_EXCEPTION;
-
+            return e;
         } finally {
             close();
         }
@@ -180,19 +168,24 @@
     protected void onCancelled() {
         Log.d(TAG, "onCancelled(), URL: " + mUrl);
 
-        close();
-
         mListener.onCancelled();
     }
 
     @Override
-    protected void onPostExecute(Integer result) {
-        Log.d(TAG, "onPostExecute(), URL: " + mUrl + ", result: " + result);
+    protected void onPostExecute(Throwable detail) {
+        if (detail == null) {
+            mResult = RESULT_OK;
+        } else if (detail instanceof IOException) {
+            mResult = RESULT_ERROR_IO;
+        } else if (detail instanceof InvalidImageUrlException) {
+            mResult = RESULT_ERROR_INVALID_URL;
+        } else {
+            mResult = RESULT_ERROR_EXCEPTION;
+        }
 
-        close();
+        Log.d(TAG, "onPostExecute(), URL: " + mUrl + ", result: " + mResult);
 
-        mResult = result;
-        mListener.onResult(mResult);
+        mListener.onResult(mResult, detail);
     }
 
     @Override
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index 31a3ff4..1544adb 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -65,6 +65,8 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * Notification assistant that provides guidance on notification channel blocking
@@ -80,6 +82,7 @@
     private static final String ATT_KEY = "key";
     private static final int DB_VERSION = 1;
     private static final String ATTR_VERSION = "version";
+    private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
 
     private static final ArrayList<Integer> PREJUDICAL_DISMISSALS = new ArrayList<>();
     static {
@@ -233,15 +236,20 @@
         if (!isForCurrentUser(sbn)) {
             return null;
         }
-        NotificationEntry entry =
-                new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
-        SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
-        if (DEBUG) {
-            Log.d(TAG, String.format("Creating Adjustment for %s, with %d actions, and %d replies.",
-                    sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
-        }
-        return createEnqueuedNotificationAdjustment(
-                entry, suggestions.actions, suggestions.replies);
+        mSingleThreadExecutor.submit(() -> {
+            NotificationEntry entry =
+                    new NotificationEntry(mPackageManager, sbn, channel, mSmsHelper);
+            SmartActionsHelper.SmartSuggestions suggestions = mSmartActionsHelper.suggest(entry);
+            if (DEBUG) {
+                Log.d(TAG, String.format(
+                        "Creating Adjustment for %s, with %d actions, and %d replies.",
+                        sbn.getKey(), suggestions.actions.size(), suggestions.replies.size()));
+            }
+            Adjustment adjustment = createEnqueuedNotificationAdjustment(
+                    entry, suggestions.actions, suggestions.replies);
+            adjustNotification(adjustment);
+        });
+        return null;
     }
 
     /** A convenience helper for creating an adjustment for an SBN. */
@@ -386,15 +394,15 @@
         NotificationEntry entry = mLiveNotifications.get(key);
 
         if (entry != null) {
-            entry.setExpanded(isExpanded);
-            mSmartActionsHelper.onNotificationExpansionChanged(entry, isUserAction, isExpanded);
+            mSingleThreadExecutor.submit(
+                    () -> mSmartActionsHelper.onNotificationExpansionChanged(entry, isExpanded));
         }
     }
 
     @Override
     public void onNotificationDirectReplied(@NonNull String key) {
         if (DEBUG) Log.i(TAG, "onNotificationDirectReplied " + key);
-        mSmartActionsHelper.onNotificationDirectReplied(key);
+        mSingleThreadExecutor.submit(() -> mSmartActionsHelper.onNotificationDirectReplied(key));
     }
 
     @Override
@@ -404,7 +412,8 @@
             Log.d(TAG, "onSuggestedReplySent() called with: key = [" + key + "], reply = [" + reply
                     + "], source = [" + source + "]");
         }
-        mSmartActionsHelper.onSuggestedReplySent(key, reply, source);
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onSuggestedReplySent(key, reply, source));
     }
 
     @Override
@@ -415,7 +424,8 @@
                     "onActionInvoked() called with: key = [" + key + "], action = [" + action.title
                             + "], source = [" + source + "]");
         }
-        mSmartActionsHelper.onActionClicked(key, action, source);
+        mSingleThreadExecutor.submit(
+                () -> mSmartActionsHelper.onActionClicked(key, action, source));
     }
 
     @Override
@@ -494,11 +504,6 @@
     }
 
     @VisibleForTesting
-    public void setSmartActionsHelper(SmartActionsHelper smartActionsHelper) {
-        mSmartActionsHelper = smartActionsHelper;
-    }
-
-    @VisibleForTesting
     public ChannelImpressions getImpressions(String key) {
         synchronized (mkeyToImpressions) {
             return mkeyToImpressions.get(key);
diff --git a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
index 546bec2..84a8a8c 100644
--- a/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
+++ b/packages/ExtServices/src/android/ext/services/notification/NotificationEntry.java
@@ -47,17 +47,18 @@
 public class NotificationEntry {
     static final String TAG = "NotificationEntry";
 
-    private StatusBarNotification mSbn;
+    private final StatusBarNotification mSbn;
     private final IPackageManager mPackageManager;
     private int mTargetSdkVersion = Build.VERSION_CODES.N_MR1;
-    private boolean mPreChannelsNotification = true;
-    private AudioAttributes mAttributes;
-    private NotificationChannel mChannel;
-    private int mImportance;
+    private final boolean mPreChannelsNotification;
+    private final AudioAttributes mAttributes;
+    private final NotificationChannel mChannel;
+    private final int mImportance;
     private boolean mSeen;
-    private boolean mExpanded;
     private boolean mIsShowActionEventLogged;
-    private SmsHelper mSmsHelper;
+    private final SmsHelper mSmsHelper;
+
+    private final Object mLock = new Object();
 
     public NotificationEntry(IPackageManager packageManager, StatusBarNotification sbn,
             NotificationChannel channel, SmsHelper smsHelper) {
@@ -233,23 +234,27 @@
     }
 
     public void setSeen() {
-        mSeen = true;
-    }
-
-    public void setExpanded(boolean expanded) {
-        mExpanded = expanded;
+        synchronized (mLock) {
+            mSeen = true;
+        }
     }
 
     public void setShowActionEventLogged() {
-        mIsShowActionEventLogged = true;
+        synchronized (mLock) {
+            mIsShowActionEventLogged = true;
+        }
     }
 
     public boolean hasSeen() {
-        return mSeen;
+        synchronized (mLock) {
+            return mSeen;
+        }
     }
 
     public boolean isShowActionEventLogged() {
-        return mIsShowActionEventLogged;
+        synchronized (mLock) {
+            return mIsShowActionEventLogged;
+        }
     }
 
     public StatusBarNotification getSbn() {
diff --git a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
index bf8a3fa..0d687d4 100644
--- a/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
+++ b/packages/ExtServices/src/android/ext/services/notification/SmartActionsHelper.java
@@ -53,6 +53,11 @@
 import java.util.Map;
 import java.util.Objects;
 
+/**
+ * Generates suggestions from incoming notifications.
+ *
+ * Methods in this class should be called in a single worker thread.
+ */
 public class SmartActionsHelper {
     static final String ENTITIES_EXTRAS = "entities-extras";
     static final String KEY_ACTION_TYPE = "action_type";
@@ -287,8 +292,7 @@
         return conversationActions;
     }
 
-    void onNotificationExpansionChanged(NotificationEntry entry, boolean isUserAction,
-            boolean isExpanded) {
+    void onNotificationExpansionChanged(NotificationEntry entry, boolean isExpanded) {
         if (!isExpanded) {
             return;
         }
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/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
index 3a7d799..ebcaee8 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/SmartActionsHelperTest.java
@@ -382,7 +382,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true, true);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
 
         ArgumentCaptor<TextClassifierEvent> argumentCaptor =
                 ArgumentCaptor.forClass(TextClassifierEvent.class);
@@ -398,7 +398,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, false);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false);
 
         verify(mTextClassifier, never()).onTextClassifierEvent(
                 argThat(new TextClassifierEventMatcher(TextClassifierEvent.TYPE_ACTIONS_SHOWN)));
@@ -410,7 +410,7 @@
         when(mStatusBarNotification.getNotification()).thenReturn(notification);
 
         mSmartActionsHelper.suggest(createNotificationEntry());
-        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), false, true);
+        mSmartActionsHelper.onNotificationExpansionChanged(createNotificationEntry(), true);
 
         ArgumentCaptor<TextClassifierEvent> argumentCaptor =
                 ArgumentCaptor.forClass(TextClassifierEvent.class);
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/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index d654f5a..938c457 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -33,8 +33,10 @@
         android:protectionLevel="signature" />
 
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <!-- Used to read wallpaper -->
+    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
+
     <!-- Used to read storage for all users -->
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
     <uses-permission android:name="android.permission.WAKE_LOCK" />
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/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 1da1405..baa2055 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1023,8 +1023,8 @@
     <dimen name="ongoing_appops_chip_bg_corner_radius">16dp</dimen>
 
 
-    <!-- How much a bubble is elevated -->
-    <dimen name="bubble_elevation">8dp</dimen>
+    <!-- How much each bubble is elevated. -->
+    <dimen name="bubble_elevation">1dp</dimen>
     <!-- Padding around a collapsed bubble -->
     <dimen name="bubble_view_padding">0dp</dimen>
     <!-- Padding between bubbles when displayed in expanded state -->
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/shared/src/com/android/systemui/shared/system/SettingsCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
deleted file mode 100644
index c16cf92..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/SettingsCompat.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License
- */
-
-package com.android.systemui.shared.system;
-
-import android.provider.Settings;
-
-public class SettingsCompat {
-
-    public static final String SWIPE_UP_SETTING_NAME
-            = Settings.Secure.SWIPE_UP_TO_SWITCH_APPS_ENABLED;
-}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 294c725..8ad5c7b 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -39,6 +39,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import com.android.internal.colorextraction.ColorExtractor;
+import com.android.systemui.SysUiServiceProvider;
 import com.android.systemui.colorextraction.SysuiColorExtractor;
 import com.android.systemui.dock.DockManager;
 import com.android.systemui.dock.DockManager.DockEventListener;
@@ -72,6 +73,7 @@
     private final Map<String, ClockPlugin> mClocks = new ArrayMap<>();
     @Nullable private ClockPlugin mCurrentClock;
 
+    private final Context mContext;
     private final ContentResolver mContentResolver;
     private final SettingsWrapper mSettingsWrapper;
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
@@ -117,7 +119,7 @@
                     reload();
                 }
             };
-    @Nullable private final DockManager mDockManager;
+    @Nullable private DockManager mDockManager;
     /**
      * When docked, the DOCKED_CLOCK_FACE setting will be checked for the custom clock face
      * to show.
@@ -132,18 +134,16 @@
 
     @Inject
     public ClockManager(Context context, InjectionInflationController injectionInflater,
-            PluginManager pluginManager, @Nullable DockManager dockManager,
-            SysuiColorExtractor colorExtractor) {
-        this(context, injectionInflater, pluginManager, dockManager, colorExtractor,
+            PluginManager pluginManager, SysuiColorExtractor colorExtractor) {
+        this(context, injectionInflater, pluginManager, colorExtractor,
                 context.getContentResolver(), new SettingsWrapper(context.getContentResolver()));
     }
 
     ClockManager(Context context, InjectionInflationController injectionInflater,
-            PluginManager pluginManager, @Nullable DockManager dockManager,
-            SysuiColorExtractor colorExtractor, ContentResolver contentResolver,
-            SettingsWrapper settingsWrapper) {
+            PluginManager pluginManager, SysuiColorExtractor colorExtractor,
+            ContentResolver contentResolver, SettingsWrapper settingsWrapper) {
+        mContext = context;
         mPluginManager = pluginManager;
-        mDockManager = dockManager;
         mColorExtractor = colorExtractor;
         mContentResolver = contentResolver;
         mSettingsWrapper = settingsWrapper;
@@ -323,6 +323,9 @@
         mContentResolver.registerContentObserver(
                 Settings.Secure.getUriFor(Settings.Secure.DOCKED_CLOCK_FACE),
                 false, mContentObserver);
+        if (mDockManager == null) {
+            mDockManager = SysUiServiceProvider.getComponent(mContext, DockManager.class);
+        }
         if (mDockManager != null) {
             mDockManager.addListener(mDockEventListener);
         }
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/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 6bb4fb5..47ad0c1 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -31,7 +31,6 @@
 import com.android.keyguard.ViewMediatorCallback;
 import com.android.systemui.assist.AssistManager;
 import com.android.systemui.classifier.FalsingManager;
-import com.android.systemui.dock.DockManager;
 import com.android.systemui.fragments.FragmentService;
 import com.android.systemui.keyguard.DismissCallbackRegistry;
 import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -220,16 +219,6 @@
         return SysUiServiceProvider.getComponent(context, StatusBar.class);
     }
 
-    /**
-     * Provides DockManager.
-     */
-    @Singleton
-    @Provides
-    @Nullable
-    public DockManager providesDockManager(Context context) {
-        return SysUiServiceProvider.getComponent(context, DockManager.class);
-    }
-
     @Module
     protected static class ContextHolder {
         private Context mContext;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 4a2731e..0e691fb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -80,8 +80,6 @@
 
     private static final String TAG = "BubbleController";
 
-    private static final int MAX_BUBBLES = 5; // TODO: actually enforce this
-
     @Retention(SOURCE)
     @IntDef({DISMISS_USER_GESTURE, DISMISS_AGED, DISMISS_TASK_FINISHED, DISMISS_BLOCKED,
             DISMISS_NOTIF_CANCEL, DISMISS_ACCESSIBILITY_ACTION})
@@ -94,6 +92,8 @@
     static final int DISMISS_NOTIF_CANCEL = 5;
     static final int DISMISS_ACCESSIBILITY_ACTION = 6;
 
+    static final int MAX_BUBBLES = 5; // TODO: actually enforce this
+
     // Enables some subset of notifs to automatically become bubbles
     private static final boolean DEBUG_ENABLE_AUTO_BUBBLE = false;
 
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index 8e3afd8..ec6ea55 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -437,7 +437,7 @@
     }
 
     boolean performBackPressIfNeeded() {
-        if (mActivityView == null || !usingActivityView()) {
+        if (!usingActivityView()) {
             return false;
         }
         mActivityView.performBackPress();
@@ -593,7 +593,7 @@
     }
 
     private boolean usingActivityView() {
-        return mBubbleIntent != null;
+        return mBubbleIntent != null && mActivityView != null;
     }
 
     private void applyRowState(ExpandableNotificationRow view) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 580acb8..b92b982 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -265,7 +265,9 @@
      * Handle config changes.
      */
     public void onConfigChanged() {
-        mExpandedBubble.expandedView.updateHeaderColor();
+        if (mExpandedBubble != null) {
+            mExpandedBubble.expandedView.updateHeaderColor();
+        }
     }
 
     @Override
@@ -871,7 +873,8 @@
         for (int i = 0; i < bubbsCount; i++) {
             BubbleView bv = (BubbleView) mBubbleContainer.getChildAt(i);
             bv.updateDotVisibility();
-            bv.setZ(bubbsCount - i);
+            bv.setZ((BubbleController.MAX_BUBBLES
+                    * getResources().getDimensionPixelSize(R.dimen.bubble_elevation)) - i);
 
             // Draw the shadow around the circle inscribed within the bubble's bounds. This
             // (intentionally) does not draw a shadow behind the update dot, which should be drawing
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
index 7a68be4..979d226 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleView.java
@@ -84,7 +84,6 @@
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
-        updateViews();
     }
 
     @Override
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/NavigationBarEdgePanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
index 4c7fdb0..4897464 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java
@@ -108,7 +108,7 @@
     public static NavigationBarEdgePanel create(@NonNull Context context, int width, int height,
             int gravity) {
         final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
-                WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
                     | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                     | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
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..bfbe886 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
@@ -338,8 +346,11 @@
             post(() -> {
                 // When the ime changes visibility, resize the edge panels to not cover the ime
                 final int width = mPrototypeController.getEdgeSensitivityWidth();
-                final int height = mContext.getDisplay().getHeight() - imeHeight
-                        - getResources().getDimensionPixelOffset(R.dimen.status_bar_height);
+                int height = mContext.getDisplay().getHeight() - imeHeight;
+                if (!imeVisible) {
+                    // Hide the navigation bar area at the bottom for gestures
+                    height -= getResources().getDimensionPixelOffset(R.dimen.navigation_bar_height);
+                }
                 if (mLeftEdgePanel != null) {
                     mLeftEdgePanel.setDimensions(width, height);
                 }
@@ -368,6 +379,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 +439,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 +481,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 +643,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 +790,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 +819,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 +974,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 +991,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 +1294,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 +1325,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/keyguard/clock/ClockManagerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
index 36265d4..46b1833 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockManagerTest.java
@@ -67,8 +67,10 @@
         when(mMockInjectionInflationController.injectable(any())).thenReturn(inflater);
 
         mFakeDockManager = new DockManagerFake();
+        getContext().putComponent(DockManager.class, mFakeDockManager);
+
         mClockManager = new ClockManager(getContext(), mMockInjectionInflationController,
-                mMockPluginManager, mFakeDockManager, mMockColorExtractor, mMockContentResolver,
+                mMockPluginManager, mMockColorExtractor, mMockContentResolver,
                 mMockSettingsWrapper);
 
         mClockManager.addOnClockChangedListener(mMockListener);
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/VpnDialogs/AndroidManifest.xml b/packages/VpnDialogs/AndroidManifest.xml
index 1d0b9b6..9f6ba03 100644
--- a/packages/VpnDialogs/AndroidManifest.xml
+++ b/packages/VpnDialogs/AndroidManifest.xml
@@ -27,7 +27,7 @@
                  android:allowBackup="false">
 
         <activity android:name=".ConfirmDialog"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert">
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -35,7 +35,7 @@
         </activity>
 
         <activity android:name=".ManageDialog"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:noHistory="true"
                   android:excludeFromRecents="true"
                   android:permission="android.permission.NETWORK_SETTINGS"
@@ -44,7 +44,7 @@
 
         <activity android:name=".AlwaysOnDisconnectedDialog"
                   android:label="@string/always_on_disconnected_title"
-                  android:theme="@android:style/Theme.Material.Light.Dialog.Alert"
+                  android:theme="@*android:style/Theme.DeviceDefault.Dialog.Alert.DayNight"
                   android:noHistory="true"
                   android:excludeFromRecents="true"
                   android:permission="android.permission.NETWORK_SETTINGS"
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/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 95abd05..f629cf6 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7149,6 +7149,13 @@
 
     // Settings > Display > Theme
     DARK_UI_SETTINGS = 1698;
+
+    // Settings > global bubble settings
+    BUBBLE_SETTINGS = 1699;
+
+    // Settings > app > bubble settings
+    APP_BUBBLE_SETTINGS = 1700;
+
     // ---- End Q Constants, all Q constants go above this line ----
     // Add new aosp constants above this line.
     // END OF AOSP CONSTANTS
diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto
index 1bcc888..1ce0c52 100644
--- a/proto/src/wifi.proto
+++ b/proto/src/wifi.proto
@@ -703,8 +703,8 @@
     // External scorer
     NOMINATOR_EXTERNAL_SCORED = 6;
 
-    // Netrec
-    NOMINATOR_NETREC = 7;
+    // Network Specifier
+    NOMINATOR_SPECIFIER = 7;
 
     // User connected choice override
     NOMINATOR_SAVED_USER_CONNECT_CHOICE = 8;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 47cd917..904817e 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -777,6 +777,7 @@
             final int removedWindowId = removeAccessibilityInteractionConnectionInternalLocked(
                     token, mGlobalWindowTokens, mGlobalInteractionConnections);
             if (removedWindowId >= 0) {
+                mSecurityPolicy.onAccessibilityClientRemovedLocked(removedWindowId);
                 if (DEBUG) {
                     Slog.i(LOG_TAG, "Removed global connection for pid:" + Binder.getCallingPid()
                             + " with windowId: " + removedWindowId + " and token: " + window.asBinder());
@@ -790,6 +791,7 @@
                         removeAccessibilityInteractionConnectionInternalLocked(
                         token, userState.mWindowTokens, userState.mInteractionConnections);
                 if (removedWindowIdForUser >= 0) {
+                    mSecurityPolicy.onAccessibilityClientRemovedLocked(removedWindowIdForUser);
                     if (DEBUG) {
                         Slog.i(LOG_TAG, "Removed user connection for pid:" + Binder.getCallingPid()
                                 + " with windowId: " + removedWindowIdForUser + " and userId:"
@@ -1332,6 +1334,7 @@
             userState.mWindowTokens.remove(windowId);
             userState.mInteractionConnections.remove(windowId);
         }
+        mSecurityPolicy.onAccessibilityClientRemovedLocked(windowId);
         if (DEBUG) {
             Slog.i(LOG_TAG, "Removing interaction connection to windowId: " + windowId);
         }
@@ -3266,6 +3269,18 @@
             mWindows = null;
         }
 
+        /**
+         * A callback when accessibility interaction client is removed.
+         */
+        public void onAccessibilityClientRemovedLocked(int windowId) {
+            // Active window cannot update immediately, if windows callback is unregistered.
+            // Update active window to invalid, when its a11y interaction client is removed.
+            if (mWindowsForAccessibilityCallback == null && windowId >= 0
+                    && mActiveWindowId == windowId) {
+                mActiveWindowId = INVALID_WINDOW_ID;
+            }
+        }
+
         public void updateWindowsLocked(List<WindowInfo> windows) {
             if (mWindows == null) {
                 mWindows = new ArrayList<>();
diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
index 21088e4..19226be 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -47,7 +47,8 @@
             RemoteAppPredictionServiceCallbacks callback, boolean bindInstantServiceAllowed,
             boolean verbose) {
         super(context, serviceInterface, componentName, userId, callback,
-                context.getMainThreadHandler(), bindInstantServiceAllowed,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0,
                 verbose, /* initialCapacity= */ 1);
     }
 
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 87a265c..7020e7e 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -198,6 +198,11 @@
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         context.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
 
+        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
+                com.android.internal.R.string.config_defaultAugmentedAutofillService);
+        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
+                (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService());
+
         if (mSupportedSmartSuggestionModes != AutofillManager.FLAG_SMART_SUGGESTION_OFF) {
             // Must eager load the services so they bind to the augmented autofill service
             final UserManager um = getContext().getSystemService(UserManager.class);
@@ -207,11 +212,6 @@
                 getServiceForUserLocked(userId);
             }
         }
-
-        mAugmentedAutofillResolver = new FrameworkResourcesServiceNameResolver(getContext(),
-                com.android.internal.R.string.config_defaultAugmentedAutofillService);
-        mAugmentedAutofillResolver.setOnTemporaryServiceNameChangedCallback(
-                (u, s) -> getServiceForUserLocked(u).updateRemoteAugmentedAutofillService());
     }
 
     @Override // from AbstractMasterSystemService
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index ff284dc..d3cd48a 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -247,7 +247,8 @@
         if (isEnabledLocked()) return FLAG_ADD_CLIENT_ENABLED;
 
         // Check if it's enabled for augmented autofill
-        if (isSetupCompletedLocked() && isWhitelistedForAugmentedAutofillLocked(componentName)) {
+        if (isAugmentedAutofillServiceAvailableLocked()
+                && isWhitelistedForAugmentedAutofillLocked(componentName)) {
             return FLAG_ADD_CLIENT_ENABLED_FOR_AUGMENTED_AUTOFILL_ONLY;
         }
 
@@ -1150,12 +1151,30 @@
                 mRemoteAugmentedAutofillServiceInfo = null;
             }
 
-            if (isEnabledLocked()) {
+            final boolean available = isAugmentedAutofillServiceAvailableLocked();
+            if (sVerbose) Slog.v(TAG, "updateRemoteAugmentedAutofillService(): " + available);
+
+            if (available) {
                 mRemoteAugmentedAutofillService = getRemoteAugmentedAutofillServiceLocked();
             }
         }
     }
 
+    private boolean isAugmentedAutofillServiceAvailableLocked() {
+        if (mMaster.verbose) {
+            Slog.v(TAG, "isAugmentedAutofillService(): "
+                    + "setupCompleted=" + isSetupCompletedLocked()
+                    + ", disabled=" + isDisabledByUserRestrictionsLocked()
+                    + ", augmentedService="
+                    + mMaster.mAugmentedAutofillResolver.getServiceName(mUserId));
+        }
+        if (!isSetupCompletedLocked() || isDisabledByUserRestrictionsLocked()
+                || mMaster.mAugmentedAutofillResolver.getServiceName(mUserId) == null) {
+            return false;
+        }
+        return true;
+    }
+
     /**
      * Sets which packages and activities can trigger augmented autofill.
      *
diff --git a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
index 3c17ac3..adf5829 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteAugmentedAutofillService.java
@@ -58,7 +58,8 @@
             boolean bindInstantServiceAllowed, boolean verbose, int idleUnbindTimeoutMs,
             int requestTimeoutMs) {
         super(context, AugmentedAutofillService.SERVICE_INTERFACE, serviceName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose);
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose);
         mIdleUnbindTimeoutMs = idleUnbindTimeoutMs;
         mRequestTimeoutMs = requestTimeoutMs;
 
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index b8a7d44..0ce6c87 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -64,7 +64,8 @@
     RemoteFillService(Context context, ComponentName componentName, int userId,
             FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
         super(context, AutofillService.SERVICE_INTERFACE, componentName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, sVerbose);
+                context.getMainThreadHandler(), Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS
+                | (bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0), sVerbose);
         mCallbacks = callbacks;
     }
 
diff --git a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
index df9ccbc..0afe252 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/RemoteContentCaptureService.java
@@ -47,7 +47,8 @@
             ContentCapturePerUserService perUserService, boolean bindInstantServiceAllowed,
             boolean verbose, int idleUnbindTimeoutMs) {
         super(context, serviceInterface, serviceComponentName, userId, perUserService,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose,
                 /* initialCapacity= */ 2);
         mPerUserService = perUserService;
         mServerCallback = callback.asBinder();
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
index 442972a..4b36352 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/RemoteContentSuggestionsService.java
@@ -47,7 +47,8 @@
             int userId, Callbacks callbacks,
             boolean bindInstantServiceAllowed, boolean verbose) {
         super(context, ContentSuggestionsService.SERVICE_INTERFACE, serviceName, userId, callbacks,
-                context.getMainThreadHandler(), bindInstantServiceAllowed, verbose,
+                context.getMainThreadHandler(),
+                bindInstantServiceAllowed ? Context.BIND_ALLOW_INSTANT : 0, verbose,
                 /* initialCapacity= */ 1);
     }
 
diff --git a/services/core/java/com/android/server/ExplicitHealthCheckController.java b/services/core/java/com/android/server/ExplicitHealthCheckController.java
new file mode 100644
index 0000000..f50364d
--- /dev/null
+++ b/services/core/java/com/android/server/ExplicitHealthCheckController.java
@@ -0,0 +1,266 @@
+/*
+ * 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;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_HEALTH_CHECK_PASSED_PACKAGE;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_REQUESTED_PACKAGES;
+import static android.service.watchdog.ExplicitHealthCheckService.EXTRA_SUPPORTED_PACKAGES;
+
+import android.Manifest;
+import android.annotation.MainThread;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteCallback;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.watchdog.ExplicitHealthCheckService;
+import android.service.watchdog.IExplicitHealthCheckService;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Controls the connections with {@link ExplicitHealthCheckService}.
+ */
+class ExplicitHealthCheckController {
+    private static final String TAG = "ExplicitHealthCheckController";
+    private final Object mLock = new Object();
+    private final Context mContext;
+    @GuardedBy("mLock") @Nullable private StateCallback mStateCallback;
+    @GuardedBy("mLock") @Nullable private IExplicitHealthCheckService mRemoteService;
+    @GuardedBy("mLock") @Nullable private ServiceConnection mConnection;
+    @GuardedBy("mLock") @Nullable private List<String> mSupportedPackages;
+
+    ExplicitHealthCheckController(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Requests an explicit health check for {@code packageName}.
+     * After this request, the callback registered on {@link startService} can receive explicit
+     * health check passed results.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void request(String packageName) throws RemoteException {
+        synchronized (mLock) {
+            enforceServiceReadyLocked();
+            mRemoteService.request(packageName);
+        }
+    }
+
+    /**
+     * Cancels all explicit health checks for {@code packageName}.
+     * After this request, the callback registered on {@link startService} can no longer receive
+     * explicit health check passed results.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void cancel(String packageName) throws RemoteException {
+        synchronized (mLock) {
+            enforceServiceReadyLocked();
+            mRemoteService.cancel(packageName);
+        }
+    }
+
+    /**
+     * Returns the packages that we can request explicit health checks for.
+     * The packages will be returned to the {@code consumer}.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void getSupportedPackages(Consumer<List<String>> consumer) throws RemoteException {
+        synchronized (mLock) {
+            enforceServiceReadyLocked();
+            if (mSupportedPackages == null) {
+                mRemoteService.getSupportedPackages(new RemoteCallback(result -> {
+                    mSupportedPackages = result.getStringArrayList(EXTRA_SUPPORTED_PACKAGES);
+                    consumer.accept(mSupportedPackages);
+                }));
+            } else {
+                consumer.accept(mSupportedPackages);
+            }
+        }
+    }
+
+    /**
+     * Returns the packages for which health checks are currently in progress.
+     * The packages will be returned to the {@code consumer}.
+     *
+     * @throws IllegalStateException if the service is not started
+     */
+    public void getRequestedPackages(Consumer<List<String>> consumer) throws RemoteException {
+        synchronized (mLock) {
+            enforceServiceReadyLocked();
+            mRemoteService.getRequestedPackages(new RemoteCallback(
+                    result -> consumer.accept(
+                            result.getStringArrayList(EXTRA_REQUESTED_PACKAGES))));
+        }
+    }
+
+    /**
+     * Starts the explicit health check service.
+     *
+     * @param stateCallback will receive important state changes changes
+     * @param passedConsumer will accept packages that pass explicit health checks
+     *
+     * @throws IllegalStateException if the service is already started
+     */
+    public void startService(StateCallback stateCallback, Consumer<String> passedConsumer) {
+        synchronized (mLock) {
+            if (mRemoteService != null) {
+                throw new IllegalStateException("Explicit health check service already started.");
+            }
+            mStateCallback = stateCallback;
+            mConnection = new ServiceConnection() {
+                @Override
+                public void onServiceConnected(ComponentName name, IBinder service) {
+                    synchronized (mLock) {
+                        mRemoteService = IExplicitHealthCheckService.Stub.asInterface(service);
+                        try {
+                            mRemoteService.setCallback(new RemoteCallback(result -> {
+                                String packageName =
+                                        result.getString(EXTRA_HEALTH_CHECK_PASSED_PACKAGE);
+                                if (!TextUtils.isEmpty(packageName)) {
+                                    passedConsumer.accept(packageName);
+                                } else {
+                                    Slog.w(TAG, "Empty package passed explicit health check?");
+                                }
+                            }));
+                            mStateCallback.onStart();
+                            Slog.i(TAG, "Explicit health check service is connected " + name);
+                        } catch (RemoteException e) {
+                            Slog.wtf(TAG, "Coud not setCallback on explicit health check service");
+                        }
+                    }
+                }
+
+                @Override
+                @MainThread
+                public void onServiceDisconnected(ComponentName name) {
+                    resetState();
+                    Slog.i(TAG, "Explicit health check service is disconnected " + name);
+                }
+
+                @Override
+                public void onBindingDied(ComponentName name) {
+                    resetState();
+                    Slog.i(TAG, "Explicit health check service binding is dead " + name);
+                }
+
+                @Override
+                public void onNullBinding(ComponentName name) {
+                    resetState();
+                    Slog.i(TAG, "Explicit health check service binding is null " + name);
+                }
+            };
+
+            ComponentName component = getServiceComponentNameLocked();
+            if (component != null) {
+                Intent intent = new Intent();
+                intent.setComponent(component);
+                mContext.bindServiceAsUser(intent, mConnection, Context.BIND_AUTO_CREATE,
+                        UserHandle.of(UserHandle.USER_SYSTEM));
+            }
+        }
+    }
+
+    // TODO: Differentiate between expected vs unexpected stop?
+    /** Callback to receive important {@link ExplicitHealthCheckController} state changes. */
+    abstract static class StateCallback {
+        /** The controller is ready and we can request explicit health checks for packages */
+        public void onStart() {}
+
+        /** The controller is not ready and we cannot request explicit health checks for packages */
+        public void onStop() {}
+    }
+
+    /** Stops the explicit health check service. */
+    public void stopService() {
+        synchronized (mLock) {
+            if (mRemoteService != null) {
+                mContext.unbindService(mConnection);
+            }
+        }
+    }
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ServiceInfo getServiceInfoLocked() {
+        final String packageName =
+                mContext.getPackageManager().getServicesSystemSharedLibraryPackageName();
+        if (packageName == null) {
+            Slog.w(TAG, "no external services package!");
+            return null;
+        }
+
+        final Intent intent = new Intent(ExplicitHealthCheckService.SERVICE_INTERFACE);
+        intent.setPackage(packageName);
+        final ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent,
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+        if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+            Slog.w(TAG, "No valid components found.");
+            return null;
+        }
+        return resolveInfo.serviceInfo;
+    }
+
+    @GuardedBy("mLock")
+    @Nullable
+    private ComponentName getServiceComponentNameLocked() {
+        final ServiceInfo serviceInfo = getServiceInfoLocked();
+        if (serviceInfo == null) {
+            return null;
+        }
+
+        final ComponentName name = new ComponentName(serviceInfo.packageName, serviceInfo.name);
+        if (!Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE
+                .equals(serviceInfo.permission)) {
+            Slog.w(TAG, name.flattenToShortString() + " does not require permission "
+                    + Manifest.permission.BIND_EXPLICIT_HEALTH_CHECK_SERVICE);
+            return null;
+        }
+        return name;
+    }
+
+    private void resetState() {
+        synchronized (mLock) {
+            mStateCallback.onStop();
+            mStateCallback = null;
+            mSupportedPackages = null;
+            mRemoteService = null;
+            mConnection = null;
+        }
+    }
+
+    @GuardedBy("mLock")
+    private void enforceServiceReadyLocked() {
+        if (mRemoteService == null) {
+            throw new IllegalStateException("Explicit health check service not ready");
+        }
+    }
+}
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..8b10267 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -73,10 +73,12 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
+import java.util.OptionalInt;
 
 /**
  * Since phone process can be restarted, this class provides a centralized place
@@ -1159,17 +1161,28 @@
 
     @Override
     public void notifyCarrierNetworkChange(boolean active) {
-        enforceNotifyPermissionOrCarrierPrivilege("notifyCarrierNetworkChange()");
+        // only CarrierService with carrier privilege rule should have the permission.
+        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        try {
+            subId = Arrays.stream(SubscriptionManager.from(mContext)
+                    .getActiveSubscriptionIdList())
+                    .filter(i -> TelephonyPermissions.checkCarrierPrivilegeForSubId(i))
+                    .findFirst().getAsInt();
+        } catch (NoSuchElementException ex) {
+            log("notifyCarrierNetworkChange without carrier privilege");
+        }
+        int phoneId = SubscriptionManager.getPhoneId(subId);
 
         if (VDBG) {
-            log("notifyCarrierNetworkChange: active=" + active);
+            log("notifyCarrierNetworkChange: active=" + active + "subId: " + subId);
         }
 
         synchronized (mRecords) {
             mCarrierNetworkChangeState = active;
             for (Record r : mRecords) {
                 if (r.matchPhoneStateListenerEvent(
-                        PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE)) {
+                        PhoneStateListener.LISTEN_CARRIER_NETWORK_CHANGE) &&
+                        idMatch(r.subId, subId, phoneId)) {
                     try {
                         r.callback.onCarrierNetworkChange(active);
                     } catch (RemoteException ex) {
@@ -1885,7 +1898,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..4f81c03 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -24,9 +24,7 @@
 import static android.hardware.display.ColorDisplayManager.COLOR_MODE_NATURAL;
 import static android.hardware.display.ColorDisplayManager.COLOR_MODE_SATURATED;
 
-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;
@@ -46,7 +44,6 @@
 import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.database.ContentObserver;
-import android.graphics.ColorSpace;
 import android.hardware.display.ColorDisplayManager;
 import android.hardware.display.ColorDisplayManager.AutoMode;
 import android.hardware.display.ColorDisplayManager.ColorMode;
@@ -56,7 +53,6 @@
 import android.opengl.Matrix;
 import android.os.Binder;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
 import android.os.SystemProperties;
@@ -66,7 +62,6 @@
 import android.util.MathUtils;
 import android.util.Slog;
 import android.view.SurfaceControl;
-import android.view.SurfaceControl.DisplayPrimaries;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.AnimationUtils;
 
@@ -88,29 +83,28 @@
 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";
+    static final String TAG = "ColorDisplayService";
+
+    /**
+     * The identity matrix, used if one of the given matrices is {@code null}.
+     */
+    static final float[] MATRIX_IDENTITY = new float[16];
+
+    static {
+        Matrix.setIdentityM(MATRIX_IDENTITY, 0);
+    }
 
     /**
      * The transition time, in milliseconds, for Night Display to turn on/off.
      */
     private static final long TRANSITION_DURATION = 3000L;
 
-    /**
-     * The identity matrix, used if one of the given matrices is {@code null}.
-     */
-    private static final float[] MATRIX_IDENTITY = new float[16];
-
-    static {
-        Matrix.setIdentityM(MATRIX_IDENTITY, 0);
-    }
-
     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 +127,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 +1027,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];
@@ -1316,245 +1183,6 @@
         }
     }
 
-    final class DisplayWhiteBalanceTintController extends TintController {
-
-        // Three chromaticity coordinates per color: X, Y, and Z
-        private static final int NUM_VALUES_PER_PRIMARY = 3;
-        // Four colors: red, green, blue, and white
-        private static final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY;
-
-        private final Object mLock = new Object();
-        @VisibleForTesting
-        int mTemperatureMin;
-        @VisibleForTesting
-        int mTemperatureMax;
-        private int mTemperatureDefault;
-        private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-        @VisibleForTesting
-        ColorSpace.Rgb mDisplayColorSpaceRGB;
-        private float[] mChromaticAdaptationMatrix;
-        @VisibleForTesting
-        int mCurrentColorTemperature;
-        private float[] mCurrentColorTemperatureXYZ;
-        private boolean mSetUp = false;
-        private float[] mMatrixDisplayWhiteBalance = new float[16];
-        private Boolean mIsAvailable;
-
-        @Override
-        public void setUp(Context context, boolean needsLinear) {
-            mSetUp = false;
-            final Resources res = context.getResources();
-
-            ColorSpace.Rgb displayColorSpaceRGB = getDisplayColorSpaceFromSurfaceControl();
-            if (displayColorSpaceRGB == null) {
-                Slog.w(TAG, "Failed to get display color space from SurfaceControl, trying res");
-                displayColorSpaceRGB = getDisplayColorSpaceFromResources(res);
-                if (displayColorSpaceRGB == null) {
-                    Slog.e(TAG, "Failed to get display color space from resources");
-                    return;
-                }
-            }
-
-            final String[] nominalWhiteValues = res.getStringArray(
-                    R.array.config_displayWhiteBalanceDisplayNominalWhite);
-            float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-            for (int i = 0; i < nominalWhiteValues.length; i++) {
-                displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]);
-            }
-
-            final int colorTemperatureMin = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureMin);
-            if (colorTemperatureMin <= 0) {
-                Slog.e(TAG, "Display white balance minimum temperature must be greater than 0");
-                return;
-            }
-
-            final int colorTemperatureMax = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureMax);
-            if (colorTemperatureMax < colorTemperatureMin) {
-                Slog.e(TAG, "Display white balance max temp must be greater or equal to min");
-                return;
-            }
-
-            final int colorTemperature = res.getInteger(
-                    R.integer.config_displayWhiteBalanceColorTemperatureDefault);
-
-            synchronized (mLock) {
-                mDisplayColorSpaceRGB = displayColorSpaceRGB;
-                mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ;
-                mTemperatureMin = colorTemperatureMin;
-                mTemperatureMax = colorTemperatureMax;
-                mTemperatureDefault = colorTemperature;
-                mSetUp = true;
-            }
-
-            setMatrix(mTemperatureDefault);
-        }
-
-        @Override
-        public float[] getMatrix() {
-            return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance : MATRIX_IDENTITY;
-        }
-
-        @Override
-        public void setMatrix(int cct) {
-            if (!mSetUp) {
-                Slog.w(TAG, "Can't set display white balance temperature: uninitialized");
-                return;
-            }
-
-            if (cct < mTemperatureMin) {
-                Slog.w(TAG, "Requested display color temperature is below allowed minimum");
-                cct = mTemperatureMin;
-            } else if (cct > mTemperatureMax) {
-                Slog.w(TAG, "Requested display color temperature is above allowed maximum");
-                cct = mTemperatureMax;
-            }
-
-            Slog.d(TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct);
-
-            synchronized (mLock) {
-                mCurrentColorTemperature = cct;
-
-                // Adapt the display's nominal white point to match the requested CCT value
-                mCurrentColorTemperatureXYZ = ColorSpace.cctToXyz(cct);
-
-                mChromaticAdaptationMatrix =
-                        ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
-                                mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ);
-
-                // Convert the adaptation matrix to RGB space
-                float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix,
-                        mDisplayColorSpaceRGB.getTransform());
-                result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result);
-
-                // Normalize the transform matrix to peak white value in RGB space
-                final float adaptedMaxR = result[0] + result[3] + result[6];
-                final float adaptedMaxG = result[1] + result[4] + result[7];
-                final float adaptedMaxB = result[2] + result[5] + result[8];
-                final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB);
-                for (int i = 0; i < result.length; i++) {
-                    result[i] /= denum;
-                }
-
-                Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0);
-                java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3);
-                java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3);
-                java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3);
-            }
-        }
-
-        @Override
-        public int getLevel() {
-            return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
-        }
-
-        @Override
-        public boolean isAvailable(Context context) {
-            if (mIsAvailable == null) {
-                mIsAvailable = ColorDisplayManager.isDisplayWhiteBalanceAvailable(context);
-            }
-            return mIsAvailable;
-        }
-
-        /**
-         * Format a given matrix into a string.
-         *
-         * @param matrix the matrix to format
-         * @param cols number of columns in the matrix
-         */
-        private String matrixToString(float[] matrix, int cols) {
-            if (matrix == null || cols <= 0) {
-                Slog.e(TAG, "Invalid arguments when formatting matrix to string");
-                return "";
-            }
-
-            StringBuilder sb = new StringBuilder("");
-            for (int i = 0; i < matrix.length; i++) {
-                if (i % cols == 0) {
-                    sb.append("\n      ");
-                }
-                sb.append(String.format("%9.6f ", matrix[i]));
-            }
-            return sb.toString();
-        }
-
-        @Override
-        public void dump(PrintWriter pw) {
-            synchronized (mLock) {
-                pw.println("    mSetUp = " + mSetUp);
-                if (!mSetUp) {
-                    return;
-                }
-
-                pw.println("    mTemperatureMin = " + mTemperatureMin);
-                pw.println("    mTemperatureMax = " + mTemperatureMax);
-                pw.println("    mTemperatureDefault = " + mTemperatureDefault);
-                pw.println("    mCurrentColorTemperature = " + mCurrentColorTemperature);
-                pw.println("    mCurrentColorTemperatureXYZ = "
-                        + matrixToString(mCurrentColorTemperatureXYZ, 3));
-                pw.println("    mDisplayColorSpaceRGB RGB-to-XYZ = "
-                        + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3));
-                pw.println("    mChromaticAdaptationMatrix = "
-                        + matrixToString(mChromaticAdaptationMatrix, 3));
-                pw.println("    mDisplayColorSpaceRGB XYZ-to-RGB = "
-                        + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3));
-                pw.println("    mMatrixDisplayWhiteBalance = "
-                        + matrixToString(mMatrixDisplayWhiteBalance, 4));
-            }
-        }
-
-        private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
-            return new ColorSpace.Rgb(
-                    "Display Color Space",
-                    redGreenBlueXYZ,
-                    whiteXYZ,
-                    2.2f // gamma, unused for display white balance
-            );
-        }
-
-        private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
-            final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
-            if (displayToken == null) {
-                return null;
-            }
-
-            DisplayPrimaries primaries = SurfaceControl.getDisplayNativePrimaries(displayToken);
-            if (primaries == null || primaries.red == null || primaries.green == null
-                    || primaries.blue == null || primaries.white == null) {
-                return null;
-            }
-
-            return makeRgbColorSpaceFromXYZ(
-                    new float[]{
-                            primaries.red.X, primaries.red.Y, primaries.red.Z,
-                            primaries.green.X, primaries.green.Y, primaries.green.Z,
-                            primaries.blue.X, primaries.blue.Y, primaries.blue.Z,
-                    },
-                    new float[]{primaries.white.X, primaries.white.Y, primaries.white.Z}
-            );
-        }
-
-        private ColorSpace.Rgb getDisplayColorSpaceFromResources(Resources res) {
-            final String[] displayPrimariesValues = res.getStringArray(
-                    R.array.config_displayWhiteBalanceDisplayPrimaries);
-            float[] displayRedGreenBlueXYZ =
-                    new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY];
-            float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
-
-            for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) {
-                displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]);
-            }
-
-            for (int i = 0; i < displayWhiteXYZ.length; i++) {
-                displayWhiteXYZ[i] = Float.parseFloat(
-                        displayPrimariesValues[displayRedGreenBlueXYZ.length + i]);
-            }
-
-            return makeRgbColorSpaceFromXYZ(displayRedGreenBlueXYZ, displayWhiteXYZ);
-        }
-    }
-
     /**
      * Local service that allows color transforms to be enabled from other system services.
      */
diff --git a/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
new file mode 100644
index 0000000..97c9c79
--- /dev/null
+++ b/services/core/java/com/android/server/display/color/DisplayWhiteBalanceTintController.java
@@ -0,0 +1,280 @@
+/*
+ * 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_DISPLAY_WHITE_BALANCE;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.ColorSpace;
+import android.hardware.display.ColorDisplayManager;
+import android.opengl.Matrix;
+import android.os.IBinder;
+import android.util.Slog;
+import android.view.SurfaceControl;
+import android.view.SurfaceControl.DisplayPrimaries;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+final class DisplayWhiteBalanceTintController extends TintController {
+
+    // Three chromaticity coordinates per color: X, Y, and Z
+    private static final int NUM_VALUES_PER_PRIMARY = 3;
+    // Four colors: red, green, blue, and white
+    private static final int NUM_DISPLAY_PRIMARIES_VALS = 4 * NUM_VALUES_PER_PRIMARY;
+
+    private final Object mLock = new Object();
+    @VisibleForTesting
+    int mTemperatureMin;
+    @VisibleForTesting
+    int mTemperatureMax;
+    private int mTemperatureDefault;
+    private float[] mDisplayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+    @VisibleForTesting
+    ColorSpace.Rgb mDisplayColorSpaceRGB;
+    private float[] mChromaticAdaptationMatrix;
+    @VisibleForTesting
+    int mCurrentColorTemperature;
+    private float[] mCurrentColorTemperatureXYZ;
+    private boolean mSetUp = false;
+    private float[] mMatrixDisplayWhiteBalance = new float[16];
+    private Boolean mIsAvailable;
+
+    @Override
+    public void setUp(Context context, boolean needsLinear) {
+        mSetUp = false;
+        final Resources res = context.getResources();
+
+        ColorSpace.Rgb displayColorSpaceRGB = getDisplayColorSpaceFromSurfaceControl();
+        if (displayColorSpaceRGB == null) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Failed to get display color space from SurfaceControl, trying res");
+            displayColorSpaceRGB = getDisplayColorSpaceFromResources(res);
+            if (displayColorSpaceRGB == null) {
+                Slog.e(ColorDisplayService.TAG, "Failed to get display color space from resources");
+                return;
+            }
+        }
+
+        final String[] nominalWhiteValues = res.getStringArray(
+                R.array.config_displayWhiteBalanceDisplayNominalWhite);
+        float[] displayNominalWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+        for (int i = 0; i < nominalWhiteValues.length; i++) {
+            displayNominalWhiteXYZ[i] = Float.parseFloat(nominalWhiteValues[i]);
+        }
+
+        final int colorTemperatureMin = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureMin);
+        if (colorTemperatureMin <= 0) {
+            Slog.e(ColorDisplayService.TAG,
+                    "Display white balance minimum temperature must be greater than 0");
+            return;
+        }
+
+        final int colorTemperatureMax = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureMax);
+        if (colorTemperatureMax < colorTemperatureMin) {
+            Slog.e(ColorDisplayService.TAG,
+                    "Display white balance max temp must be greater or equal to min");
+            return;
+        }
+
+        final int colorTemperature = res.getInteger(
+                R.integer.config_displayWhiteBalanceColorTemperatureDefault);
+
+        synchronized (mLock) {
+            mDisplayColorSpaceRGB = displayColorSpaceRGB;
+            mDisplayNominalWhiteXYZ = displayNominalWhiteXYZ;
+            mTemperatureMin = colorTemperatureMin;
+            mTemperatureMax = colorTemperatureMax;
+            mTemperatureDefault = colorTemperature;
+            mSetUp = true;
+        }
+
+        setMatrix(mTemperatureDefault);
+    }
+
+    @Override
+    public float[] getMatrix() {
+        return mSetUp && isActivated() ? mMatrixDisplayWhiteBalance
+                : ColorDisplayService.MATRIX_IDENTITY;
+    }
+
+    @Override
+    public void setMatrix(int cct) {
+        if (!mSetUp) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Can't set display white balance temperature: uninitialized");
+            return;
+        }
+
+        if (cct < mTemperatureMin) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Requested display color temperature is below allowed minimum");
+            cct = mTemperatureMin;
+        } else if (cct > mTemperatureMax) {
+            Slog.w(ColorDisplayService.TAG,
+                    "Requested display color temperature is above allowed maximum");
+            cct = mTemperatureMax;
+        }
+
+        Slog.d(ColorDisplayService.TAG, "setDisplayWhiteBalanceTemperatureMatrix: cct = " + cct);
+
+        synchronized (mLock) {
+            mCurrentColorTemperature = cct;
+
+            // Adapt the display's nominal white point to match the requested CCT value
+            mCurrentColorTemperatureXYZ = ColorSpace.cctToXyz(cct);
+
+            mChromaticAdaptationMatrix =
+                    ColorSpace.chromaticAdaptation(ColorSpace.Adaptation.BRADFORD,
+                            mDisplayNominalWhiteXYZ, mCurrentColorTemperatureXYZ);
+
+            // Convert the adaptation matrix to RGB space
+            float[] result = ColorSpace.mul3x3(mChromaticAdaptationMatrix,
+                    mDisplayColorSpaceRGB.getTransform());
+            result = ColorSpace.mul3x3(mDisplayColorSpaceRGB.getInverseTransform(), result);
+
+            // Normalize the transform matrix to peak white value in RGB space
+            final float adaptedMaxR = result[0] + result[3] + result[6];
+            final float adaptedMaxG = result[1] + result[4] + result[7];
+            final float adaptedMaxB = result[2] + result[5] + result[8];
+            final float denum = Math.max(Math.max(adaptedMaxR, adaptedMaxG), adaptedMaxB);
+            for (int i = 0; i < result.length; i++) {
+                result[i] /= denum;
+            }
+
+            Matrix.setIdentityM(mMatrixDisplayWhiteBalance, 0);
+            java.lang.System.arraycopy(result, 0, mMatrixDisplayWhiteBalance, 0, 3);
+            java.lang.System.arraycopy(result, 3, mMatrixDisplayWhiteBalance, 4, 3);
+            java.lang.System.arraycopy(result, 6, mMatrixDisplayWhiteBalance, 8, 3);
+        }
+    }
+
+    @Override
+    public int getLevel() {
+        return LEVEL_COLOR_MATRIX_DISPLAY_WHITE_BALANCE;
+    }
+
+    @Override
+    public boolean isAvailable(Context context) {
+        if (mIsAvailable == null) {
+            mIsAvailable = ColorDisplayManager.isDisplayWhiteBalanceAvailable(context);
+        }
+        return mIsAvailable;
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        synchronized (mLock) {
+            pw.println("    mSetUp = " + mSetUp);
+            if (!mSetUp) {
+                return;
+            }
+
+            pw.println("    mTemperatureMin = " + mTemperatureMin);
+            pw.println("    mTemperatureMax = " + mTemperatureMax);
+            pw.println("    mTemperatureDefault = " + mTemperatureDefault);
+            pw.println("    mCurrentColorTemperature = " + mCurrentColorTemperature);
+            pw.println("    mCurrentColorTemperatureXYZ = "
+                    + matrixToString(mCurrentColorTemperatureXYZ, 3));
+            pw.println("    mDisplayColorSpaceRGB RGB-to-XYZ = "
+                    + matrixToString(mDisplayColorSpaceRGB.getTransform(), 3));
+            pw.println("    mChromaticAdaptationMatrix = "
+                    + matrixToString(mChromaticAdaptationMatrix, 3));
+            pw.println("    mDisplayColorSpaceRGB XYZ-to-RGB = "
+                    + matrixToString(mDisplayColorSpaceRGB.getInverseTransform(), 3));
+            pw.println("    mMatrixDisplayWhiteBalance = "
+                    + matrixToString(mMatrixDisplayWhiteBalance, 4));
+        }
+    }
+
+    /**
+     * Format a given matrix into a string.
+     *
+     * @param matrix the matrix to format
+     * @param columns number of columns in the matrix
+     */
+    private String matrixToString(float[] matrix, int columns) {
+        if (matrix == null || columns <= 0) {
+            Slog.e(ColorDisplayService.TAG, "Invalid arguments when formatting matrix to string");
+            return "";
+        }
+
+        final StringBuilder sb = new StringBuilder("");
+        for (int i = 0; i < matrix.length; i++) {
+            if (i % columns == 0) {
+                sb.append("\n      ");
+            }
+            sb.append(String.format("%9.6f", matrix[i]));
+        }
+        return sb.toString();
+    }
+
+    private ColorSpace.Rgb makeRgbColorSpaceFromXYZ(float[] redGreenBlueXYZ, float[] whiteXYZ) {
+        return new ColorSpace.Rgb(
+                "Display Color Space",
+                redGreenBlueXYZ,
+                whiteXYZ,
+                2.2f // gamma, unused for display white balance
+        );
+    }
+
+    private ColorSpace.Rgb getDisplayColorSpaceFromSurfaceControl() {
+        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
+        if (displayToken == null) {
+            return null;
+        }
+
+        DisplayPrimaries primaries = SurfaceControl.getDisplayNativePrimaries(displayToken);
+        if (primaries == null || primaries.red == null || primaries.green == null
+                || primaries.blue == null || primaries.white == null) {
+            return null;
+        }
+
+        return makeRgbColorSpaceFromXYZ(
+                new float[]{
+                        primaries.red.X, primaries.red.Y, primaries.red.Z,
+                        primaries.green.X, primaries.green.Y, primaries.green.Z,
+                        primaries.blue.X, primaries.blue.Y, primaries.blue.Z,
+                },
+                new float[]{primaries.white.X, primaries.white.Y, primaries.white.Z}
+        );
+    }
+
+    private ColorSpace.Rgb getDisplayColorSpaceFromResources(Resources res) {
+        final String[] displayPrimariesValues = res.getStringArray(
+                R.array.config_displayWhiteBalanceDisplayPrimaries);
+        float[] displayRedGreenBlueXYZ =
+                new float[NUM_DISPLAY_PRIMARIES_VALS - NUM_VALUES_PER_PRIMARY];
+        float[] displayWhiteXYZ = new float[NUM_VALUES_PER_PRIMARY];
+
+        for (int i = 0; i < displayRedGreenBlueXYZ.length; i++) {
+            displayRedGreenBlueXYZ[i] = Float.parseFloat(displayPrimariesValues[i]);
+        }
+
+        for (int i = 0; i < displayWhiteXYZ.length; i++) {
+            displayWhiteXYZ[i] = Float.parseFloat(
+                    displayPrimariesValues[displayRedGreenBlueXYZ.length + i]);
+        }
+
+        return makeRgbColorSpaceFromXYZ(displayRedGreenBlueXYZ, displayWhiteXYZ);
+    }
+}
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..a3d758d
--- /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. */
+final 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/infra/AbstractPerUserSystemService.java b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
index ac07e9d..c52921e 100644
--- a/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractPerUserSystemService.java
@@ -113,6 +113,13 @@
     }
 
     /**
+     * Gets whether the service is disabled by {@link UserManager} restrictions.
+     */
+    protected final boolean isDisabledByUserRestrictionsLocked() {
+        return mDisabled;
+    }
+
+    /**
      * Updates the state of this service.
      *
      * <p>Typically called when the service {@link Settings} property or {@link UserManager}
@@ -136,7 +143,9 @@
                     + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
         }
 
-        mSetupComplete = isSetupCompletedLocked();
+        final String setupComplete = Settings.Secure.getStringForUser(
+                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
+        mSetupComplete = "1".equals(setupComplete);
         mDisabled = disabled;
 
         updateServiceInfoLocked();
@@ -235,6 +244,15 @@
     }
 
     /**
+     * Gets the {@link ServiceInfo} of the remote service this service binds to, or {@code null}
+     * if the service is disabled.
+     */
+    @Nullable
+    public final ServiceInfo getServiceInfo() {
+        return mServiceInfo;
+    }
+
+    /**
      * Gets the {@link ComponentName} of the remote service this service binds to, or {@code null}
      * if the service is disabled.
      */
@@ -311,9 +329,7 @@
      * Gets whether the device already finished setup.
      */
     protected final boolean isSetupCompletedLocked() {
-        final String setupComplete = Settings.Secure.getStringForUser(
-                getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
-        return "1".equals(setupComplete);
+        return mSetupComplete;
     }
 
     /**
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/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index e0fb9e7..a8c16c7 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -27,10 +27,10 @@
 import android.media.MediaParceledListSlice;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.session.ControllerCallbackLink;
 import android.media.session.ISession;
 import android.media.session.ISessionCallback;
 import android.media.session.ISessionController;
+import android.media.session.ISessionControllerCallback;
 import android.media.session.MediaController;
 import android.media.session.MediaController.PlaybackInfo;
 import android.media.session.MediaSession;
@@ -88,7 +88,7 @@
     private final Context mContext;
 
     private final Object mLock = new Object();
-    private final ArrayList<ControllerCallbackLinkHolder> mControllerCallbackHolders =
+    private final ArrayList<ISessionControllerCallbackHolder> mControllerCallbackHolders =
             new ArrayList<>();
 
     private long mFlags;
@@ -265,7 +265,7 @@
      * @param useSuggested True to use adjustSuggestedStreamVolume instead of
      */
     public void adjustVolume(String packageName, String opPackageName, int pid, int uid,
-            ControllerCallbackLink caller, boolean asSystemService, int direction, int flags,
+            ISessionControllerCallback caller, boolean asSystemService, int direction, int flags,
             boolean useSuggested) {
         int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
         if (isPlaybackActive() || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
@@ -311,7 +311,7 @@
     }
 
     private void setVolumeTo(String packageName, String opPackageName, int pid, int uid,
-            ControllerCallbackLink caller, int value, int flags) {
+            ISessionControllerCallback caller, int value, int flags) {
         if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
             int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
             final int volumeValue = value;
@@ -558,7 +558,7 @@
     }
 
     private void logCallbackException(
-            String msg, ControllerCallbackLinkHolder holder, Exception e) {
+            String msg, ISessionControllerCallbackHolder holder, Exception e) {
         Log.v(TAG, msg + ", this=" + this + ", callback package=" + holder.mPackageName
                 + ", exception=" + e);
     }
@@ -569,18 +569,16 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyPlaybackStateChanged(mPlaybackState);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushPlaybackStateUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onPlaybackStateChanged(mPlaybackState);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushPlaybackStateUpdate",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushPlaybackStateUpdate",
+                            holder, e);
                 }
             }
         }
@@ -592,18 +590,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyMetadataChanged(mMetadata);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushMetadataUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushMetadataUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onMetadataChanged(mMetadata);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushMetadataUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushMetadataUpdate", holder, e);
                 }
             }
         }
@@ -615,17 +609,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyQueueChanged(mQueue);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushQueueUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
-                    }
+                    holder.mCallback.onQueueChanged(mQueue == null ? null :
+                            new MediaParceledListSlice<>(mQueue));
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushQueueUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushQueueUpdate", holder, e);
                 }
             }
         }
@@ -637,18 +629,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyQueueTitleChanged(mQueueTitle);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushQueueTitleUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushQueueTitleUpdate",
-                                holder, e);
-                    }
+                    holder.mCallback.onQueueTitleChanged(mQueueTitle);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushQueueTitleUpdate",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushQueueTitleUpdate", holder, e);
                 }
             }
         }
@@ -660,17 +649,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyExtrasChanged(mExtras);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushExtrasUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
-                    }
+                    holder.mCallback.onExtrasChanged(mExtras);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushExtrasUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushExtrasUpdate", holder, e);
                 }
             }
         }
@@ -683,17 +669,14 @@
             }
             PlaybackInfo info = getVolumeAttributes();
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyVolumeInfoChanged(info);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushVolumeUpdate",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
-                    }
+                    holder.mCallback.onVolumeInfoChanged(info);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushVolumeUpdate", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushVolumeUpdate", holder, e);
                 }
             }
         }
@@ -705,16 +688,14 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifyEvent(event, data);
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushEvent", holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushEvent", holder, e);
-                    }
+                    holder.mCallback.onEvent(event, data);
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushEvent", holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushEvent", holder, e);
                 }
             }
         }
@@ -728,18 +709,15 @@
                 return;
             }
             for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-                ControllerCallbackLinkHolder holder = mControllerCallbackHolders.get(i);
+                ISessionControllerCallbackHolder holder = mControllerCallbackHolders.get(i);
                 try {
-                    holder.mCallback.notifySessionDestroyed();
-                } catch (RuntimeException e) {
-                    if (e.getCause() instanceof DeadObjectException) {
-                        mControllerCallbackHolders.remove(i);
-                        logCallbackException("Removing dead callback in pushSessionDestroyed",
-                                holder, e);
-                    } else {
-                        logCallbackException("unexpected exception in pushSessionDestroyed",
-                                holder, e);
-                    }
+                    holder.mCallback.onSessionDestroyed();
+                } catch (DeadObjectException e) {
+                    mControllerCallbackHolders.remove(i);
+                    logCallbackException("Removing dead callback in pushSessionDestroyed",
+                            holder, e);
+                } catch (RemoteException e) {
+                    logCallbackException("unexpected exception in pushSessionDestroyed", holder, e);
                 }
             }
             // After notifying clear all listeners
@@ -779,10 +757,10 @@
         return result == null ? state : result;
     }
 
-    private int getControllerHolderIndexForCb(ControllerCallbackLink cb) {
-        IBinder binder = cb.getBinder();
+    private int getControllerHolderIndexForCb(ISessionControllerCallback cb) {
+        IBinder binder = cb.asBinder();
         for (int i = mControllerCallbackHolders.size() - 1; i >= 0; i--) {
-            if (binder.equals(mControllerCallbackHolders.get(i).mCallback.getBinder())) {
+            if (binder.equals(mControllerCallbackHolders.get(i).mCallback.asBinder())) {
                 return i;
             }
         }
@@ -1027,7 +1005,7 @@
         }
 
         public boolean sendMediaButton(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, boolean asSystemService,
+                ISessionControllerCallback caller, boolean asSystemService,
                 KeyEvent keyEvent) {
             try {
                 if (asSystemService) {
@@ -1045,7 +1023,7 @@
         }
 
         public void sendCommand(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
+                ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
             try {
                 mCb.onCommand(packageName, pid, uid, caller, command, args, cb);
             } catch (RemoteException e) {
@@ -1054,7 +1032,7 @@
         }
 
         public void sendCustomAction(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String action,
+                ISessionControllerCallback caller, String action,
                 Bundle args) {
             try {
                 mCb.onCustomAction(packageName, pid, uid, caller, action, args);
@@ -1064,7 +1042,7 @@
         }
 
         public void prepare(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onPrepare(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1073,7 +1051,7 @@
         }
 
         public void prepareFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId, Bundle extras) {
+                ISessionControllerCallback caller, String mediaId, Bundle extras) {
             try {
                 mCb.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
             } catch (RemoteException e) {
@@ -1082,7 +1060,7 @@
         }
 
         public void prepareFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query, Bundle extras) {
+                ISessionControllerCallback caller, String query, Bundle extras) {
             try {
                 mCb.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
             } catch (RemoteException e) {
@@ -1091,7 +1069,7 @@
         }
 
         public void prepareFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             try {
                 mCb.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
             } catch (RemoteException e) {
@@ -1099,7 +1077,7 @@
             }
         }
 
-        public void play(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void play(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onPlay(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1108,7 +1086,7 @@
         }
 
         public void playFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId, Bundle extras) {
+                ISessionControllerCallback caller, String mediaId, Bundle extras) {
             try {
                 mCb.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
             } catch (RemoteException e) {
@@ -1117,7 +1095,7 @@
         }
 
         public void playFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query, Bundle extras) {
+                ISessionControllerCallback caller, String query, Bundle extras) {
             try {
                 mCb.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
             } catch (RemoteException e) {
@@ -1126,7 +1104,7 @@
         }
 
         public void playFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+                ISessionControllerCallback caller, Uri uri, Bundle extras) {
             try {
                 mCb.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
             } catch (RemoteException e) {
@@ -1135,7 +1113,7 @@
         }
 
         public void skipToTrack(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long id) {
+                ISessionControllerCallback caller, long id) {
             try {
                 mCb.onSkipToTrack(packageName, pid, uid, caller, id);
             } catch (RemoteException e) {
@@ -1143,7 +1121,7 @@
             }
         }
 
-        public void pause(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void pause(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onPause(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1151,7 +1129,7 @@
             }
         }
 
-        public void stop(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void stop(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onStop(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1159,7 +1137,7 @@
             }
         }
 
-        public void next(String packageName, int pid, int uid, ControllerCallbackLink caller) {
+        public void next(String packageName, int pid, int uid, ISessionControllerCallback caller) {
             try {
                 mCb.onNext(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1168,7 +1146,7 @@
         }
 
         public void previous(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onPrevious(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1177,7 +1155,7 @@
         }
 
         public void fastForward(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onFastForward(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1186,7 +1164,7 @@
         }
 
         public void rewind(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
+                ISessionControllerCallback caller) {
             try {
                 mCb.onRewind(packageName, pid, uid, caller);
             } catch (RemoteException e) {
@@ -1194,7 +1172,7 @@
             }
         }
 
-        public void seekTo(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void seekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 long pos) {
             try {
                 mCb.onSeekTo(packageName, pid, uid, caller, pos);
@@ -1203,7 +1181,7 @@
             }
         }
 
-        public void rate(String packageName, int pid, int uid, ControllerCallbackLink caller,
+        public void rate(String packageName, int pid, int uid, ISessionControllerCallback caller,
                 Rating rating) {
             try {
                 mCb.onRate(packageName, pid, uid, caller, rating);
@@ -1213,7 +1191,7 @@
         }
 
         public void setPlaybackSpeed(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, float speed) {
+                ISessionControllerCallback caller, float speed) {
             try {
                 mCb.onSetPlaybackSpeed(packageName, pid, uid, caller, speed);
             } catch (RemoteException e) {
@@ -1222,7 +1200,7 @@
         }
 
         public void adjustVolume(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, boolean asSystemService, int direction) {
+                ISessionControllerCallback caller, boolean asSystemService, int direction) {
             try {
                 if (asSystemService) {
                     mCb.onAdjustVolume(mContext.getPackageName(), Process.myPid(),
@@ -1236,7 +1214,7 @@
         }
 
         public void setVolumeTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int value) {
+                ISessionControllerCallback caller, int value) {
             try {
                 mCb.onSetVolumeTo(packageName, pid, uid, caller, value);
             } catch (RemoteException e) {
@@ -1253,34 +1231,34 @@
 
     class ControllerStub extends ISessionController.Stub {
         @Override
-        public void sendCommand(String packageName, ControllerCallbackLink caller,
+        public void sendCommand(String packageName, ISessionControllerCallback caller,
                 String command, Bundle args, ResultReceiver cb) {
             mSessionCb.sendCommand(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, command, args, cb);
         }
 
         @Override
-        public boolean sendMediaButton(String packageName, ControllerCallbackLink cb,
+        public boolean sendMediaButton(String packageName, ISessionControllerCallback cb,
                 KeyEvent keyEvent) {
             return mSessionCb.sendMediaButton(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), cb, false, keyEvent);
         }
 
         @Override
-        public void registerCallback(String packageName, ControllerCallbackLink cb) {
+        public void registerCallback(String packageName, ISessionControllerCallback cb) {
             synchronized (mLock) {
                 // If this session is already destroyed tell the caller and
                 // don't add them.
                 if (mDestroyed) {
                     try {
-                        cb.notifySessionDestroyed();
+                        cb.onSessionDestroyed();
                     } catch (Exception e) {
                         // ignored
                     }
                     return;
                 }
                 if (getControllerHolderIndexForCb(cb) < 0) {
-                    mControllerCallbackHolders.add(new ControllerCallbackLinkHolder(cb,
+                    mControllerCallbackHolders.add(new ISessionControllerCallbackHolder(cb,
                             packageName, Binder.getCallingUid()));
                     if (DEBUG) {
                         Log.d(TAG, "registering controller callback " + cb + " from controller"
@@ -1291,14 +1269,14 @@
         }
 
         @Override
-        public void unregisterCallback(ControllerCallbackLink cb) {
+        public void unregisterCallback(ISessionControllerCallback cb) {
             synchronized (mLock) {
                 int index = getControllerHolderIndexForCb(cb);
                 if (index != -1) {
                     mControllerCallbackHolders.remove(index);
                 }
                 if (DEBUG) {
-                    Log.d(TAG, "unregistering callback " + cb.getBinder());
+                    Log.d(TAG, "unregistering callback " + cb.asBinder());
                 }
             }
         }
@@ -1335,7 +1313,7 @@
 
         @Override
         public void adjustVolume(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int direction, int flags) {
+                ISessionControllerCallback caller, int direction, int flags) {
             int pid = Binder.getCallingPid();
             int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
@@ -1349,7 +1327,7 @@
 
         @Override
         public void setVolumeTo(String packageName, String opPackageName,
-                ControllerCallbackLink caller, int value, int flags) {
+                ISessionControllerCallback caller, int value, int flags) {
             int pid = Binder.getCallingPid();
             int uid = Binder.getCallingUid();
             final long token = Binder.clearCallingIdentity();
@@ -1362,117 +1340,117 @@
         }
 
         @Override
-        public void prepare(String packageName, ControllerCallbackLink caller) {
+        public void prepare(String packageName, ISessionControllerCallback caller) {
             mSessionCb.prepare(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void prepareFromMediaId(String packageName, ControllerCallbackLink caller,
+        public void prepareFromMediaId(String packageName, ISessionControllerCallback caller,
                 String mediaId, Bundle extras) {
             mSessionCb.prepareFromMediaId(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), caller, mediaId, extras);
         }
 
         @Override
-        public void prepareFromSearch(String packageName, ControllerCallbackLink caller,
+        public void prepareFromSearch(String packageName, ISessionControllerCallback caller,
                 String query, Bundle extras) {
             mSessionCb.prepareFromSearch(packageName, Binder.getCallingPid(),
                     Binder.getCallingUid(), caller, query, extras);
         }
 
         @Override
-        public void prepareFromUri(String packageName, ControllerCallbackLink caller,
+        public void prepareFromUri(String packageName, ISessionControllerCallback caller,
                 Uri uri, Bundle extras) {
             mSessionCb.prepareFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, uri, extras);
         }
 
         @Override
-        public void play(String packageName, ControllerCallbackLink caller) {
+        public void play(String packageName, ISessionControllerCallback caller) {
             mSessionCb.play(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void playFromMediaId(String packageName, ControllerCallbackLink caller,
+        public void playFromMediaId(String packageName, ISessionControllerCallback caller,
                 String mediaId, Bundle extras) {
             mSessionCb.playFromMediaId(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, mediaId, extras);
         }
 
         @Override
-        public void playFromSearch(String packageName, ControllerCallbackLink caller,
+        public void playFromSearch(String packageName, ISessionControllerCallback caller,
                 String query, Bundle extras) {
             mSessionCb.playFromSearch(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, query, extras);
         }
 
         @Override
-        public void playFromUri(String packageName, ControllerCallbackLink caller,
+        public void playFromUri(String packageName, ISessionControllerCallback caller,
                 Uri uri, Bundle extras) {
             mSessionCb.playFromUri(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, uri, extras);
         }
 
         @Override
-        public void skipToQueueItem(String packageName, ControllerCallbackLink caller,
+        public void skipToQueueItem(String packageName, ISessionControllerCallback caller,
                 long id) {
             mSessionCb.skipToTrack(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, id);
         }
 
         @Override
-        public void pause(String packageName, ControllerCallbackLink caller) {
+        public void pause(String packageName, ISessionControllerCallback caller) {
             mSessionCb.pause(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void stop(String packageName, ControllerCallbackLink caller) {
+        public void stop(String packageName, ISessionControllerCallback caller) {
             mSessionCb.stop(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void next(String packageName, ControllerCallbackLink caller) {
+        public void next(String packageName, ISessionControllerCallback caller) {
             mSessionCb.next(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void previous(String packageName, ControllerCallbackLink caller) {
+        public void previous(String packageName, ISessionControllerCallback caller) {
             mSessionCb.previous(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller);
         }
 
         @Override
-        public void fastForward(String packageName, ControllerCallbackLink caller) {
+        public void fastForward(String packageName, ISessionControllerCallback caller) {
             mSessionCb.fastForward(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller);
         }
 
         @Override
-        public void rewind(String packageName, ControllerCallbackLink caller) {
+        public void rewind(String packageName, ISessionControllerCallback caller) {
             mSessionCb.rewind(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller);
         }
 
         @Override
-        public void seekTo(String packageName, ControllerCallbackLink caller, long pos) {
+        public void seekTo(String packageName, ISessionControllerCallback caller, long pos) {
             mSessionCb.seekTo(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                     pos);
         }
 
         @Override
-        public void rate(String packageName, ControllerCallbackLink caller, Rating rating) {
+        public void rate(String packageName, ISessionControllerCallback caller, Rating rating) {
             mSessionCb.rate(packageName, Binder.getCallingPid(), Binder.getCallingUid(), caller,
                     rating);
         }
 
         @Override
-        public void setPlaybackSpeed(String packageName, ControllerCallbackLink caller,
+        public void setPlaybackSpeed(String packageName, ISessionControllerCallback caller,
                 float speed) {
             mSessionCb.setPlaybackSpeed(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, speed);
         }
 
         @Override
-        public void sendCustomAction(String packageName, ControllerCallbackLink caller,
+        public void sendCustomAction(String packageName, ISessionControllerCallback caller,
                 String action, Bundle args) {
             mSessionCb.sendCustomAction(packageName, Binder.getCallingPid(), Binder.getCallingUid(),
                     caller, action, args);
@@ -1515,12 +1493,12 @@
         }
     }
 
-    private class ControllerCallbackLinkHolder {
-        private final ControllerCallbackLink mCallback;
+    private class ISessionControllerCallbackHolder {
+        private final ISessionControllerCallback mCallback;
         private final String mPackageName;
         private final int mUid;
 
-        ControllerCallbackLinkHolder(ControllerCallbackLink callback, String packageName,
+        ISessionControllerCallbackHolder(ISessionControllerCallback callback, String packageName,
                 int uid) {
             mCallback = callback;
             mPackageName = packageName;
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..81448b7 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;
@@ -20010,8 +20027,12 @@
      */
     public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
             int userId) {
+        if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
+            return;
+        }
         Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
-                .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo);
+                .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
+                .setPackage(sessionInfo.installerPackageName);
         mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
     }
 
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/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index d632749..6630926 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -1015,6 +1015,9 @@
 
     @Override
     public boolean notifyStagedSession(int sessionId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("notifyStagedSession may only be called by the system.");
+        }
         final LinkedBlockingQueue<Boolean> result = new LinkedBlockingQueue<>();
 
         // NOTE: We post this runnable on the RollbackManager's binder thread because we'd prefer
@@ -1066,6 +1069,9 @@
 
     @Override
     public void notifyStagedApkSession(int originalSessionId, int apkSessionId) {
+        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+            throw new SecurityException("notifyStagedApkSession may only be called by the system.");
+        }
         getHandler().post(() -> {
             RollbackData rd = null;
             synchronized (mLock) {
diff --git a/services/core/java/com/android/server/stats/StatsCompanionService.java b/services/core/java/com/android/server/stats/StatsCompanionService.java
index 1800433..28a853f 100644
--- a/services/core/java/com/android/server/stats/StatsCompanionService.java
+++ b/services/core/java/com/android/server/stats/StatsCompanionService.java
@@ -1724,7 +1724,7 @@
             throw new IllegalStateException("mKernelCpuThreadReader is null");
         }
         ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsages =
-                this.mKernelCpuThreadReader.getProcessCpuUsageByUids();
+                this.mKernelCpuThreadReader.getProcessCpuUsage();
         if (processCpuUsages == null) {
             throw new IllegalStateException("processCpuUsages is null");
         }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e53fde9..5502bb9 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -77,6 +77,7 @@
 import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.os.storage.StorageManager;
 import android.service.wallpaper.IWallpaperConnection;
 import android.service.wallpaper.IWallpaperEngine;
 import android.service.wallpaper.IWallpaperService;
@@ -2089,28 +2090,14 @@
         }
     }
 
-    private void enforceCallingOrSelfPermissionAndAppOp(String permission, final String callingPkg,
-            final int callingUid, String message) {
-        mContext.enforceCallingOrSelfPermission(permission, message);
-
-        final String opName = AppOpsManager.permissionToOp(permission);
-        if (opName != null) {
-            final int appOpMode = mAppOpsManager.noteOp(opName, callingUid, callingPkg);
-            if (appOpMode != AppOpsManager.MODE_ALLOWED) {
-                throw new SecurityException(
-                        message + ": " + callingPkg + " is not allowed to " + permission);
-            }
-        }
-    }
-
     @Override
     public ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb,
             final int which, Bundle outParams, int wallpaperUserId) {
         final int hasPrivilege = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.READ_WALLPAPER_INTERNAL);
         if (hasPrivilege != PackageManager.PERMISSION_GRANTED) {
-            enforceCallingOrSelfPermissionAndAppOp(android.Manifest.permission.READ_EXTERNAL_STORAGE,
-                    callingPkg, Binder.getCallingUid(), "read wallpaper");
+            mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
+                    Binder.getCallingPid(), Binder.getCallingUid(), callingPkg);
         }
 
         wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index bbbf11d..9f7cb3d 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -49,7 +49,7 @@
     private static final String TAG = TAG_WITH_CLASS_NAME ? "AppWindowThumbnail" : TAG_WM;
 
     private final AppWindowToken mAppToken;
-    private final SurfaceControl mSurfaceControl;
+    private SurfaceControl mSurfaceControl;
     private final SurfaceAnimator mSurfaceAnimator;
     private final int mWidth;
     private final int mHeight;
@@ -68,10 +68,21 @@
      */
     AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader,
             boolean relative) {
+        this(t, appToken, thumbnailHeader, relative, new Surface(), null);
+    }
+
+    AppWindowThumbnail(Transaction t, AppWindowToken appToken, GraphicBuffer thumbnailHeader,
+            boolean relative, Surface drawSurface, SurfaceAnimator animator) {
         mAppToken = appToken;
         mRelative = relative;
-        mSurfaceAnimator =
+        if (animator != null) {
+            mSurfaceAnimator = animator;
+        } else {
+            // We can't use a delegating constructor since we need to
+            // reference this::onAnimationFinished
+            mSurfaceAnimator =
                 new SurfaceAnimator(this, this::onAnimationFinished, appToken.mWmService);
+        }
         mWidth = thumbnailHeader.getWidth();
         mHeight = thumbnailHeader.getHeight();
 
@@ -95,7 +106,6 @@
         }
 
         // Transfer the thumbnail to the surface
-        Surface drawSurface = new Surface();
         drawSurface.copyFrom(mSurfaceControl);
         drawSurface.attachAndQueueBuffer(thumbnailHeader);
         drawSurface.release();
@@ -145,6 +155,7 @@
     void destroy() {
         mSurfaceAnimator.cancelAnimation();
         getPendingTransaction().remove(mSurfaceControl);
+        mSurfaceControl = null;
     }
 
     /**
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/mockingservicestests/src/com/android/server/am/AppCompactorTest.java b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
index e100d16..da439b8 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/AppCompactorTest.java
@@ -44,7 +44,7 @@
  * Tests for {@link AppCompactor}.
  *
  * Build/Install/Run:
- * atest FrameworksServicesTests:AppCompactorTest
+ * atest FrameworksMockingServicesTests:AppCompactorTest
  */
 @RunWith(MockitoJUnitRunner.class)
 public final class AppCompactorTest {
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 2f427b0..de841a0 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -124,7 +124,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -133,7 +133,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -142,7 +142,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -151,7 +151,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -160,7 +160,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -169,7 +169,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -178,7 +178,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -187,7 +187,7 @@
     @Test
     public void customSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeCustom(-120 /* startTimeOffset */, -60 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -196,7 +196,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -205,7 +205,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -214,7 +214,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -223,7 +223,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -232,7 +232,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -241,7 +241,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -250,7 +250,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -259,7 +259,7 @@
     @Test
     public void customSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeCustom(60 /* startTimeOffset */, 120 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -268,7 +268,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -277,7 +277,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -286,7 +286,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -295,7 +295,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -304,7 +304,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -313,7 +313,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -322,7 +322,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -331,7 +331,7 @@
     @Test
     public void customSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeCustom(-60 /* startTimeOffset */, 60 /* endTimeOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -340,7 +340,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -349,7 +349,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -358,7 +358,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -367,7 +367,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -376,7 +376,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -385,7 +385,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -394,7 +394,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -403,7 +403,7 @@
     @Test
     public void twilightSchedule_whenStartedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -412,7 +412,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -421,7 +421,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -430,7 +430,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -439,7 +439,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -448,7 +448,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -457,7 +457,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -466,7 +466,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -475,7 +475,7 @@
     @Test
     public void twilightSchedule_whenStartedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -484,7 +484,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -493,7 +493,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -502,7 +502,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -511,7 +511,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(false /* activated */);
@@ -520,7 +520,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -529,7 +529,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -538,7 +538,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -547,7 +547,7 @@
     @Test
     public void twilightSchedule_whenStartedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         startService();
         assertActivated(true /* activated */);
@@ -556,7 +556,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -571,7 +571,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -586,7 +586,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -601,7 +601,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOffInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -616,7 +616,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -631,7 +631,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -646,7 +646,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -661,7 +661,7 @@
     @Test
     public void twilightSchedule_whenRebootedAfterNight_ifOnInFuture_turnsOff() {
         setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -676,7 +676,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -691,7 +691,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -706,7 +706,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -721,7 +721,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOffInPast_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -736,7 +736,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnAfterNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 180 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -751,7 +751,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnBeforeNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -766,7 +766,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnDuringNight_turnsOff() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -781,7 +781,7 @@
     @Test
     public void twilightSchedule_whenRebootedBeforeNight_ifOnInPast_turnsOn() {
         setAutoModeTwilight(60 /* sunsetOffset */, 120 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -796,7 +796,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -811,7 +811,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -826,7 +826,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -841,7 +841,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOffDuringNightInPast_turnsOff() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -856,7 +856,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnAfterNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -871,7 +871,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnBeforeNight_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -90 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -886,7 +886,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInFuture_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, 30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -901,7 +901,7 @@
     @Test
     public void twilightSchedule_whenRebootedDuringNight_ifOnDuringNightInPast_turnsOn() {
         setAutoModeTwilight(-60 /* sunsetOffset */, 60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         final TwilightState state = mTwilightManager.getLastTwilightState();
         mTwilightManager.setTwilightState(null);
@@ -984,22 +984,19 @@
     }
 
     @Test
-    public void displayWhiteBalance_enable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+    public void displayWhiteBalance_enabled() {
+        setDisplayWhiteBalanceEnabled(true);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
         startService();
         assertDwbActive(true);
     }
 
     @Test
-    public void displayWhiteBalance_disableAfterNightDisplayEnable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-
+    public void displayWhiteBalance_disabledAfterNightDisplayEnabled() {
+        setDisplayWhiteBalanceEnabled(true);
         startService();
-        /* Enable nightlight */
-        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         /* Since we are using FakeSettingsProvider which could not trigger observer change,
          * force an update here.*/
@@ -1008,26 +1005,23 @@
     }
 
     @Test
-    public void displayWhiteBalance_enableAfterNightDisplayDisable() {
-        setWhiteBalance(true /* Enable DWB Setting */);
+    public void displayWhiteBalance_enabledAfterNightDisplayDisabled() {
+        setDisplayWhiteBalanceEnabled(true);
         startService();
-        /* Enable nightlight */
-        setAutoModeTwilight(-120 /* sunsetOffset */, -60 /* sunriseOffset */);
-        setActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(true /* activated */, -30 /* lastActivatedTimeOffset */);
 
         mCds.updateDisplayWhiteBalanceStatus();
         assertDwbActive(false);
 
-        /* Disable nightlight */
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         mCds.updateDisplayWhiteBalanceStatus();
         assertDwbActive(true);
     }
 
     @Test
-    public void displayWhiteBalance_enableAfterLinearColorMode() {
-        setWhiteBalance(true /* Enable DWB Setting */);
-        setActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+    public void displayWhiteBalance_enabledAfterLinearColorModeSelected() {
+        setDisplayWhiteBalanceEnabled(true);
+        setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
         startService();
         mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
 
@@ -1035,47 +1029,6 @@
         assertDwbActive(true);
     }
 
-    @Test
-    public void displayWhiteBalance_setTemperatureOverMax() {
-        int max = mCds.mDisplayWhiteBalanceTintController.mTemperatureMax;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(max + 1);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(max);
-    }
-
-    @Test
-    public void displayWhiteBalance_setTemperatureBelowMin() {
-        int min = mCds.mDisplayWhiteBalanceTintController.mTemperatureMin;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(min - 1);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(min);
-    }
-
-    @Test
-    public void displayWhiteBalance_setValidTemperature() {
-        int min = mCds.mDisplayWhiteBalanceTintController.mTemperatureMin;
-        int max = mCds.mDisplayWhiteBalanceTintController.mTemperatureMax;
-        int valToSet = (min + max) / 2;
-
-        ColorDisplayService.ColorDisplayServiceInternal cdsInternal = LocalServices.getService(
-                ColorDisplayService.ColorDisplayServiceInternal.class);
-        cdsInternal.setDisplayWhiteBalanceColorTemperature(valToSet);
-
-        assertWithMessage("Unexpected temperature set")
-                .that(mCds.mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
-                .isEqualTo(valToSet);
-    }
-
     /**
      * Configures Night display to use a custom schedule.
      *
@@ -1109,7 +1062,7 @@
      * @param lastActivatedTimeOffset the offset relative to now to record that Night display was
      * activated (in minutes)
      */
-    private void setActivated(boolean activated, int lastActivatedTimeOffset) {
+    private void setNightDisplayActivated(boolean activated, int lastActivatedTimeOffset) {
         mBinderService.setNightDisplayActivated(activated);
         Secure.putStringForUser(mContext.getContentResolver(),
                 Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
@@ -1140,11 +1093,11 @@
     /**
      * Configures the Display White Balance setting state.
      *
-     * @param state {@code true} if display white balance should be enabled
+     * @param enabled {@code true} if display white balance should be enabled
      */
-    private void setWhiteBalance(boolean state) {
+    private void setDisplayWhiteBalanceEnabled(boolean enabled) {
         Secure.putIntForUser(mContext.getContentResolver(),
-                Secure.DISPLAY_WHITE_BALANCE_ENABLED, state ? 1 : 0, mUserId);
+                Secure.DISPLAY_WHITE_BALANCE_ENABLED, enabled ? 1 : 0, mUserId);
     }
 
     /**
diff --git a/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
new file mode 100644
index 0000000..1dd4e15
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/color/DisplayWhiteBalanceTintControllerTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.assertWithMessage;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class DisplayWhiteBalanceTintControllerTest {
+
+    private DisplayWhiteBalanceTintController mDisplayWhiteBalanceTintController;
+
+    @Before
+    public void setUp() {
+        mDisplayWhiteBalanceTintController = new DisplayWhiteBalanceTintController();
+    }
+
+    @Test
+    public void displayWhiteBalance_setTemperatureOverMax() {
+        final int max = mDisplayWhiteBalanceTintController.mTemperatureMax;
+        mDisplayWhiteBalanceTintController.setMatrix(max + 1);
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(max);
+    }
+
+    @Test
+    public void displayWhiteBalance_setTemperatureBelowMin() {
+        final int min = mDisplayWhiteBalanceTintController.mTemperatureMin;
+        mDisplayWhiteBalanceTintController.setMatrix(min - 1);
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(min);
+    }
+
+    @Test
+    public void displayWhiteBalance_setValidTemperature() {
+        final int colorTemperature = (mDisplayWhiteBalanceTintController.mTemperatureMin
+                + mDisplayWhiteBalanceTintController.mTemperatureMax) / 2;
+        mDisplayWhiteBalanceTintController.setMatrix(colorTemperature);
+
+        assertWithMessage("Unexpected temperature set")
+                .that(mDisplayWhiteBalanceTintController.mCurrentColorTemperature)
+                .isEqualTo(colorTemperature);
+    }
+
+}
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/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
index febb795..380f7c6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
@@ -22,12 +22,11 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
 
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 
-import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
 import org.junit.Before;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index 9bd9930..b1ffbbd 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -24,9 +24,9 @@
 import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 import android.platform.test.annotations.Presubmit;
 import android.view.WindowManager;
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
new file mode 100644
index 0000000..fa0c384
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppWindowThumbnailTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.wm;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
+
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import android.graphics.GraphicBuffer;
+import android.graphics.PixelFormat;
+import android.platform.test.annotations.Presubmit;
+import android.view.Surface;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Test class for {@link TaskSnapshotSurface}.
+ *
+ * Build/Install/Run:
+ *  atest FrameworksServicesTest:AppWindowThumbnailTest
+ *
+ */
+@SmallTest
+@Presubmit
+public class AppWindowThumbnailTest extends WindowTestsBase {
+    private AppWindowThumbnail buildThumbnail() {
+        final GraphicBuffer buffer = GraphicBuffer.create(1, 1, PixelFormat.RGBA_8888,
+                GraphicBuffer.USAGE_SW_READ_RARELY | GraphicBuffer.USAGE_SW_WRITE_NEVER);
+        final AppWindowToken mockAwt = mock(AppWindowToken.class);
+        when(mockAwt.getPendingTransaction()).thenReturn(new StubTransaction());
+        when(mockAwt.makeSurface()).thenReturn(new MockSurfaceControlBuilder());
+        return new AppWindowThumbnail(new StubTransaction(), mockAwt,
+                buffer, false, mock(Surface.class), mock(SurfaceAnimator.class));
+    }
+
+    @Test
+    public void testDestroy_nullsSurface() {
+        final AppWindowThumbnail t = buildThumbnail();
+        assertNotNull(t.getSurfaceControl());
+        t.destroy();
+        assertNull(t.getSurfaceControl());
+    }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
index a166444..4e906bc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/PersisterQueueTests.java
@@ -18,11 +18,10 @@
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertSame;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
 import android.os.SystemClock;
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index 1c6afd54..3bedabc 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -18,8 +18,8 @@
 
 import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
 
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 
 import android.platform.test.annotations.Presubmit;
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index 792e8a6..113f3c8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -23,7 +23,7 @@
 import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME;
 import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL;
 
-import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertEquals;
 
 import android.platform.test.annotations.Presubmit;
 import android.util.ArraySet;
diff --git a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 8854ede..a91daf0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -16,9 +16,8 @@
 
 package com.android.server.wm;
 
-import static junit.framework.Assert.assertTrue;
+import static org.junit.Assert.assertTrue;
 
-import android.os.SystemClock;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index f1e2281..79e6851 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -842,7 +842,7 @@
                             && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST)
                             && status.isRoleCombinationSupported(POWER_ROLE_SOURCE,
                             DATA_ROLE_DEVICE)
-                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_HOST);
+                            && status.isRoleCombinationSupported(POWER_ROLE_SINK, DATA_ROLE_DEVICE);
 
                     args.recycle();
                     updateUsbNotification(false);
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/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 3d7cbb5..94352b2 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -889,7 +889,7 @@
         public void onCallStateChanged(int state, String arg1) {
             if (DBG) Slog.d(TAG, "onCallStateChanged: " + state);
             synchronized (mLock) {
-                onCallStateChangedLocked(TelephonyManager.CALL_STATE_IDLE != state);
+                onCallStateChangedLocked(TelephonyManager.CALL_STATE_OFFHOOK == state);
             }
         }
     }
@@ -924,7 +924,7 @@
         long token = Binder.clearCallingIdentity();
         try {
             // Get the current call state synchronously for the first recognition.
-            mCallActive = mTelephonyManager.getCallState() != TelephonyManager.CALL_STATE_IDLE;
+            mCallActive = mTelephonyManager.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK;
 
             // Register for call state changes when the first call to start recognition occurs.
             mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 07ffaac..dde8057 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -17,11 +17,13 @@
 package android.telephony;
 
 import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SuppressAutoDoc;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.ActivityThread;
 import android.app.PendingIntent;
@@ -50,6 +52,8 @@
 import com.android.internal.telephony.ISms;
 import com.android.internal.telephony.SmsRawData;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -2327,4 +2331,84 @@
         return filtered;
     }
 
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"SMS_CATEGORY_"},
+            value = {
+                    SmsManager.SMS_CATEGORY_NOT_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_FREE_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE,
+                    SmsManager.SMS_CATEGORY_PREMIUM_SHORT_CODE})
+    public @interface SmsShortCodeCategory {}
+
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for regular
+     * phone numbers.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_NOT_SHORT_CODE = 0;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for free
+     * (no cost) short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_FREE_SHORT_CODE = 1;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+     * standard rate (non-premium)
+     * short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_STANDARD_SHORT_CODE = 2;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for possible
+     * premium short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE = 3;
+    /**
+     * Return value from {@link #checkSmsShortCodeDestination(String, String)} ()} for
+     * premium short codes.
+     * @hide
+     */
+    @TestApi
+    public static final int SMS_CATEGORY_PREMIUM_SHORT_CODE = 4;
+
+    /**
+     * Check if the destination address is a possible premium short code.
+     * NOTE: the caller is expected to strip non-digits from the destination number with
+     * {@link PhoneNumberUtils#extractNetworkPortion} before calling this method.
+     *
+     * @param destAddress the destination address to test for possible short code
+     * @param countryIso the ISO country code
+     *
+     * @return
+     * {@link SmsManager#SMS_CATEGORY_NOT_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_FREE_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE},
+     * {@link SmsManager#SMS_CATEGORY_PREMIUM_SHORT_CODE}, or
+     * {@link SmsManager#SMS_CATEGORY_STANDARD_SHORT_CODE}
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
+    @TestApi
+    public @SmsShortCodeCategory int checkSmsShortCodeDestination(
+            String destAddress, String countryIso) {
+        try {
+            ISms iccISms = getISmsServiceOrThrow();
+            if (iccISms != null) {
+                return iccISms.checkSmsShortCodeDestination(getSubscriptionId(),
+                        ActivityThread.currentPackageName(), destAddress, countryIso);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "checkSmsShortCodeDestination() RemoteException", e);
+        }
+        return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE;
+    }
 }
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5df7bf7..ffd5b16 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1321,7 +1321,7 @@
 
     /**
      * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the
-     * subscription which has changed.
+     * subscription which has changed; or in general whenever a subscription ID needs specified.
      */
     public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID";
 
@@ -1439,13 +1439,24 @@
 
     /**
      * Integer intent extra to be used with {@link #ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED}
-     * to indicate whether a SIM selection is needed to choose default subscription.
+     * to indicate what type of SIM selection is needed.
      *
      * @hide
      */
     public static final String EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE =
             "android.telephony.extra.DEFAULT_SUBSCRIPTION_SELECT_TYPE";
 
+    /** @hide */
+    @IntDef({
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_VOICE,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_SMS,
+            EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DefaultSubscriptionSelectType{}
+
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate there's no need to re-select any default subscription.
@@ -1477,20 +1488,11 @@
     /**
      * Used as an int value for {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE}
      * to indicate user to decide whether current SIM should be preferred for all
-     * data / voice / sms.
+     * data / voice / sms. {@link #EXTRA_SUBSCRIPTION_ID} will specified to indicate
+     * which subscription should be the default subscription.
      * @hide
      */
-    public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES = 4;
-
-    /**
-     * Integer intent extra to be used with
-     * {@link #EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES}
-     * to indicate which SIM is being selected.
-     *
-     * @hide
-     */
-    public static final String EXTRA_DEFAULT_SUBSCRIPTION_ID =
-            "android.telephony.extra.DEFAULT_SUBSCRIPTION_ID";
+    public static final int EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL = 4;
 
     //
     //
@@ -7195,10 +7197,21 @@
      * @hide
      */
     public boolean getTetherApnRequired() {
+        return getTetherApnRequired(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
+    }
+
+    /**
+     * Check whether DUN APN is required for tethering with subId.
+     *
+     * @param subId the id of the subscription to require tethering.
+     * @return {@code true} if DUN APN is required for tethering.
+     * @hide
+     */
+    public boolean getTetherApnRequired(int subId) {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null)
-                return telephony.getTetherApnRequired();
+                return telephony.getTetherApnRequiredForSubscriber(subId);
         } catch (RemoteException ex) {
             Rlog.e(TAG, "hasMatchedTetherApnSetting RemoteException", ex);
         } catch (NullPointerException ex) {
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index b51eda3..c34feed 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -588,4 +588,11 @@
      */
     void getSmsMessagesForFinancialApp(
         int subId, String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
+
+    /**
+     * Check if the destination is a possible premium short code.
+     *
+     * @param destAddress the destination address to test for possible short code
+     */
+    int checkSmsShortCodeDestination(int subId, String callingApk, String destAddress, String countryIso);
 }
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 12c5c30..aa1f94f 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -202,4 +202,10 @@
             int subId, String callingPkg, Bundle params, IFinancialSmsCallback callback) {
         throw new UnsupportedOperationException();
     }
+
+    @Override
+    public int checkSmsShortCodeDestination(
+            int subid, String callingApk, String destAddress, String countryIso) {
+        throw new UnsupportedOperationException();
+    }
 }
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d98f8d8..9e2d9ee 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -788,12 +788,13 @@
     int getPreferredNetworkType(int subId);
 
     /**
-     * Check whether DUN APN is required for tethering.
+     * Check whether DUN APN is required for tethering with subId.
      *
+     * @param subId the id of the subscription to require tethering.
      * @return {@code true} if DUN APN is required for tethering.
      * @hide
      */
-    boolean getTetherApnRequired();
+    boolean getTetherApnRequiredForSubscriber(int subId);
 
     /**
     * Enables framework IMS and triggers IMS Registration.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 4886a3f..d93e582 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -123,6 +123,19 @@
                 context, TELEPHONY_SUPPLIER, subId, pid, uid, callingPackage, message);
     }
 
+    /**
+     * Check whether the calling packages has carrier privileges for the passing subscription.
+     * @return {@code true} if the caller has carrier privileges, {@false} otherwise.
+     */
+    public static boolean checkCarrierPrivilegeForSubId(int subId) {
+        if (SubscriptionManager.isValidSubscriptionId(subId)
+                && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, Binder.getCallingUid())
+                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+            return true;
+        }
+        return false;
+    }
+
     @VisibleForTesting
     public static boolean checkReadPhoneState(
             Context context, Supplier<ITelephony> telephonySupplier, int subId, int pid, int uid,
@@ -204,9 +217,7 @@
         }
         // Calling packages with carrier privileges will also have access to device identifiers, but
         // this may be removed in a future release.
-        if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
-                TELEPHONY_SUPPLIER, subId, uid)
-                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+        if (checkCarrierPrivilegeForSubId(subId)) {
             return true;
         }
         // else the calling package is not authorized to access the device identifiers; call
@@ -243,9 +254,7 @@
         }
         // If the calling package has carrier privileges then allow access to the subscriber
         // identifiers.
-        if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
-                TELEPHONY_SUPPLIER, subId, uid)
-                == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+        if (checkCarrierPrivilegeForSubId(subId)) {
             return true;
         }
         return reportAccessDeniedToReadIdentifiers(context, subId, pid, uid, callingPackage,
@@ -365,9 +374,7 @@
                         uid) == PackageManager.PERMISSION_GRANTED) {
                     return false;
                 }
-                if (SubscriptionManager.isValidSubscriptionId(subId)
-                        && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, uid)
-                        == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                if (checkCarrierPrivilegeForSubId(subId)) {
                     return false;
                 }
             }
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/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1151214..e881ad4 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -212,7 +212,6 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.Consumer;
 import java.util.function.Predicate;
 
 /**
@@ -4022,8 +4021,13 @@
         callback3.expectStopped();
     }
 
+    @FunctionalInterface
+    private interface ThrowingConsumer<T> {
+        void accept(T t) throws Exception;
+    }
+
     // Helper method to prepare the executor and run test
-    private void runTestWithSerialExecutors(Consumer<Executor> functor) {
+    private void runTestWithSerialExecutors(ThrowingConsumer<Executor> functor) throws Exception {
         final ExecutorService executorSingleThread = Executors.newSingleThreadExecutor();
         final Executor executorInline = (Runnable r) -> r.run();
         functor.accept(executorSingleThread);
@@ -4032,15 +4036,9 @@
     }
 
     @Test
-    public void testNattSocketKeepalives() {
-        runTestWithSerialExecutors(executor -> {
-            try {
-                doTestNattSocketKeepalivesWithExecutor(executor);
-                doTestNattSocketKeepalivesFdWithExecutor(executor);
-            } catch (Exception e) {
-                fail(e.getMessage());
-            }
-        });
+    public void testNattSocketKeepalives() throws Exception {
+        runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesWithExecutor(executor));
+        runTestWithSerialExecutors(executor -> doTestNattSocketKeepalivesFdWithExecutor(executor));
     }
 
     private void doTestNattSocketKeepalivesWithExecutor(Executor executor) throws Exception {
@@ -4210,14 +4208,8 @@
     }
 
     @Test
-    public void testTcpSocketKeepalives() {
-        runTestWithSerialExecutors(executor -> {
-            try {
-                doTestTcpSocketKeepalivesWithExecutor(executor);
-            } catch (Exception e) {
-                fail(e.getMessage());
-            }
-        });
+    public void testTcpSocketKeepalives() throws Exception {
+        runTestWithSerialExecutors(executor -> doTestTcpSocketKeepalivesWithExecutor(executor));
     }
 
     private void doTestTcpSocketKeepalivesWithExecutor(Executor executor) throws Exception {
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/FrameworksTestsFilter.java
similarity index 76%
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/FrameworksTestsFilter.java
index 1a81c2c..e0d74e0 100644
--- a/core/tests/coretests/src/com/android/server/wm/test/filters/CoreTestsFilter.java
+++ b/tests/utils/testutils/java/com/android/server/wm/test/filters/FrameworksTestsFilter.java
@@ -26,23 +26,25 @@
  * <p>Use this filter when running FrameworksCoreTests as
  * <pre>
  * adb shell am instrument -w \
- *     -e filter com.android.server.wm.test.filters.CoreTestsFilter  \
+ *     -e filter com.android.server.wm.test.filters.FrameworksTestsFilter  \
  *     -e selectTest_verbose true \
  *     com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner
  * </pre>
  */
-public final class CoreTestsFilter extends SelectTest {
+public final class FrameworksTestsFilter extends SelectTest {
 
-    private static final String[] SELECTED_CORE_TESTS = {
+    private static final String[] SELECTED_TESTS = {
+            // Test specifications for FrameworksCoreTests.
             "android.app.servertransaction.", // all tests under the package.
             "android.view.DisplayCutoutTest",
+            "android.view.InsetsAnimationControlImplTest",
             "android.view.InsetsControllerTest",
             "android.view.InsetsSourceTest",
             "android.view.InsetsSourceConsumerTest",
             "android.view.InsetsStateTest",
     };
 
-    public CoreTestsFilter(Bundle testArgs) {
-        super(addSelectTest(testArgs, SELECTED_CORE_TESTS));
+    public FrameworksTestsFilter(Bundle testArgs) {
+        super(addSelectTest(testArgs, SELECTED_TESTS));
     }
 }
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/tools/apilint/apilint.py b/tools/apilint/apilint.py
index f967c2f..97ca6dc 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -2147,6 +2147,8 @@
             del cur[prev_clazz.fullname]
 
     for clazz in cur.values():
+        if not is_interesting(clazz): continue
+
         if "deprecated" in clazz.split and not clazz.fullname in prev:
             error(clazz, None, None, "Found API deprecation at birth")
 
diff --git a/tools/bit/main.cpp b/tools/bit/main.cpp
index 0f555b1..1a91f52 100644
--- a/tools/bit/main.cpp
+++ b/tools/bit/main.cpp
@@ -856,7 +856,7 @@
             // TODO: if (!apk.file.fileInfo.exists || apk.file.HasChanged())
             err = run_adb("shell", "mkdir", "-p", dir.c_str(), NULL);
             check_error(err);
-            err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str());
+            err = run_adb("push", pushed.file.filename.c_str(), pushed.dest.c_str(), NULL);
             check_error(err);
             // pushed.installed = true;
         }
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",
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
index a9c9939..f576745 100644
--- a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -283,10 +283,10 @@
 
         /**
          * Specify the priority of this network among other network suggestions provided by the same
-         * app (priorities have no impact on suggestions by different apps). The lower the number,
-         * the higher the priority (i.e value of 0 = highest priority).
+         * app (priorities have no impact on suggestions by different apps). The higher the number,
+         * the higher the priority (i.e value of 0 = lowest priority).
          * <p>
-         * <li>If not set, defaults to -1 (i.e unassigned priority).</li>
+         * <li>If not set, defaults a lower priority than any assigned priority.</li>
          *
          * @param priority Integer number representing the priority among suggestions by the app.
          * @return Instance of {@link Builder} to enable chaining of the builder method.