Merge "Add /system_ext sepolicy support to SELinuxMMAC.java"
diff --git a/Android.bp b/Android.bp
index 7241417..7577353 100644
--- a/Android.bp
+++ b/Android.bp
@@ -894,8 +894,10 @@
 
 packages_to_document = [
     "android",
+    "dalvik",
     "java",
     "javax",
+    "junit",
     "org.apache.http",
     "org.json",
     "org.w3c.dom",
diff --git a/api/system-current.txt b/api/system-current.txt
index 8add646..8132c76 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5168,7 +5168,8 @@
     method @NonNull public static java.io.File getOdmDirectory();
     method @NonNull public static java.io.File getOemDirectory();
     method @NonNull public static java.io.File getProductDirectory();
-    method @NonNull public static java.io.File getProductServicesDirectory();
+    method @Deprecated @NonNull public static java.io.File getProductServicesDirectory();
+    method @NonNull public static java.io.File getSystemExtDirectory();
     method @NonNull public static java.io.File getVendorDirectory();
   }
 
@@ -8108,7 +8109,7 @@
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean disableDataConnectivity();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableDataConnectivity();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean enableModemForSlot(int, boolean);
-    method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
+    method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void enableVideoCalling(boolean);
     method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getAidForAppType(int);
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int);
     method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent);
@@ -8155,7 +8156,7 @@
     method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isPotentialEmergencyNumber(@NonNull String);
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRadioOn();
     method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isRinging();
-    method @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
+    method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE}) public boolean isVideoCallingEnabled();
     method @Deprecated @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) public boolean isVisualVoicemailEnabled(android.telecom.PhoneAccountHandle);
     method public boolean needsOtaServiceProvisioning();
     method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean rebootRadio();
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index d4d5871..4c77ba4 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -69,6 +69,7 @@
             static_libs: [
                 "libandroidfw",
                 "libbase",
+                "libcutils",
                 "libutils",
                 "libziparchive",
             ],
@@ -121,6 +122,7 @@
             static_libs: [
                 "libandroidfw",
                 "libbase",
+                "libcutils",
                 "libidmap2",
                 "liblog",
                 "libutils",
@@ -163,6 +165,7 @@
             static_libs: [
                 "libandroidfw",
                 "libbase",
+                "libcutils",
                 "libidmap2",
                 "liblog",
                 "libutils",
diff --git a/cmds/idmap2/idmap2/Scan.cpp b/cmds/idmap2/idmap2/Scan.cpp
index cfac5f3..0b349e1 100644
--- a/cmds/idmap2/idmap2/Scan.cpp
+++ b/cmds/idmap2/idmap2/Scan.cpp
@@ -103,6 +103,7 @@
       {"/oem/", kPolicyOem},
       {"/product/", kPolicyProduct},
       {"/system/", kPolicySystem},
+      {"/system_ext/", kPolicySystem},
       {"/vendor/", kPolicyVendor},
   };
 
diff --git a/cmds/incident/main.cpp b/cmds/incident/main.cpp
index dfb4f99..6c3d197 100644
--- a/cmds/incident/main.cpp
+++ b/cmds/incident/main.cpp
@@ -198,6 +198,26 @@
 }
 
 // ================================================================================
+static int
+stream_output(const int read_fd, const int write_fd) {
+    while (true) {
+        uint8_t buf[4096];
+        ssize_t amt = TEMP_FAILURE_RETRY(read(read_fd, buf, sizeof(buf)));
+        if (amt < 0) {
+            break;
+        } else if (amt == 0) {
+            break;
+        }
+
+        ssize_t wamt = TEMP_FAILURE_RETRY(write(write_fd, buf, amt));
+        if (wamt != amt) {
+            return errno;
+        }
+    }
+    return 0;
+}
+
+// ================================================================================
 static void
 usage(FILE* out)
 {
@@ -208,11 +228,13 @@
     fprintf(out, "OPTIONS\n");
     fprintf(out, "  -l           list available sections\n");
     fprintf(out, "  -p           privacy spec, LOCAL, EXPLICIT or AUTOMATIC. Default AUTOMATIC.\n");
+    fprintf(out, "  -r REASON    human readable description of why the report is taken.\n");
     fprintf(out, "\n");
     fprintf(out, "and one of these destinations:\n");
     fprintf(out, "  -b           (default) print the report to stdout (in proto format)\n");
     fprintf(out, "  -d           send the report into dropbox\n");
-    fprintf(out, "  -r REASON    human readable description of why the report is taken.\n");
+    fprintf(out, "  -u           print a full report to stdout for dumpstate to zip as a bug\n");
+    fprintf(out, "               report. SECTION is ignored. Should only be called by dumpstate.\n");
     fprintf(out, "  -s PKG/CLS   send broadcast to the broadcast receiver.\n");
     fprintf(out, "\n");
     fprintf(out, "  SECTION     the field numbers of the incident report fields to include\n");
@@ -224,14 +246,14 @@
 {
     Status status;
     IncidentReportArgs args;
-    enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST } destination = DEST_UNSET;
+    enum { DEST_UNSET, DEST_DROPBOX, DEST_STDOUT, DEST_BROADCAST, DEST_DUMPSTATE } destination = DEST_UNSET;
     int privacyPolicy = PRIVACY_POLICY_AUTOMATIC;
     string reason;
     string receiverArg;
 
     // Parse the args
     int opt;
-    while ((opt = getopt(argc, argv, "bhdlp:r:s:")) != -1) {
+    while ((opt = getopt(argc, argv, "bhdlp:r:s:u")) != -1) {
         switch (opt) {
             case 'h':
                 usage(stdout);
@@ -253,6 +275,13 @@
                 }
                 destination = DEST_DROPBOX;
                 break;
+            case 'u':
+                if (!(destination == DEST_UNSET || destination == DEST_DUMPSTATE)) {
+                    usage(stderr);
+                    return 1;
+                }
+                destination = DEST_DUMPSTATE;
+                break;
             case 'p':
                 privacyPolicy = get_privacy_policy(optarg);
                 break;
@@ -355,21 +384,16 @@
 
         // Wait for the result and print out the data they send.
         //IPCThreadState::self()->joinThreadPool();
-
-        while (true) {
-            uint8_t buf[4096];
-            ssize_t amt = TEMP_FAILURE_RETRY(read(fds[0], buf, sizeof(buf)));
-            if (amt < 0) {
-                break;
-            } else if (amt == 0) {
-                break;
-            }
-
-            ssize_t wamt = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buf, amt));
-            if (wamt != amt) {
-                return errno;
-            }
+        return stream_output(fds[0], STDOUT_FILENO);
+    } else if (destination == DEST_DUMPSTATE) {
+        // Call into the service
+        sp<StatusListener> listener(new StatusListener());
+        status = service->reportIncidentToDumpstate(writeEnd, listener);
+        if (!status.isOk()) {
+            fprintf(stderr, "reportIncident returned \"%s\"\n", status.toString8().string());
+            return 1;
         }
+        return stream_output(fds[0], STDOUT_FILENO);
     } else {
         status = service->reportIncident(args);
         if (!status.isOk()) {
diff --git a/cmds/incidentd/src/IncidentService.cpp b/cmds/incidentd/src/IncidentService.cpp
index a527263..999936b 100644
--- a/cmds/incidentd/src/IncidentService.cpp
+++ b/cmds/incidentd/src/IncidentService.cpp
@@ -46,12 +46,11 @@
 #define DEFAULT_BYTES_SIZE_LIMIT (96 * 1024 * 1024)        // 96MB
 #define DEFAULT_REFACTORY_PERIOD_MS (24 * 60 * 60 * 1000)  // 1 Day
 
-// Skip these sections for dumpstate only. Dumpstate allows 10s max for each service to dump.
+// Skip these sections (for dumpstate only)
 // Skip logs (1100 - 1108) and traces (1200 - 1202) because they are already in the bug report.
-// Skip 3018 because it takes too long.
-#define SKIPPED_SECTIONS { 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
-                           1200, 1201, 1202, /* Native, hal, java traces */ \
-                           3018  /* "meminfo -a --proto" */ }
+#define SKIPPED_DUMPSTATE_SECTIONS { \
+            1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, /* Logs */ \
+            1200, 1201, 1202, /* Native, hal, java traces */ }
 
 namespace android {
 namespace os {
@@ -307,6 +306,39 @@
     return Status::ok();
 }
 
+Status IncidentService::reportIncidentToDumpstate(const unique_fd& stream,
+        const sp<IIncidentReportStatusListener>& listener) {
+    uid_t caller = IPCThreadState::self()->getCallingUid();
+    if (caller != AID_ROOT && caller != AID_SHELL) {
+        ALOGW("Calling uid %d does not have permission: only ROOT or SHELL allowed", caller);
+        return Status::fromExceptionCode(Status::EX_SECURITY, "Only ROOT or SHELL allowed");
+    }
+
+    ALOGD("Stream incident report to dumpstate");
+    IncidentReportArgs incidentArgs;
+    // Privacy policy for dumpstate incident reports is always EXPLICIT.
+    incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
+
+    int skipped[] = SKIPPED_DUMPSTATE_SECTIONS;
+    for (const Section** section = SECTION_LIST; *section; section++) {
+        const int id = (*section)->id;
+        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
+                && !section_requires_specific_mention(id)) {
+            incidentArgs.addSection(id);
+        }
+    }
+
+    // The ReportRequest takes ownership of the fd, so we need to dup it.
+    int fd = dup(stream.get());
+    if (fd < 0) {
+        return Status::fromStatusT(-errno);
+    }
+
+    mHandler->scheduleStreamingReport(incidentArgs, listener, fd);
+
+    return Status::ok();
+}
+
 Status IncidentService::systemRunning() {
     if (IPCThreadState::self()->getCallingUid() != AID_SYSTEM) {
         return Status::fromExceptionCode(Status::EX_SECURITY,
@@ -551,43 +583,6 @@
     return NO_ERROR;
 }
 
-status_t IncidentService::dump(int fd, const Vector<String16>& args) {
-    if (std::find(args.begin(), args.end(), String16("--proto")) == args.end()) {
-        ALOGD("Skip dumping incident. Only proto format is supported.");
-        dprintf(fd, "Incident dump only supports proto version.\n");
-        return NO_ERROR;
-    }
-
-    ALOGD("Dump incident proto");
-    IncidentReportArgs incidentArgs;
-    incidentArgs.setPrivacyPolicy(PRIVACY_POLICY_EXPLICIT);
-    int skipped[] = SKIPPED_SECTIONS;
-    for (const Section** section = SECTION_LIST; *section; section++) {
-        const int id = (*section)->id;
-        if (std::find(std::begin(skipped), std::end(skipped), id) == std::end(skipped)
-                && !section_requires_specific_mention(id)) {
-            incidentArgs.addSection(id);
-        }
-    }
-
-    if (!checkIncidentPermissions(incidentArgs).isOk()) {
-        return PERMISSION_DENIED;
-    }
-
-    // The ReportRequest takes ownership of the fd, so we need to dup it.
-    int fd1 = dup(fd);
-    if (fd1 < 0) {
-        return -errno;
-    }
-
-    // TODO: Remove this.  Someone even dumpstate, wanting to get an incident report
-    // should use the API.  That will take making dumpstated call the API, which is a
-    // good thing.  It also means it won't be subject to the timeout.
-    mHandler->scheduleStreamingReport(incidentArgs, NULL, fd1);
-
-    return NO_ERROR;
-}
-
 }  // namespace incidentd
 }  // namespace os
 }  // namespace android
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index 6481321..fb013d0 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -123,6 +123,9 @@
                                           const sp<IIncidentReportStatusListener>& listener,
                                           const unique_fd& stream);
 
+    virtual Status reportIncidentToDumpstate(const unique_fd& stream,
+            const sp<IIncidentReportStatusListener>& listener);
+
     virtual Status systemRunning();
 
     virtual Status getIncidentReportList(const String16& pkg, const String16& cls,
@@ -140,7 +143,6 @@
     virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                 uint32_t flags) override;
     virtual status_t command(FILE* in, FILE* out, FILE* err, Vector<String8>& args);
-    virtual status_t dump(int fd, const Vector<String16>& args);
 
 private:
     sp<WorkDirectory> mWorkDirectory;
diff --git a/cmds/incidentd/src/main.cpp b/cmds/incidentd/src/main.cpp
index 098d74e..4948823 100644
--- a/cmds/incidentd/src/main.cpp
+++ b/cmds/incidentd/src/main.cpp
@@ -45,8 +45,7 @@
 
     // Create the service
     sp<IncidentService> service = new IncidentService(looper);
-    if (defaultServiceManager()->addService(String16("incident"), service, false,
-            IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO) != 0) {
+    if (defaultServiceManager()->addService(String16("incident"), service) != 0) {
         ALOGE("Failed to add service");
         return -1;
     }
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
index 08c97eb..19d158d 100644
--- a/core/java/android/app/AppCompatCallbacks.java
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -18,7 +18,6 @@
 
 import android.compat.Compatibility;
 import android.os.Process;
-import android.util.Log;
 import android.util.StatsLog;
 
 import com.android.internal.compat.ChangeReporter;
@@ -31,8 +30,6 @@
  * @hide
  */
 public final class AppCompatCallbacks extends Compatibility.Callbacks {
-    private static final String TAG = "Compatibility";
-
     private final long[] mDisabledChanges;
     private final ChangeReporter mChangeReporter;
 
@@ -48,7 +45,8 @@
     private AppCompatCallbacks(long[] disabledChanges) {
         mDisabledChanges = Arrays.copyOf(disabledChanges, disabledChanges.length);
         Arrays.sort(mDisabledChanges);
-        mChangeReporter = new ChangeReporter();
+        mChangeReporter = new ChangeReporter(
+                StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__APP_PROCESS);
     }
 
     protected void reportChange(long changeId) {
@@ -67,10 +65,7 @@
 
     private void reportChange(long changeId, int state) {
         int uid = Process.myUid();
-        //TODO(b/138374585): Implement rate limiting for the logs.
-        Log.d(TAG, ChangeReporter.createLogString(uid, changeId, state));
-        mChangeReporter.reportChange(uid, changeId,
-                state, /* source */StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__APP_PROCESS);
+        mChangeReporter.reportChange(uid, changeId, state);
     }
 
 }
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9bc5f80..d6b70e0 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -614,10 +614,10 @@
 
     /**
      * Value for {@link #privateFlags}: whether this app is pre-installed on the
-     * google partition of the system image.
+     * system_ext partition of the system image.
      * @hide
      */
-    public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;
+    public static final int PRIVATE_FLAG_SYSTEM_EXT = 1 << 21;
 
     /**
      * Indicates whether this package requires access to non-SDK APIs.
@@ -713,7 +713,7 @@
             PRIVATE_FLAG_USE_EMBEDDED_DEX,
             PRIVATE_FLAG_PRIVILEGED,
             PRIVATE_FLAG_PRODUCT,
-            PRIVATE_FLAG_PRODUCT_SERVICES,
+            PRIVATE_FLAG_SYSTEM_EXT,
             PRIVATE_FLAG_PROFILEABLE_BY_SHELL,
             PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
             PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
@@ -2047,8 +2047,8 @@
     }
 
     /** @hide */
-    public boolean isProductServices() {
-        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     /** @hide */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 643cb3e..f15b5d7 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6897,8 +6897,8 @@
         }
 
         /** @hide */
-        public boolean isProductServices() {
-            return applicationInfo.isProductServices();
+        public boolean isSystemExt() {
+            return applicationInfo.isSystemExt();
         }
 
         /** @hide */
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index a809b28..2cf2a65 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -85,6 +85,9 @@
     private static final long OUI_MASK = MacAddress.fromString("ff:ff:ff:0:0:0").mAddr;
     private static final long NIC_MASK = MacAddress.fromString("0:0:0:ff:ff:ff").mAddr;
     private static final MacAddress BASE_GOOGLE_MAC = MacAddress.fromString("da:a1:19:0:0:0");
+    /** Default wifi MAC address used for a special purpose **/
+    private static final MacAddress DEFAULT_MAC_ADDRESS =
+            MacAddress.fromString(WifiInfo.DEFAULT_MAC_ADDRESS);
 
     // Internal representation of the MAC address as a single 8 byte long.
     // The encoding scheme sets the two most significant bytes to 0. The 6 bytes of the
@@ -361,16 +364,7 @@
      * @hide
      */
     public static @NonNull MacAddress createRandomUnicastAddress() {
-        SecureRandom r = new SecureRandom();
-        long addr = r.nextLong() & VALID_LONG_MASK;
-        addr |= LOCALLY_ASSIGNED_MASK;
-        addr &= ~MULTICAST_MASK;
-        MacAddress mac = new MacAddress(addr);
-        // WifiInfo.DEFAULT_MAC_ADDRESS is being used for another purpose, so do not use it here.
-        if (mac.toString().equals(WifiInfo.DEFAULT_MAC_ADDRESS)) {
-            return createRandomUnicastAddress();
-        }
-        return mac;
+        return createRandomUnicastAddress(null, new SecureRandom());
     }
 
     /**
@@ -380,18 +374,23 @@
      * The locally assigned bit is always set to 1. The multicast bit is always set to 0.
      *
      * @param base a base MacAddress whose OUI is used for generating the random address.
+     *             If base == null then the OUI will also be randomized.
      * @param r a standard Java Random object used for generating the random address.
      * @return a random locally assigned MacAddress.
      *
      * @hide
      */
     public static @NonNull MacAddress createRandomUnicastAddress(MacAddress base, Random r) {
-        long addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong());
+        long addr;
+        if (base == null) {
+            addr = r.nextLong() & VALID_LONG_MASK;
+        } else {
+            addr = (base.mAddr & OUI_MASK) | (NIC_MASK & r.nextLong());
+        }
         addr |= LOCALLY_ASSIGNED_MASK;
         addr &= ~MULTICAST_MASK;
         MacAddress mac = new MacAddress(addr);
-        // WifiInfo.DEFAULT_MAC_ADDRESS is being used for another purpose, so do not use it here.
-        if (mac.toString().equals(WifiInfo.DEFAULT_MAC_ADDRESS)) {
+        if (mac.equals(DEFAULT_MAC_ADDRESS)) {
             return createRandomUnicastAddress(base, r);
         }
         return mac;
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 51896aa..f5426cd 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1186,7 +1186,7 @@
         ArrayList<Partition> partitions = new ArrayList();
 
         String[] names = new String[] {
-            "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+            "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
             "vendor"
         };
         for (String name : names) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0ee9a11..3462d1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -54,7 +54,7 @@
     private static final String ENV_ODM_ROOT = "ODM_ROOT";
     private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
     private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
-    private static final String ENV_PRODUCT_SERVICES_ROOT = "PRODUCT_SERVICES_ROOT";
+    private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
 
     /** {@hide} */
     public static final String DIR_ANDROID = "Android";
@@ -77,8 +77,8 @@
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
     private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
-    private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
-                                                           "/product_services");
+    private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
+                                                           "/system_ext");
 
     @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
@@ -222,11 +222,26 @@
      * Return root directory of the "product_services" partition holding middleware
      * services if any. If present, the partition is mounted read-only.
      *
+     * @deprecated This directory is not guaranteed to exist.
+     *             Its name is changed to "system_ext" because the partition's purpose is changed.
+     *             {@link #getSystemExtDirectory()}
      * @hide
      */
     @SystemApi
+    @Deprecated
     public static @NonNull File getProductServicesDirectory() {
-        return DIR_PRODUCT_SERVICES_ROOT;
+        return getDirectory("PRODUCT_SERVICES_ROOT", "/product_services");
+    }
+
+    /**
+     * Return root directory of the "system_ext" partition holding system partition's extension
+     * If present, the partition is mounted read-only.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static @NonNull File getSystemExtDirectory() {
+        return DIR_SYSTEM_EXT_ROOT;
     }
 
     /**
diff --git a/core/java/android/os/IIncidentManager.aidl b/core/java/android/os/IIncidentManager.aidl
index 5e024b9..7e1b1e0 100644
--- a/core/java/android/os/IIncidentManager.aidl
+++ b/core/java/android/os/IIncidentManager.aidl
@@ -43,6 +43,15 @@
             FileDescriptor stream);
 
     /**
+     * Takes a report with the given args, reporting status to the optional listener.
+     * This should only be callable by dumpstate (enforced by callee).
+     *
+     * When the report is completed, the system report listener will be notified.
+     */
+    oneway void reportIncidentToDumpstate(FileDescriptor stream,
+            @nullable IIncidentReportStatusListener listener);
+
+    /**
      * Tell the incident daemon that the android system server is up and running.
      */
     oneway void systemRunning();
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 7bf1c4b..a6e5972 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -39,6 +39,13 @@
  * Gives access to the system properties store.  The system properties
  * store contains a list of string key-value pairs.
  *
+ * <p>Use this class only for the system properties that are local. e.g., within
+ * an app, a partition, or a module. For system properties used across the
+ * boundaries, formally define them in <code>*.sysprop</code> files and use the
+ * auto-generated methods. For more information, see <a href=
+ * "https://source.android.com/devices/architecture/sysprops-apis">Implementing
+ * System Properties as APIs</a>.</p>
+ *
  * {@hide}
  */
 @SystemApi
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index 1ce071b..8283eb7 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -16,14 +16,88 @@
 
 package com.android.internal.compat;
 
+import android.util.Log;
+import android.util.Slog;
 import android.util.StatsLog;
 
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
 /**
  * A helper class to report changes to stats log.
  *
  * @hide
  */
 public final class ChangeReporter {
+    private static final String TAG = "CompatibilityChangeReporter";
+    private int mSource;
+
+    private final class ChangeReport {
+        int mUid;
+        long mChangeId;
+        int mState;
+
+        ChangeReport(int uid, long changeId, int state) {
+            mUid = uid;
+            mChangeId = changeId;
+            mState = state;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+            ChangeReport that = (ChangeReport) o;
+            return mUid == that.mUid
+                    && mChangeId == that.mChangeId
+                    && mState == that.mState;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mUid, mChangeId, mState);
+        }
+    }
+
+    @GuardedBy("mReportedChanges")
+    private Set<ChangeReport> mReportedChanges =  new HashSet<>();
+
+    public ChangeReporter(int source) {
+        mSource = source;
+    }
+
+    /**
+     * Report the change to stats log.
+     *
+     * @param uid      affected by the change
+     * @param changeId the reported change id
+     * @param state    of the reported change - enabled/disabled/only logged
+     */
+    public void reportChange(int uid, long changeId, int state) {
+        ChangeReport report = new ChangeReport(uid, changeId, state);
+        synchronized (mReportedChanges) {
+            if (!mReportedChanges.contains(report)) {
+                debugLog(uid, changeId, state);
+                StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
+                        state, mSource);
+                mReportedChanges.add(report);
+            }
+        }
+    }
+
+    private void debugLog(int uid, long changeId, int state) {
+        String message = String.format("Compat change id reported: %d; UID %d; state: %s", changeId,
+                uid, stateToString(state));
+        if (mSource == StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER) {
+            Slog.d(TAG, message);
+        } else {
+            Log.d(TAG, message);
+        }
+
+    }
 
     /**
      * Transforms StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE enum to a string.
@@ -43,31 +117,4 @@
                 return "UNKNOWN";
         }
     }
-
-    /**
-     * Constructs and returns a string to be logged to logcat when a change is reported.
-     *
-     * @param uid      affected by the change
-     * @param changeId the reported change id
-     * @param state    of the reported change - enabled/disabled/only logged
-     * @return string to log
-     */
-    public static String createLogString(int uid, long changeId, int state) {
-        return String.format("Compat change id reported: %d; UID %d; state: %s", changeId, uid,
-                stateToString(state));
-    }
-
-    /**
-     * Report the change to stats log.
-     *
-     * @param uid      affected by the change
-     * @param changeId the reported change id
-     * @param state    of the reported change - enabled/disabled/only logged
-     * @param source   of the logging - app process or system server
-     */
-    public void reportChange(int uid, long changeId, int state, int source) {
-        //TODO(b/138374585): Implement rate limiting for stats log.
-        StatsLog.write(StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED, uid, changeId,
-                state, source);
-    }
 }
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index 9049c3a..e415b41 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -33,15 +33,30 @@
      * Reports that a compatibility change is affecting an app process now.
      *
      * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)},
-     * you do not need to call this API directly. The change will be reported for you in the case
-     * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}.
+     * you do not need to call this API directly. The change will be reported for you.
      *
      * @param changeId The ID of the compatibility change taking effect.
-     * @param appInfo Representing the affected app.
+     * @param appInfo  Representing the affected app.
      */
     void reportChange(long changeId, in ApplicationInfo appInfo);
 
     /**
+     * Reports that a compatibility change is affecting an app process now.
+     *
+     * <p>Same as {@link #reportChange(long, ApplicationInfo)}, except it receives a package name
+     * instead of an {@link ApplicationInfo}
+     * object, and finds an app info object based on the package name. Returns {@code true} if
+     * there is no installed package by that name.
+     *
+     * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, String)},
+     * you do not need to call this API directly. The change will be reported for you.
+     *
+     * @param changeId    The ID of the compatibility change taking effect.
+     * @param packageName The package name of the app in question.
+     */
+     void reportChangeByPackageName(long changeId, in String packageName);
+
+    /**
      * Query if a given compatibility change is enabled for an app process. This method should
      * be called when implementing functionality on behalf of the affected app.
      *
@@ -49,13 +64,35 @@
      * change, resulting in differing behaviour compared to earlier releases. If this method returns
      * {@code false}, the calling code should behave as it did in earlier releases.
      *
-     * <p>When this method returns {@code true}, it will also report the change as
-     * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method
-     * directly.
+     * <p>It will also report the change as {@link #reportChange(long, ApplicationInfo)} would, so
+     * there is no need to call that method directly.
      *
      * @param changeId The ID of the compatibility change in question.
-     * @param appInfo Representing the app in question.
+     * @param appInfo  Representing the app in question.
      * @return {@code true} if the change is enabled for the current app.
      */
     boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo);
+
+    /**
+     * Query if a given compatibility change is enabled for an app process. This method should
+     * be called when implementing functionality on behalf of the affected app.
+     *
+     * <p>Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a package name
+     * instead of an {@link ApplicationInfo}
+     * object, and finds an app info object based on the package name. Returns {@code true} if
+     * there is no installed package by that name.
+     *
+     * <p>If this method returns {@code true}, the calling code should implement the compatibility
+     * change, resulting in differing behaviour compared to earlier releases. If this method
+     * returns
+     * {@code false}, the calling code should behave as it did in earlier releases.
+     *
+     * <p>It will also report the change as {@link #reportChange(long, String)} would, so there is
+     * no need to call that method directly.
+     *
+     * @param changeId    The ID of the compatibility change in question.
+     * @param packageName The package name of the app in question.
+     * @return {@code true} if the change is enabled for the current app.
+     */
+    boolean isChangeEnabledByPackageName(long changeId, in String packageName);
 }
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 1de2e72..d6caa09 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -192,6 +192,15 @@
         }
     }
 
+    /**
+     * Common initialization that (unlike {@link #commonInit()} should happen prior to
+     * the Zygote fork.
+     */
+    public static void preForkInit() {
+        if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
+        RuntimeInit.enableDdms();
+    }
+
     @UnsupportedAppUsage
     protected static final void commonInit() {
         if (DEBUG) Slog.d(TAG, "Entered RuntimeInit!");
@@ -324,7 +333,7 @@
 
     @UnsupportedAppUsage
     public static final void main(String[] argv) {
-        enableDdms();
+        preForkInit();
         if (argv.length == 2 && argv[1].equals("application")) {
             if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application");
             redirectLogStreams();
@@ -418,7 +427,7 @@
     /**
      * Enable DDMS.
      */
-    static final void enableDdms() {
+    private static void enableDdms() {
         // Register handlers for DDM messages.
         android.ddm.DdmRegister.registerHandlers();
     }
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index ea4b63a..72d2464 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -835,7 +835,7 @@
             TimingsTraceLog bootTimingsTraceLog = new TimingsTraceLog(bootTimeTag,
                     Trace.TRACE_TAG_DALVIK);
             bootTimingsTraceLog.traceBegin("ZygoteInit");
-            RuntimeInit.enableDdms();
+            RuntimeInit.preForkInit();
 
             boolean startSystemServer = false;
             String zygoteSocketName = "zygote";
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..364278d 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -194,9 +194,8 @@
     final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
     final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
 
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppPermissions = new ArrayMap<>();
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppDenyPermissions =
-            new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
 
     final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
 
@@ -321,12 +320,20 @@
         return mProductPrivAppDenyPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
-        return mProductServicesPrivAppPermissions.get(packageName);
+    /**
+     * Read from "permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly granted.
+     */
+    public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
+        return mSystemExtPrivAppPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
-        return mProductServicesPrivAppDenyPermissions.get(packageName);
+    /**
+     * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly denied.
+     */
+    public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
+        return mSystemExtPrivAppDenyPermissions.get(packageName);
     }
 
     public Map<String, Boolean> getOemPermissions(String packageName) {
@@ -398,11 +405,11 @@
         readPermissions(Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
 
-        // Allow /product_services to customize all system configs
+        // Allow /system_ext to customize all system configs
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
     }
 
     void readPermissions(File libraryDir, int permissionFlag) {
@@ -848,7 +855,7 @@
                     } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
-                            // privapp permissions from system, vendor, product and product_services
+                            // privapp permissions from system, vendor, product and system_ext
                             // partitions are stored separately. This is to prevent xml files in
                             // the vendor partition from granting permissions to priv apps in the
                             // system partition and vice versa.
@@ -858,17 +865,17 @@
                                     Environment.getOdmDirectory().toPath() + "/");
                             boolean product = permFile.toPath().startsWith(
                                     Environment.getProductDirectory().toPath() + "/");
-                            boolean productServices = permFile.toPath().startsWith(
-                                    Environment.getProductServicesDirectory().toPath() + "/");
+                            boolean systemExt = permFile.toPath().startsWith(
+                                    Environment.getSystemExtDirectory().toPath() + "/");
                             if (vendor) {
                                 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                         mVendorPrivAppDenyPermissions);
                             } else if (product) {
                                 readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                         mProductPrivAppDenyPermissions);
-                            } else if (productServices) {
-                                readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
-                                        mProductServicesPrivAppDenyPermissions);
+                            } else if (systemExt) {
+                                readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
+                                        mSystemExtPrivAppDenyPermissions);
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 7df621d..571c2cb 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -696,26 +696,32 @@
     // Read if we are using the profile configuration, do this at the start since the last ART args
     // take precedence.
     property_get("dalvik.vm.profilebootclasspath", propBuf, "");
-    std::string profile_boot_class_path = propBuf;
+    std::string profile_boot_class_path_flag = propBuf;
     // Empty means the property is unset and we should default to the phenotype property.
     // The possible values are {"true", "false", ""}
-    if (profile_boot_class_path.empty()) {
-        profile_boot_class_path = server_configurable_flags::GetServerConfigurableFlag(
+    if (profile_boot_class_path_flag.empty()) {
+        profile_boot_class_path_flag = server_configurable_flags::GetServerConfigurableFlag(
                 RUNTIME_NATIVE_BOOT_NAMESPACE,
                 PROFILE_BOOT_CLASS_PATH,
                 /*default_value=*/ "");
     }
-    if (profile_boot_class_path == "true") {
+    const bool profile_boot_class_path = (profile_boot_class_path_flag == "true");
+    if (profile_boot_class_path) {
+        addOption("-Xcompiler-option");
+        addOption("--count-hotness-in-compiled-code");
         addOption("-Xps-profile-boot-class-path");
         addOption("-Xps-profile-aot-code");
         addOption("-Xjitsaveprofilinginfo");
     }
 
-    std::string use_apex_image =
+    std::string use_apex_image_flag =
         server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
                                                              ENABLE_APEX_IMAGE,
                                                              /*default_value=*/ "");
-    if (use_apex_image == "true") {
+    // Use the APEX boot image for boot class path profiling to get JIT samples on BCP methods.
+    // Also use the APEX boot image if it's explicitly enabled via configuration flag.
+    const bool use_apex_image = profile_boot_class_path || (use_apex_image_flag == "true");
+    if (use_apex_image) {
         addOption(kApexImageOption);
         ALOGI("Using Apex boot image: '%s'\n", kApexImageOption);
     } else if (parseRuntimeOption("dalvik.vm.boot-image", bootImageBuf, "-Ximage:")) {
@@ -1163,9 +1169,15 @@
         setenv("ANDROID_ROOT", rootDir, 1);
     }
 
-    const char* runtimeRootDir = getenv("ANDROID_RUNTIME_ROOT");
-    if (runtimeRootDir == NULL) {
-        LOG_FATAL("No runtime directory specified with ANDROID_RUNTIME_ROOT environment variable.");
+    const char* artRootDir = getenv("ANDROID_ART_ROOT");
+    if (artRootDir == NULL) {
+        LOG_FATAL("No ART directory specified with ANDROID_ART_ROOT environment variable.");
+        return;
+    }
+
+    const char* i18nRootDir = getenv("ANDROID_I18N_ROOT");
+    if (i18nRootDir == NULL) {
+        LOG_FATAL("No runtime directory specified with ANDROID_I18N_ROOT environment variable.");
         return;
     }
 
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index f6385cb..7c6a25b 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -257,6 +257,8 @@
             which_heap = HEAP_NATIVE;
         } else if (base::StartsWith(name, "[anon:libc_malloc]")) {
             which_heap = HEAP_NATIVE;
+        } else if (base::StartsWith(name, "[anon:scudo:")) {
+            which_heap = HEAP_NATIVE;
         } else if (base::StartsWith(name, "[stack")) {
             which_heap = HEAP_STACK;
         } else if (base::StartsWith(name, "[anon:stack_and_tls:")) {
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 2b471fe..9342088 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -163,7 +163,7 @@
       }
 
       // Generic idmap parameters
-      const char* argv[10];
+      const char* argv[11];
       int argc = 0;
       struct stat st;
 
@@ -195,8 +195,8 @@
         argv[argc++] = AssetManager::PRODUCT_OVERLAY_DIR;
       }
 
-      if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-        argv[argc++] = AssetManager::PRODUCT_SERVICES_OVERLAY_DIR;
+      if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+        argv[argc++] = AssetManager::SYSTEM_EXT_OVERLAY_DIR;
       }
 
       if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
@@ -237,8 +237,8 @@
     input_dirs.push_back(AssetManager::PRODUCT_OVERLAY_DIR);
   }
 
-  if (stat(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR, &st) == 0) {
-    input_dirs.push_back(AssetManager::PRODUCT_SERVICES_OVERLAY_DIR);
+  if (stat(AssetManager::SYSTEM_EXT_OVERLAY_DIR, &st) == 0) {
+    input_dirs.push_back(AssetManager::SYSTEM_EXT_OVERLAY_DIR);
   }
 
   if (stat(AssetManager::ODM_OVERLAY_DIR, &st) == 0) {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index f7318b6..1a81e3d 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -74,7 +74,6 @@
 #include <android-base/strings.h>
 #include <android-base/unique_fd.h>
 #include <bionic/malloc.h>
-#include <cutils/ashmem.h>
 #include <cutils/fs.h>
 #include <cutils/multiuser.h>
 #include <private/android_filesystem_config.h>
@@ -1590,11 +1589,6 @@
   if (!SetTaskProfiles(0, {})) {
     ZygoteFailure(env, "zygote", nullptr, "Zygote SetTaskProfiles failed");
   }
-
-  /*
-   * ashmem initialization to avoid dlopen overhead
-   */
-  ashmem_init();
 }
 
 /**
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 18448d2..bb57805 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -100,8 +100,8 @@
   static const char* kVendorOverlaySubdir = "/system/vendor/overlay-subdir/";
   static const char* kSystemProductOverlayDir = "/system/product/overlay/";
   static const char* kProductOverlayDir = "/product/overlay";
-  static const char* kSystemProductServicesOverlayDir = "/system/product_services/overlay/";
-  static const char* kProductServicesOverlayDir = "/product_services/overlay";
+  static const char* kSystemSystemExtOverlayDir = "/system/system_ext/overlay/";
+  static const char* kSystemExtOverlayDir = "/system_ext/overlay";
   static const char* kSystemOdmOverlayDir = "/system/odm/overlay";
   static const char* kOdmOverlayDir = "/odm/overlay";
   static const char* kSystemOemOverlayDir = "/system/oem/overlay";
@@ -113,8 +113,8 @@
        || android::base::StartsWith(path, kVendorOverlayDir)
        || android::base::StartsWith(path, kSystemProductOverlayDir)
        || android::base::StartsWith(path, kProductOverlayDir)
-       || android::base::StartsWith(path, kSystemProductServicesOverlayDir)
-       || android::base::StartsWith(path, kProductServicesOverlayDir)
+       || android::base::StartsWith(path, kSystemSystemExtOverlayDir)
+       || android::base::StartsWith(path, kSystemExtOverlayDir)
        || android::base::StartsWith(path, kSystemOdmOverlayDir)
        || android::base::StartsWith(path, kOdmOverlayDir)
        || android::base::StartsWith(path, kSystemOemOverlayDir)
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 4755cb8..f7c8337 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -74,7 +74,7 @@
 const char* AssetManager::IDMAP_BIN = "/system/bin/idmap";
 const char* AssetManager::VENDOR_OVERLAY_DIR = "/vendor/overlay";
 const char* AssetManager::PRODUCT_OVERLAY_DIR = "/product/overlay";
-const char* AssetManager::PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+const char* AssetManager::SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 const char* AssetManager::ODM_OVERLAY_DIR = "/odm/overlay";
 const char* AssetManager::OEM_OVERLAY_DIR = "/oem/overlay";
 const char* AssetManager::OVERLAY_THEME_DIR_PROPERTY = "ro.boot.vendor.overlay.theme";
@@ -575,7 +575,7 @@
                         mZipSet.setZipResourceTableAsset(ap.path, ass);
                 }
             }
-            
+
             if (nextEntryIdx == 0 && ass != NULL) {
                 // If this is the first resource table in the asset
                 // manager, then we are going to cache it so that we
diff --git a/libs/androidfw/include/androidfw/AssetManager.h b/libs/androidfw/include/androidfw/AssetManager.h
index 66fba26b..ce0985b 100644
--- a/libs/androidfw/include/androidfw/AssetManager.h
+++ b/libs/androidfw/include/androidfw/AssetManager.h
@@ -61,7 +61,7 @@
     static const char* IDMAP_BIN;
     static const char* VENDOR_OVERLAY_DIR;
     static const char* PRODUCT_OVERLAY_DIR;
-    static const char* PRODUCT_SERVICES_OVERLAY_DIR;
+    static const char* SYSTEM_EXT_OVERLAY_DIR;
     static const char* ODM_OVERLAY_DIR;
     static const char* OEM_OVERLAY_DIR;
     /*
diff --git a/libs/hwui/pipeline/skia/LayerDrawable.cpp b/libs/hwui/pipeline/skia/LayerDrawable.cpp
index eed1942..b017384 100644
--- a/libs/hwui/pipeline/skia/LayerDrawable.cpp
+++ b/libs/hwui/pipeline/skia/LayerDrawable.cpp
@@ -33,21 +33,51 @@
     }
 }
 
-// This is a less-strict matrix.isTranslate() that will still report being translate-only
-// on imperceptibly small scaleX & scaleY values.
-static bool isBasicallyTranslate(const SkMatrix& matrix) {
-    if (!matrix.isScaleTranslate()) return false;
-    return MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY());
+static inline SkScalar isIntegerAligned(SkScalar x) {
+    return fabsf(roundf(x) - x) <= NON_ZERO_EPSILON;
 }
 
-static bool shouldFilter(const SkMatrix& matrix) {
-    if (!matrix.isScaleTranslate()) return true;
-
-    // We only care about meaningful scale here
-    bool noScale = MathUtils::isOne(matrix.getScaleX()) && MathUtils::isOne(matrix.getScaleY());
-    bool pixelAligned =
-            SkScalarIsInt(matrix.getTranslateX()) && SkScalarIsInt(matrix.getTranslateY());
-    return !(noScale && pixelAligned);
+// Disable filtering when there is no scaling in screen coordinates and the corners have the same
+// fraction (for translate) or zero fraction (for any other rect-to-rect transform).
+static bool shouldFilterRect(const SkMatrix& matrix, const SkRect& srcRect, const SkRect& dstRect) {
+    if (!matrix.rectStaysRect()) return true;
+    SkRect dstDevRect = matrix.mapRect(dstRect);
+    float dstW, dstH;
+    bool requiresIntegerTranslate = false;
+    if (MathUtils::isZero(matrix.getScaleX()) && MathUtils::isZero(matrix.getScaleY())) {
+        // Has a 90 or 270 degree rotation, although total matrix may also have scale factors
+        // in m10 and m01. Those scalings are automatically handled by mapRect so comparing
+        // dimensions is sufficient, but swap width and height comparison.
+        dstW = dstDevRect.height();
+        dstH = dstDevRect.width();
+        requiresIntegerTranslate = true;
+    } else {
+        // Handle H/V flips or 180 rotation matrices. Axes may have been mirrored, but
+        // dimensions are still safe to compare directly.
+        dstW = dstDevRect.width();
+        dstH = dstDevRect.height();
+        requiresIntegerTranslate =
+                matrix.getScaleX() < -NON_ZERO_EPSILON || matrix.getScaleY() < -NON_ZERO_EPSILON;
+    }
+    if (!(MathUtils::areEqual(dstW, srcRect.width()) &&
+          MathUtils::areEqual(dstH, srcRect.height()))) {
+        return true;
+    }
+    if (requiresIntegerTranslate) {
+        // Device rect and source rect should be integer aligned to ensure there's no difference
+        // in how nearest-neighbor sampling is resolved.
+        return !(isIntegerAligned(srcRect.x()) &&
+                 isIntegerAligned(srcRect.y()) &&
+                 isIntegerAligned(dstDevRect.x()) &&
+                 isIntegerAligned(dstDevRect.y()));
+    } else {
+        // As long as src and device rects are translated by the same fractional amount,
+        // filtering won't be needed
+        return !(MathUtils::areEqual(SkScalarFraction(srcRect.x()),
+                                     SkScalarFraction(dstDevRect.x())) &&
+                 MathUtils::areEqual(SkScalarFraction(srcRect.y()),
+                                     SkScalarFraction(dstDevRect.y())));
+    }
 }
 
 bool LayerDrawable::DrawLayer(GrContext* context, SkCanvas* canvas, Layer* layer,
@@ -114,24 +144,21 @@
                 skiaDestRect = SkRect::MakeIWH(layerWidth, layerHeight);
             }
             matrixInv.mapRect(&skiaDestRect);
-            // If (matrix is identity or an integer translation) and (src/dst buffers size match),
+            // If (matrix is a rect-to-rect transform)
+            // and (src/dst buffers size match in screen coordinates)
+            // and (src/dst corners align fractionally),
             // then use nearest neighbor, otherwise use bilerp sampling.
-            // Integer translation is defined as when src rect and dst rect align fractionally.
             // Skia TextureOp has the above logic build-in, but not NonAAFillRectOp. TextureOp works
             // only for SrcOver blending and without color filter (readback uses Src blending).
-            bool isIntegerTranslate =
-                    isBasicallyTranslate(totalMatrix) &&
-                    SkScalarFraction(skiaDestRect.fLeft + totalMatrix[SkMatrix::kMTransX]) ==
-                            SkScalarFraction(skiaSrcRect.fLeft) &&
-                    SkScalarFraction(skiaDestRect.fTop + totalMatrix[SkMatrix::kMTransY]) ==
-                            SkScalarFraction(skiaSrcRect.fTop);
-            if (layer->getForceFilter() || !isIntegerTranslate) {
+            if (layer->getForceFilter() ||
+                shouldFilterRect(totalMatrix, skiaSrcRect, skiaDestRect)) {
                 paint.setFilterQuality(kLow_SkFilterQuality);
             }
             canvas->drawImageRect(layerImage.get(), skiaSrcRect, skiaDestRect, &paint,
                                   SkCanvas::kFast_SrcRectConstraint);
         } else {
-            if (layer->getForceFilter() || shouldFilter(totalMatrix)) {
+            SkRect imageRect = SkRect::MakeIWH(layerImage->width(), layerImage->height());
+            if (layer->getForceFilter() || shouldFilterRect(totalMatrix, imageRect, imageRect)) {
                 paint.setFilterQuality(kLow_SkFilterQuality);
             }
             canvas->drawImage(layerImage.get(), 0, 0, &paint);
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f326ce8..9898a1c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -148,7 +148,8 @@
 
     if (surface) {
         mNativeSurface = new ReliableSurface{std::move(surface)};
-        mNativeSurface->setDequeueTimeout(500_ms);
+        // TODO: Fix error handling & re-shorten timeout
+        mNativeSurface->setDequeueTimeout(4000_ms);
     } else {
         mNativeSurface = nullptr;
     }
diff --git a/libs/hwui/surfacetexture/ImageConsumer.cpp b/libs/hwui/surfacetexture/ImageConsumer.cpp
index bae616b..17ee17d 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.cpp
+++ b/libs/hwui/surfacetexture/ImageConsumer.cpp
@@ -71,13 +71,16 @@
     void makeImage(sp<GraphicBuffer>& graphicBuffer, android_dataspace dataspace,
                    GrContext* context);
 
+    void newBufferContent(GrContext* context);
+
 private:
     // The only way to invoke dtor is with unref, when mUsageCount is 0.
     ~AutoBackendTextureRelease() {}
 
     GrBackendTexture mBackendTexture;
     GrAHardwareBufferUtils::DeleteImageProc mDeleteProc;
-    GrAHardwareBufferUtils::DeleteImageCtx mDeleteCtx;
+    GrAHardwareBufferUtils::UpdateImageProc mUpdateProc;
+    GrAHardwareBufferUtils::TexImageCtx mImageCtx;
 
     // Starting with refcount 1, because the first ref is held by SurfaceTexture. Additional refs
     // are held by SkImages.
@@ -101,7 +104,8 @@
         buffer->getWidth(),
         buffer->getHeight(),
         &mDeleteProc,
-        &mDeleteCtx,
+        &mUpdateProc,
+        &mImageCtx,
         createProtectedImage,
         backendFormat,
         false);
@@ -123,7 +127,7 @@
     mUsageCount--;
     if (mUsageCount <= 0) {
         if (mBackendTexture.isValid()) {
-            mDeleteProc(mDeleteCtx);
+            mDeleteProc(mImageCtx);
             mBackendTexture = {};
         }
         delete this;
@@ -154,6 +158,12 @@
     }
 }
 
+void AutoBackendTextureRelease::newBufferContent(GrContext* context) {
+    if (mBackendTexture.isValid()) {
+        mUpdateProc(mImageCtx, context);
+    }
+}
+
 void ImageConsumer::ImageSlot::createIfNeeded(sp<GraphicBuffer> graphicBuffer,
                                               android_dataspace dataspace, bool forceCreate,
                                               GrContext* context) {
@@ -166,6 +176,8 @@
 
         if (!mTextureRelease) {
             mTextureRelease = new AutoBackendTextureRelease(context, graphicBuffer.get());
+        } else {
+            mTextureRelease->newBufferContent(context);
         }
 
         mDataspace = dataspace;
diff --git a/libs/hwui/surfacetexture/ImageConsumer.h b/libs/hwui/surfacetexture/ImageConsumer.h
index 2fdece9..3e2a91a 100644
--- a/libs/hwui/surfacetexture/ImageConsumer.h
+++ b/libs/hwui/surfacetexture/ImageConsumer.h
@@ -26,11 +26,6 @@
 #include <gui/BufferItem.h>
 #include <system/graphics.h>
 
-namespace GrAHardwareBufferUtils {
-typedef void* DeleteImageCtx;
-typedef void (*DeleteImageProc)(DeleteImageCtx);
-}
-
 namespace android {
 
 namespace uirenderer {
diff --git a/location/lib/Android.bp b/location/lib/Android.bp
index 3cd6ccf..fe0f669 100644
--- a/location/lib/Android.bp
+++ b/location/lib/Android.bp
@@ -16,9 +16,11 @@
 
 java_sdk_library {
     name: "com.android.location.provider",
-    srcs: [
-        "java/**/*.java",
-        ":framework-all-sources",
+    srcs: ["java/**/*.java"],
+    api_srcs: [":framework-all-sources"],
+    libs: [
+        "androidx.annotation_annotation",
+        "framework-all",
     ],
     api_packages: ["com.android.location.provider"],
 }
diff --git a/location/lib/api/current.txt b/location/lib/api/current.txt
index d1b39b3..5471bea 100644
--- a/location/lib/api/current.txt
+++ b/location/lib/api/current.txt
@@ -9,7 +9,7 @@
   public abstract class LocationProviderBase {
     ctor public LocationProviderBase(String, com.android.location.provider.ProviderPropertiesUnbundled);
     method public android.os.IBinder getBinder();
-    method public boolean isEnabled();
+    method @RequiresApi(android.os.Build.VERSION_CODES.Q) public boolean isEnabled();
     method @Deprecated protected void onDisable();
     method @Deprecated protected void onDump(java.io.FileDescriptor, java.io.PrintWriter, String[]);
     method @Deprecated protected void onEnable();
@@ -19,9 +19,9 @@
     method protected boolean onSendExtraCommand(@Nullable String, @Nullable android.os.Bundle);
     method protected abstract void onSetRequest(com.android.location.provider.ProviderRequestUnbundled, android.os.WorkSource);
     method public void reportLocation(android.location.Location);
-    method public void setAdditionalProviderPackages(java.util.List<java.lang.String>);
-    method public void setEnabled(boolean);
-    method public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
+    method @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setAdditionalProviderPackages(java.util.List<java.lang.String>);
+    method @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setEnabled(boolean);
+    method @RequiresApi(android.os.Build.VERSION_CODES.Q) public void setProperties(com.android.location.provider.ProviderPropertiesUnbundled);
     field public static final String EXTRA_NO_GPS_LOCATION = "noGPSLocation";
     field public static final String FUSED_PROVIDER = "fused";
   }
@@ -48,7 +48,7 @@
     method public long getInterval();
     method public java.util.List<com.android.location.provider.LocationRequestUnbundled> getLocationRequests();
     method public boolean getReportLocation();
-    method public boolean isLocationSettingsIgnored();
+    method @RequiresApi(android.os.Build.VERSION_CODES.Q) public boolean isLocationSettingsIgnored();
   }
 
 }
diff --git a/location/lib/java/com/android/location/provider/LocationProviderBase.java b/location/lib/java/com/android/location/provider/LocationProviderBase.java
index fa113a8..6bde3a8 100644
--- a/location/lib/java/com/android/location/provider/LocationProviderBase.java
+++ b/location/lib/java/com/android/location/provider/LocationProviderBase.java
@@ -22,6 +22,7 @@
 import android.location.Location;
 import android.location.LocationManager;
 import android.location.LocationProvider;
+import android.os.Build.VERSION_CODES;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -29,6 +30,8 @@
 import android.os.WorkSource;
 import android.util.Log;
 
+import androidx.annotation.RequiresApi;
+
 import com.android.internal.location.ILocationProvider;
 import com.android.internal.location.ILocationProviderManager;
 import com.android.internal.location.ProviderProperties;
@@ -125,6 +128,7 @@
      * taken into account in the parent's enabled/disabled state. For most providers, it is expected
      * that they will be always enabled.
      */
+    @RequiresApi(VERSION_CODES.Q)
     public void setEnabled(boolean enabled) {
         synchronized (mBinder) {
             if (mEnabled == enabled) {
@@ -148,6 +152,7 @@
      * Sets the provider properties that may be queried by clients. Generally speaking, providers
      * should try to avoid changing their properties after construction.
      */
+    @RequiresApi(VERSION_CODES.Q)
     public void setProperties(ProviderPropertiesUnbundled properties) {
         synchronized (mBinder) {
             mProperties = properties.getProviderProperties();
@@ -170,6 +175,7 @@
      * providing location. This will inform location services to treat the other packages as
      * location providers as well.
      */
+    @RequiresApi(VERSION_CODES.Q)
     public void setAdditionalProviderPackages(List<String> packageNames) {
         synchronized (mBinder) {
             mAdditionalProviderPackages.clear();
@@ -190,6 +196,7 @@
      * Returns true if this provider has been set as enabled. This will be true unless explicitly
      * set otherwise.
      */
+    @RequiresApi(VERSION_CODES.Q)
     public boolean isEnabled() {
         return mEnabled;
     }
diff --git a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
index febbf1b..d12d6b7 100644
--- a/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
+++ b/location/lib/java/com/android/location/provider/ProviderRequestUnbundled.java
@@ -17,6 +17,9 @@
 package com.android.location.provider;
 
 import android.location.LocationRequest;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
 
 import com.android.internal.location.ProviderRequest;
 
@@ -46,6 +49,7 @@
         return mRequest.interval;
     }
 
+    @RequiresApi(Build.VERSION_CODES.Q)
     public boolean isLocationSettingsIgnored() {
         return mRequest.locationSettingsIgnored;
     }
diff --git a/media/Android.bp b/media/Android.bp
index 25aef76..a768b81 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -61,26 +61,6 @@
     path: "apex/java",
 }
 
-filegroup {
-    name: "mediaplayer2-srcs",
-    srcs: [
-        "apex/java/android/media/CloseGuard.java",
-        "apex/java/android/media/DataSourceCallback.java",
-        "apex/java/android/media/DataSourceDesc.java",
-        "apex/java/android/media/UriDataSourceDesc.java",
-        "apex/java/android/media/FileDataSourceDesc.java",
-        "apex/java/android/media/Media2Utils.java",
-        "apex/java/android/media/MediaPlayer2Utils.java",
-        "apex/java/android/media/MediaPlayer2.java",
-        "apex/java/android/media/Media2HTTPService.java",
-        "apex/java/android/media/Media2HTTPConnection.java",
-        "apex/java/android/media/RoutingDelegate.java",
-        "apex/java/android/media/BufferingParams.java",
-        "apex/java/android/media/ProxyDataSourceCallback.java",
-    ],
-    path: "apex/java",
-}
-
 metalava_updatable_media_args = " --error UnhiddenSystemApi " +
     "--hide RequiresPermission " +
     "--hide MissingPermission --hide BroadcastBehavior " +
diff --git a/media/apex/java/android/media/DataSourceDesc.java b/media/apex/java/android/media/DataSourceDesc.java
deleted file mode 100644
index 9a9c74a..0000000
--- a/media/apex/java/android/media/DataSourceDesc.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.Uri;
-import android.os.ParcelFileDescriptor;
-
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Data source descriptor.
- *
- * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
- * {@link MediaPlayer2#setNextDataSources} to set data source for playback.
- *
- * @hide
- */
-public class DataSourceDesc {
-    // intentionally less than long.MAX_VALUE
-    static final long LONG_MAX = 0x7ffffffffffffffL;
-
-    // keep consistent with native code
-    public static final long LONG_MAX_TIME_MS = LONG_MAX / 1000;
-    /**
-     * @hide
-     */
-    public static final long LONG_MAX_TIME_US = LONG_MAX_TIME_MS * 1000;
-
-    public static final long POSITION_UNKNOWN = LONG_MAX_TIME_MS;
-
-    private String mMediaId;
-    private long mStartPositionMs = 0;
-    private long mEndPositionMs = POSITION_UNKNOWN;
-
-    DataSourceDesc(String mediaId, long startPositionMs, long endPositionMs) {
-        mMediaId = mediaId;
-        mStartPositionMs = startPositionMs;
-        mEndPositionMs = endPositionMs;
-    }
-
-    /**
-     * Releases the resources held by this {@code DataSourceDesc} object.
-     */
-    void close() {
-    }
-
-    // Have to declare protected for finalize() since it is protected
-    // in the base class Object.
-    @Override
-    protected void finalize() throws Throwable {
-        close();
-    }
-
-    /**
-     * Return the media Id of data source.
-     * @return the media Id of data source
-     */
-    public @Nullable String getMediaId() {
-        return mMediaId;
-    }
-
-    /**
-     * Return the position in milliseconds at which the playback will start.
-     * @return the position in milliseconds at which the playback will start
-     */
-    public long getStartPosition() {
-        return mStartPositionMs;
-    }
-
-    /**
-     * Return the position in milliseconds at which the playback will end.
-     * {@link #POSITION_UNKNOWN} means ending at the end of source content.
-     * @return the position in milliseconds at which the playback will end
-     */
-    public long getEndPosition() {
-        return mEndPositionMs;
-    }
-
-    @Override
-    public String toString() {
-        final StringBuilder sb = new StringBuilder("DataSourceDesc{");
-        sb.append("mMediaId=").append(mMediaId);
-        sb.append(", mStartPositionMs=").append(mStartPositionMs);
-        sb.append(", mEndPositionMs=").append(mEndPositionMs);
-        sb.append('}');
-        return sb.toString();
-    }
-
-    /**
-     * Builder for {@link DataSourceDesc}.
-     * <p>
-     * Here is an example where <code>Builder</code> is used to define the
-     * {@link DataSourceDesc} to be used by a {@link MediaPlayer2} instance:
-     *
-     * <pre class="prettyprint">
-     * DataSourceDesc newDSD = new DataSourceDesc.Builder()
-     *         .setDataSource(context, uri, headers, cookies)
-     *         .setStartPosition(1000)
-     *         .setEndPosition(15000)
-     *         .build();
-     * mediaplayer2.setDataSourceDesc(newDSD);
-     * </pre>
-     */
-    public static final class Builder {
-        private static final int SOURCE_TYPE_UNKNOWN = 0;
-        private static final int SOURCE_TYPE_URI = 1;
-        private static final int SOURCE_TYPE_FILE = 2;
-
-        private int mSourceType = SOURCE_TYPE_UNKNOWN;
-        private String mMediaId;
-        private long mStartPositionMs = 0;
-        private long mEndPositionMs = POSITION_UNKNOWN;
-
-        // For UriDataSourceDesc
-        private Uri mUri;
-        private Map<String, String> mHeader;
-        private List<HttpCookie> mCookies;
-
-        // For FileDataSourceDesc
-        private ParcelFileDescriptor mPFD;
-        private long mOffset = 0;
-        private long mLength = FileDataSourceDesc.FD_LENGTH_UNKNOWN;
-
-        /**
-         * Constructs a new BuilderBase with the defaults.
-         */
-        public Builder() {
-        }
-
-        /**
-         * Constructs a new BuilderBase from a given {@link DataSourceDesc} instance
-         * @param dsd the {@link DataSourceDesc} object whose data will be reused
-         * in the new BuilderBase.
-         */
-        public Builder(@Nullable DataSourceDesc dsd) {
-            if (dsd == null) {
-                return;
-            }
-            mMediaId = dsd.mMediaId;
-            mStartPositionMs = dsd.mStartPositionMs;
-            mEndPositionMs = dsd.mEndPositionMs;
-            if (dsd instanceof FileDataSourceDesc) {
-                mSourceType = SOURCE_TYPE_FILE;
-                mPFD = ((FileDataSourceDesc) dsd).getParcelFileDescriptor();
-                mOffset = ((FileDataSourceDesc) dsd).getOffset();
-                mLength = ((FileDataSourceDesc) dsd).getLength();
-            } else if (dsd instanceof UriDataSourceDesc) {
-                mSourceType = SOURCE_TYPE_URI;
-                mUri = ((UriDataSourceDesc) dsd).getUri();
-                mHeader = ((UriDataSourceDesc) dsd).getHeaders();
-                mCookies = ((UriDataSourceDesc) dsd).getCookies();
-            } else {
-                throw new IllegalStateException("Unknown source type:" + mSourceType);
-            }
-        }
-
-        /**
-         * Sets all fields that have been set in the {@link DataSourceDesc} object.
-         * <code>IllegalStateException</code> will be thrown if there is conflict between fields.
-         *
-         * @return {@link DataSourceDesc}
-         */
-        @NonNull
-        public DataSourceDesc build() {
-            if (mSourceType == SOURCE_TYPE_UNKNOWN) {
-                throw new IllegalStateException("Source is not set.");
-            }
-            if (mStartPositionMs > mEndPositionMs) {
-                throw new IllegalStateException("Illegal start/end position: "
-                    + mStartPositionMs + " : " + mEndPositionMs);
-            }
-
-            DataSourceDesc desc;
-            if (mSourceType == SOURCE_TYPE_FILE) {
-                desc = new FileDataSourceDesc(
-                        mMediaId, mStartPositionMs, mEndPositionMs, mPFD, mOffset, mLength);
-            } else if (mSourceType == SOURCE_TYPE_URI) {
-                desc = new UriDataSourceDesc(
-                        mMediaId, mStartPositionMs, mEndPositionMs, mUri, mHeader, mCookies);
-            } else {
-                throw new IllegalStateException("Unknown source type:" + mSourceType);
-            }
-            return desc;
-        }
-
-        /**
-         * Sets the media Id of this data source.
-         *
-         * @param mediaId the media Id of this data source
-         * @return the same Builder instance.
-         */
-        @NonNull
-        public Builder setMediaId(@Nullable String mediaId) {
-            mMediaId = mediaId;
-            return this;
-        }
-
-        /**
-         * Sets the start position in milliseconds at which the playback will start.
-         * Any negative number is treated as 0.
-         *
-         * @param position the start position in milliseconds at which the playback will start
-         * @return the same Builder instance.
-         *
-         */
-        @NonNull
-        public Builder setStartPosition(long position) {
-            if (position < 0) {
-                position = 0;
-            }
-            mStartPositionMs = position;
-            return this;
-        }
-
-        /**
-         * Sets the end position in milliseconds at which the playback will end.
-         * Any negative number is treated as maximum duration {@link #LONG_MAX_TIME_MS}
-         * of the data source
-         *
-         * @param position the end position in milliseconds at which the playback will end
-         * @return the same Builder instance.
-         */
-        @NonNull
-        public Builder setEndPosition(long position) {
-            if (position < 0) {
-                position = LONG_MAX_TIME_MS;
-            }
-            mEndPositionMs = position;
-            return this;
-        }
-
-        /**
-         * Sets the data source as a content Uri.
-         *
-         * @param uri the Content URI of the data you want to play
-         * @return the same Builder instance.
-         * @throws NullPointerException if context or uri is null.
-         */
-        @NonNull
-        public Builder setDataSource(@NonNull Uri uri) {
-            setSourceType(SOURCE_TYPE_URI);
-            Media2Utils.checkArgument(uri != null, "uri cannot be null");
-            mUri = uri;
-            return this;
-        }
-
-        /**
-         * Sets the data source as a content Uri.
-         *
-         * To provide cookies for the subsequent HTTP requests, you can install your own default
-         * cookie handler and use other variants of setDataSource APIs instead. Alternatively, you
-         * can use this API to pass the cookies as a list of HttpCookie. If the app has not
-         * installed a CookieHandler already, {@link MediaPlayer2} will create a CookieManager
-         * and populates its CookieStore with the provided cookies when this data source is passed
-         * to {@link MediaPlayer2}. If the app has installed its own handler already, the handler
-         * is required to be of CookieManager type such that {@link MediaPlayer2} can update the
-         * manager’s CookieStore.
-         *
-         *  <p><strong>Note</strong> that the cross domain redirection is allowed by default,
-         * but that can be changed with key/value pairs through the headers parameter with
-         * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
-         * disallow or allow cross domain redirection.
-         *
-         * @param uri the Content URI of the data you want to play
-         * @param headers the headers to be sent together with the request for the data
-         *                The headers must not include cookies. Instead, use the cookies param.
-         * @param cookies the cookies to be sent together with the request
-         * @return the same Builder instance.
-         * @throws NullPointerException if context or uri is null.
-         * @throws IllegalArgumentException if the cookie handler is not of CookieManager type
-         *                                  when cookies are provided.
-         */
-        @NonNull
-        public Builder setDataSource(@NonNull Uri uri, @Nullable Map<String, String> headers,
-                @Nullable List<HttpCookie> cookies) {
-            setSourceType(SOURCE_TYPE_URI);
-            Media2Utils.checkArgument(uri != null, "uri cannot be null");
-            if (cookies != null) {
-                CookieHandler cookieHandler = CookieHandler.getDefault();
-                if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) {
-                    throw new IllegalArgumentException(
-                            "The cookie handler has to be of CookieManager type "
-                                    + "when cookies are provided.");
-                }
-            }
-
-            mUri = uri;
-            if (headers != null) {
-                mHeader = new HashMap<String, String>(headers);
-            }
-            if (cookies != null) {
-                mCookies = new ArrayList<HttpCookie>(cookies);
-            }
-            return this;
-        }
-
-        /**
-         * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be
-         * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc}
-         * created by this builder is passed to {@link MediaPlayer2} via
-         * {@link MediaPlayer2#setDataSource},
-         * {@link MediaPlayer2#setNextDataSource} or
-         * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will
-         * close the ParcelFileDescriptor.
-         *
-         * @param pfd the ParcelFileDescriptor for the file to play
-         * @return the same Builder instance.
-         * @throws NullPointerException if pfd is null.
-         */
-        @NonNull
-        public Builder setDataSource(@NonNull ParcelFileDescriptor pfd) {
-            setSourceType(SOURCE_TYPE_FILE);
-            Media2Utils.checkArgument(pfd != null, "pfd cannot be null.");
-            mPFD = pfd;
-            return this;
-        }
-
-        /**
-         * Sets the data source (ParcelFileDescriptor) to use. The ParcelFileDescriptor must be
-         * seekable (N.B. a LocalSocket is not seekable). When the {@link DataSourceDesc}
-         * created by this builder is passed to {@link MediaPlayer2} via
-         * {@link MediaPlayer2#setDataSource},
-         * {@link MediaPlayer2#setNextDataSource} or
-         * {@link MediaPlayer2#setNextDataSources}, MediaPlayer2 will
-         * close the ParcelFileDescriptor.
-         *
-         * Any negative number for offset is treated as 0.
-         * Any negative number for length is treated as maximum length of the data source.
-         *
-         * @param pfd the ParcelFileDescriptor for the file to play
-         * @param offset the offset into the file where the data to be played starts, in bytes
-         * @param length the length in bytes of the data to be played
-         * @return the same Builder instance.
-         * @throws NullPointerException if pfd is null.
-         */
-        @NonNull
-        public Builder setDataSource(
-                @NonNull ParcelFileDescriptor pfd, long offset, long length) {
-            setSourceType(SOURCE_TYPE_FILE);
-            if (pfd == null) {
-                throw new NullPointerException("pfd cannot be null.");
-            }
-            if (offset < 0) {
-                offset = 0;
-            }
-            if (length < 0) {
-                length = FileDataSourceDesc.FD_LENGTH_UNKNOWN;
-            }
-            mPFD = pfd;
-            mOffset = offset;
-            mLength = length;
-            return this;
-        }
-
-        private void setSourceType(int type) {
-            if (mSourceType != SOURCE_TYPE_UNKNOWN) {
-                throw new IllegalStateException("Source is already set. type=" + mSourceType);
-            }
-            mSourceType = type;
-        }
-    }
-}
diff --git a/media/apex/java/android/media/FileDataSourceDesc.java b/media/apex/java/android/media/FileDataSourceDesc.java
deleted file mode 100644
index 2aa2cb7..0000000
--- a/media/apex/java/android/media/FileDataSourceDesc.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.NonNull;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import java.io.IOException;
-
-/**
- * Structure of data source descriptor for sources using file descriptor.
- *
- * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
- * {@link MediaPlayer2#setNextDataSources} to set data source for playback.
- *
- * <p>Users should use {@link Builder} to create {@link FileDataSourceDesc}.
- * @hide
- */
-public class FileDataSourceDesc extends DataSourceDesc {
-    private static final String TAG = "FileDataSourceDesc";
-
-    /**
-     * Used when the length of file descriptor is unknown.
-     *
-     * @see #getLength()
-     */
-    public static final long FD_LENGTH_UNKNOWN = LONG_MAX;
-
-    private ParcelFileDescriptor mPFD;
-    private long mOffset = 0;
-    private long mLength = FD_LENGTH_UNKNOWN;
-    private int mCount = 0;
-    private boolean mClosed = false;
-
-    FileDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs,
-            ParcelFileDescriptor pfd, long offset, long length) {
-        super(mediaId, startPositionMs, endPositionMs);
-        mPFD = pfd;
-        mOffset = offset;
-        mLength = length;
-    }
-
-    /**
-     * Releases the resources held by this {@code FileDataSourceDesc} object.
-     */
-    @Override
-    void close() {
-        super.close();
-        decCount();
-    }
-
-    /**
-     * Decrements usage count by {@link MediaPlayer2}.
-     * If this is the last usage, also releases the file descriptor held by this
-     * {@code FileDataSourceDesc} object.
-     */
-    void decCount() {
-        synchronized (this) {
-            --mCount;
-            if (mCount > 0) {
-                return;
-            }
-
-            try {
-                mPFD.close();
-                mClosed = true;
-            } catch (IOException e) {
-                Log.e(TAG, "failed to close pfd: " + e);
-            }
-        }
-    }
-
-    /**
-     * Increments usage count by {@link MediaPlayer2} if PFD has not been closed.
-     */
-    void incCount() {
-        synchronized (this) {
-            if (!mClosed) {
-                ++mCount;
-            }
-        }
-    }
-
-    /**
-     * Return the status of underline ParcelFileDescriptor
-     * @return true if underline ParcelFileDescriptor is closed, false otherwise.
-     */
-    boolean isPFDClosed() {
-        synchronized (this) {
-            return mClosed;
-        }
-    }
-
-    /**
-     * Return the ParcelFileDescriptor of this data source.
-     * @return the ParcelFileDescriptor of this data source
-     */
-    public @NonNull ParcelFileDescriptor getParcelFileDescriptor() {
-        return mPFD;
-    }
-
-    /**
-     * Return the offset associated with the ParcelFileDescriptor of this data source.
-     * It's meaningful only when it has been set by the {@link Builder}.
-     * @return the offset associated with the ParcelFileDescriptor of this data source
-     */
-    public long getOffset() {
-        return mOffset;
-    }
-
-    /**
-     * Return the content length associated with the ParcelFileDescriptor of this data source.
-     * {@link #FD_LENGTH_UNKNOWN} means same as the length of source content.
-     * @return the content length associated with the ParcelFileDescriptor of this data source
-     */
-    public long getLength() {
-        return mLength;
-    }
-}
diff --git a/media/apex/java/android/media/Media2HTTPConnection.java b/media/apex/java/android/media/Media2HTTPConnection.java
deleted file mode 100644
index a369a62..0000000
--- a/media/apex/java/android/media/Media2HTTPConnection.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright 2017 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 android.media.MediaPlayer2.MEDIA_ERROR_UNSUPPORTED;
-
-import android.os.StrictMode;
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.HttpURLConnection;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.NoRouteToHostException;
-import java.net.ProtocolException;
-import java.net.Proxy;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.net.UnknownServiceException;
-import java.util.HashMap;
-import java.util.Map;
-
-/** @hide */
-public class Media2HTTPConnection {
-    private static final String TAG = "Media2HTTPConnection";
-    private static final boolean VERBOSE = false;
-
-    // connection timeout - 30 sec
-    private static final int CONNECT_TIMEOUT_MS = 30 * 1000;
-
-    private long mCurrentOffset = -1;
-    private URL mURL = null;
-    private Map<String, String> mHeaders = null;
-    private HttpURLConnection mConnection = null;
-    private long mTotalSize = -1;
-    private InputStream mInputStream = null;
-
-    private boolean mAllowCrossDomainRedirect = true;
-    private boolean mAllowCrossProtocolRedirect = true;
-
-    // from com.squareup.okhttp.internal.http
-    private final static int HTTP_TEMP_REDIRECT = 307;
-    private final static int MAX_REDIRECTS = 20;
-
-    public Media2HTTPConnection() {
-        CookieHandler cookieHandler = CookieHandler.getDefault();
-        if (cookieHandler == null) {
-            Log.w(TAG, "Media2HTTPConnection: Unexpected. No CookieHandler found.");
-        }
-    }
-
-    public boolean connect(String uri, String headers) {
-        if (VERBOSE) {
-            Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
-        }
-
-        try {
-            disconnect();
-            mAllowCrossDomainRedirect = true;
-            mURL = new URL(uri);
-            mHeaders = convertHeaderStringToMap(headers);
-        } catch (MalformedURLException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private boolean parseBoolean(String val) {
-        try {
-            return Long.parseLong(val) != 0;
-        } catch (NumberFormatException e) {
-            return "true".equalsIgnoreCase(val) ||
-                "yes".equalsIgnoreCase(val);
-        }
-    }
-
-    /* returns true iff header is internal */
-    private boolean filterOutInternalHeaders(String key, String val) {
-        if ("android-allow-cross-domain-redirect".equalsIgnoreCase(key)) {
-            mAllowCrossDomainRedirect = parseBoolean(val);
-            // cross-protocol redirects are also controlled by this flag
-            mAllowCrossProtocolRedirect = mAllowCrossDomainRedirect;
-        } else {
-            return false;
-        }
-        return true;
-    }
-
-    private Map<String, String> convertHeaderStringToMap(String headers) {
-        HashMap<String, String> map = new HashMap<String, String>();
-
-        String[] pairs = headers.split("\r\n");
-        for (String pair : pairs) {
-            int colonPos = pair.indexOf(":");
-            if (colonPos >= 0) {
-                String key = pair.substring(0, colonPos);
-                String val = pair.substring(colonPos + 1);
-
-                if (!filterOutInternalHeaders(key, val)) {
-                    map.put(key, val);
-                }
-            }
-        }
-
-        return map;
-    }
-
-    public void disconnect() {
-        teardownConnection();
-        mHeaders = null;
-        mURL = null;
-    }
-
-    private void teardownConnection() {
-        if (mConnection != null) {
-            if (mInputStream != null) {
-                try {
-                    mInputStream.close();
-                } catch (IOException e) {
-                }
-                mInputStream = null;
-            }
-
-            mConnection.disconnect();
-            mConnection = null;
-
-            mCurrentOffset = -1;
-        }
-    }
-
-    private static final boolean isLocalHost(URL url) {
-        if (url == null) {
-            return false;
-        }
-
-        String host = url.getHost();
-
-        if (host == null) {
-            return false;
-        }
-
-        try {
-            if (host.equalsIgnoreCase("localhost")) {
-                return true;
-            }
-            if (InetAddress.getByName(host).isLoopbackAddress()) {
-                return true;
-            }
-        } catch (IllegalArgumentException | UnknownHostException e) {
-        }
-        return false;
-    }
-
-    private void seekTo(long offset) throws IOException {
-        teardownConnection();
-
-        try {
-            int response;
-            int redirectCount = 0;
-
-            URL url = mURL;
-
-            // do not use any proxy for localhost (127.0.0.1)
-            boolean noProxy = isLocalHost(url);
-
-            while (true) {
-                if (noProxy) {
-                    mConnection = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
-                } else {
-                    mConnection = (HttpURLConnection)url.openConnection();
-                }
-                mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
-
-                // handle redirects ourselves if we do not allow cross-domain redirect
-                mConnection.setInstanceFollowRedirects(mAllowCrossDomainRedirect);
-
-                if (mHeaders != null) {
-                    for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
-                        mConnection.setRequestProperty(
-                                entry.getKey(), entry.getValue());
-                    }
-                }
-
-                if (offset > 0) {
-                    mConnection.setRequestProperty(
-                            "Range", "bytes=" + offset + "-");
-                }
-
-                response = mConnection.getResponseCode();
-                if (response != HttpURLConnection.HTTP_MULT_CHOICE &&
-                        response != HttpURLConnection.HTTP_MOVED_PERM &&
-                        response != HttpURLConnection.HTTP_MOVED_TEMP &&
-                        response != HttpURLConnection.HTTP_SEE_OTHER &&
-                        response != HTTP_TEMP_REDIRECT) {
-                    // not a redirect, or redirect handled by HttpURLConnection
-                    break;
-                }
-
-                if (++redirectCount > MAX_REDIRECTS) {
-                    throw new NoRouteToHostException("Too many redirects: " + redirectCount);
-                }
-
-                String method = mConnection.getRequestMethod();
-                if (response == HTTP_TEMP_REDIRECT &&
-                        !method.equals("GET") && !method.equals("HEAD")) {
-                    // "If the 307 status code is received in response to a
-                    // request other than GET or HEAD, the user agent MUST NOT
-                    // automatically redirect the request"
-                    throw new NoRouteToHostException("Invalid redirect");
-                }
-                String location = mConnection.getHeaderField("Location");
-                if (location == null) {
-                    throw new NoRouteToHostException("Invalid redirect");
-                }
-                url = new URL(mURL /* TRICKY: don't use url! */, location);
-                if (!url.getProtocol().equals("https") &&
-                        !url.getProtocol().equals("http")) {
-                    throw new NoRouteToHostException("Unsupported protocol redirect");
-                }
-                boolean sameProtocol = mURL.getProtocol().equals(url.getProtocol());
-                if (!mAllowCrossProtocolRedirect && !sameProtocol) {
-                    throw new NoRouteToHostException("Cross-protocol redirects are disallowed");
-                }
-                boolean sameHost = mURL.getHost().equals(url.getHost());
-                if (!mAllowCrossDomainRedirect && !sameHost) {
-                    throw new NoRouteToHostException("Cross-domain redirects are disallowed");
-                }
-
-                if (response != HTTP_TEMP_REDIRECT) {
-                    // update effective URL, unless it is a Temporary Redirect
-                    mURL = url;
-                }
-            }
-
-            if (mAllowCrossDomainRedirect) {
-                // remember the current, potentially redirected URL if redirects
-                // were handled by HttpURLConnection
-                mURL = mConnection.getURL();
-            }
-
-            if (response == HttpURLConnection.HTTP_PARTIAL) {
-                // Partial content, we cannot just use getContentLength
-                // because what we want is not just the length of the range
-                // returned but the size of the full content if available.
-
-                String contentRange =
-                    mConnection.getHeaderField("Content-Range");
-
-                mTotalSize = -1;
-                if (contentRange != null) {
-                    // format is "bytes xxx-yyy/zzz
-                    // where "zzz" is the total number of bytes of the
-                    // content or '*' if unknown.
-
-                    int lastSlashPos = contentRange.lastIndexOf('/');
-                    if (lastSlashPos >= 0) {
-                        String total =
-                            contentRange.substring(lastSlashPos + 1);
-
-                        try {
-                            mTotalSize = Long.parseLong(total);
-                        } catch (NumberFormatException e) {
-                        }
-                    }
-                }
-            } else if (response != HttpURLConnection.HTTP_OK) {
-                throw new IOException();
-            } else {
-                mTotalSize = mConnection.getContentLength();
-            }
-
-            if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
-                // Some servers simply ignore "Range" requests and serve
-                // data from the start of the content.
-                throw new ProtocolException();
-            }
-
-            mInputStream =
-                new BufferedInputStream(mConnection.getInputStream());
-
-            mCurrentOffset = offset;
-        } catch (IOException e) {
-            mTotalSize = -1;
-            teardownConnection();
-            mCurrentOffset = -1;
-
-            throw e;
-        }
-    }
-
-    public int readAt(long offset, byte[] data, int size) {
-        StrictMode.ThreadPolicy policy =
-            new StrictMode.ThreadPolicy.Builder().permitAll().build();
-
-        StrictMode.setThreadPolicy(policy);
-
-        try {
-            if (offset != mCurrentOffset) {
-                seekTo(offset);
-            }
-
-            int n = mInputStream.read(data, 0, size);
-
-            if (n == -1) {
-                // InputStream signals EOS using a -1 result, our semantics
-                // are to return a 0-length read.
-                n = 0;
-            }
-
-            mCurrentOffset += n;
-
-            if (VERBOSE) {
-                Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
-            }
-
-            return n;
-        } catch (ProtocolException e) {
-            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
-            return MEDIA_ERROR_UNSUPPORTED;
-        } catch (NoRouteToHostException e) {
-            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
-            return MEDIA_ERROR_UNSUPPORTED;
-        } catch (UnknownServiceException e) {
-            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
-            return MEDIA_ERROR_UNSUPPORTED;
-        } catch (IOException e) {
-            if (VERBOSE) {
-                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
-            }
-            return -1;
-        } catch (Exception e) {
-            if (VERBOSE) {
-                Log.d(TAG, "unknown exception " + e);
-                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
-            }
-            return -1;
-        }
-    }
-
-    public long getSize() {
-        if (mConnection == null) {
-            try {
-                seekTo(0);
-            } catch (IOException e) {
-                return -1;
-            }
-        }
-
-        return mTotalSize;
-    }
-
-    public String getMIMEType() {
-        if (mConnection == null) {
-            try {
-                seekTo(0);
-            } catch (IOException e) {
-                return "application/octet-stream";
-            }
-        }
-
-        return mConnection.getContentType();
-    }
-
-    public String getUri() {
-        return mURL.toString();
-    }
-}
diff --git a/media/apex/java/android/media/Media2HTTPService.java b/media/apex/java/android/media/Media2HTTPService.java
deleted file mode 100644
index 0d46ce4..0000000
--- a/media/apex/java/android/media/Media2HTTPService.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2017 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 android.util.Log;
-
-import java.net.HttpCookie;
-import java.util.List;
-
-/** @hide */
-public class Media2HTTPService {
-    private static final String TAG = "Media2HTTPService";
-    private List<HttpCookie> mCookies;
-    private Boolean mCookieStoreInitialized = new Boolean(false);
-
-    public Media2HTTPService(List<HttpCookie> cookies) {
-        mCookies = cookies;
-        Log.v(TAG, "Media2HTTPService(" + this + "): Cookies: " + cookies);
-    }
-
-    public Media2HTTPConnection makeHTTPConnection() {
-
-        synchronized (mCookieStoreInitialized) {
-            Media2Utils.storeCookies(mCookies);
-        }
-
-        return new Media2HTTPConnection();
-    }
-
-    /* package private */ static Media2HTTPService createHTTPService(String path) {
-        return createHTTPService(path, null);
-    }
-
-    // when cookies are provided
-    static Media2HTTPService createHTTPService(String path, List<HttpCookie> cookies) {
-        if (path.startsWith("http://") || path.startsWith("https://")) {
-            return (new Media2HTTPService(cookies));
-        } else if (path.startsWith("widevine://")) {
-            Log.d(TAG, "Widevine classic is no longer supported");
-        }
-
-        return null;
-    }
-}
diff --git a/media/apex/java/android/media/Media2Utils.java b/media/apex/java/android/media/Media2Utils.java
deleted file mode 100644
index a87e967..0000000
--- a/media/apex/java/android/media/Media2Utils.java
+++ /dev/null
@@ -1,78 +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 android.media;
-
-import android.util.Log;
-
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.CookieStore;
-import java.net.HttpCookie;
-import java.util.List;
-
-/** @hide */
-public class Media2Utils {
-    private static final String TAG = "Media2Utils";
-
-    private Media2Utils() {
-    }
-
-    /**
-     * Ensures that an expression checking an argument is true.
-     *
-     * @param expression the expression to check
-     * @param errorMessage the exception message to use if the check fails; will
-     *     be converted to a string using {@link String#valueOf(Object)}
-     * @throws IllegalArgumentException if {@code expression} is false
-     */
-    public static void checkArgument(boolean expression, String errorMessage) {
-        if (!expression) {
-            throw new IllegalArgumentException(errorMessage);
-        }
-    }
-
-    public static synchronized void storeCookies(List<HttpCookie> cookies) {
-        CookieHandler cookieHandler = CookieHandler.getDefault();
-        if (cookieHandler == null) {
-            cookieHandler = new CookieManager();
-            CookieHandler.setDefault(cookieHandler);
-            Log.v(TAG, "storeCookies: CookieManager created: " + cookieHandler);
-        } else {
-            Log.v(TAG, "storeCookies: CookieHandler (" + cookieHandler + ") exists.");
-        }
-
-        if (cookies != null) {
-            if (cookieHandler instanceof CookieManager) {
-                CookieManager cookieManager = (CookieManager)cookieHandler;
-                CookieStore store = cookieManager.getCookieStore();
-                for (HttpCookie cookie : cookies) {
-                    try {
-                        store.add(null, cookie);
-                    } catch (Exception e) {
-                        Log.v(TAG, "storeCookies: CookieStore.add" + cookie, e);
-                    }
-                }
-            } else {
-                Log.w(TAG, "storeCookies: The installed CookieHandler is not a CookieManager."
-                        + " Can’t add the provided cookies to the cookie store.");
-            }
-        }   // cookies
-
-        Log.v(TAG, "storeCookies: cookieHandler: " + cookieHandler + " Cookies: " + cookies);
-
-    }
-}
diff --git a/media/apex/java/android/media/MediaPlayer2.java b/media/apex/java/android/media/MediaPlayer2.java
deleted file mode 100644
index 614d737..0000000
--- a/media/apex/java/android/media/MediaPlayer2.java
+++ /dev/null
@@ -1,5507 +0,0 @@
-/*
- * Copyright 2017 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 android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.StringDef;
-import android.annotation.TestApi;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.res.AssetFileDescriptor;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.media.MediaDrm.KeyRequest;
-import android.media.MediaPlayer2.DrmInfo;
-import android.media.MediaPlayer2Proto.PlayerMessage;
-import android.media.MediaPlayer2Proto.Value;
-import android.media.protobuf.InvalidProtocolBufferException;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.os.ParcelFileDescriptor;
-import android.os.PersistableBundle;
-import android.os.PowerManager;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-
-import com.android.internal.annotations.GuardedBy;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
-import java.net.HttpCookie;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.nio.ByteOrder;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Queue;
-import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.RejectedExecutionException;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * MediaPlayer2 class can be used to control playback of audio/video files and streams.
- *
- * <p>
- * This API is not generally intended for third party application developers.
- * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
- * <a href="{@docRoot}reference/androidx/media2/package-summary.html">Media2 Library</a>
- * for consistent behavior across all devices.
- *
- * <p>Topics covered here are:
- * <ol>
- * <li><a href="#PlayerStates">Player states</a>
- * <li><a href="#InvalidStates">Invalid method calls</a>
- * <li><a href="#Permissions">Permissions</a>
- * <li><a href="#Callbacks">Callbacks</a>
- * </ol>
- *
- *
- * <h3 id="PlayerStates">Player states</h3>
- *
- * <p>The playback control of audio/video files is managed as a state machine.</p>
- * <p><div style="text-align:center;"><img src="../../../images/mediaplayer2_state_diagram.png"
- *         alt="MediaPlayer2 State diagram"
- *         border="0" /></div></p>
- * <p>The MediaPlayer2 object has five states:</p>
- * <ol>
- *     <li><p>{@link #PLAYER_STATE_IDLE}: MediaPlayer2 is in the <strong>Idle</strong>
- *         state after it's created, or after calling {@link #reset()}.</p>
- *
- *         <p>While in this state, you should call
- *         {@link #setDataSource setDataSource}. It is a good
- *         programming practice to register an {@link EventCallback#onCallCompleted onCallCompleted}
- *         <a href="#Callbacks">callback</a> and watch for {@link #CALL_STATUS_BAD_VALUE} and
- *         {@link #CALL_STATUS_ERROR_IO}, which might be caused by <code>setDataSource</code>.
- *         </p>
- *
- *         <p>Calling {@link #prepare()} transfers a MediaPlayer2 object to
- *         the <strong>Prepared</strong> state. Note
- *         that {@link #prepare()} is asynchronous. When the preparation completes,
- *         if you register an {@link EventCallback#onInfo onInfo} <a href="#Callbacks">callback</a>,
- *         the player executes the callback
- *         with {@link #MEDIA_INFO_PREPARED} and transitions to the
- *         <strong>Prepared</strong> state.</p>
- *         </li>
- *
- *     <li>{@link #PLAYER_STATE_PREPARED}: A MediaPlayer object must be in the
- *         <strong>Prepared</strong> state before playback can be started for the first time.
- *         While in this state, you can set player properties
- *         such as audio/sound volume and looping by invoking the corresponding set methods.
- *         Calling {@link #play()} transfers a MediaPlayer2 object to
- *         the <strong>Playing</strong> state.
- *      </li>
- *
- *     <li>{@link #PLAYER_STATE_PLAYING}:
- *         <p>The player plays the data source while in this state.
- *         If you register an {@link EventCallback#onInfo onInfo} <a href="#Callbacks">callback</a>,
- *         the player regularly executes the callback with
- *         {@link #MEDIA_INFO_BUFFERING_UPDATE}.
- *         This allows applications to keep track of the buffering status
- *         while streaming audio/video.</p>
- *
- *         <p> When the playback reaches the end of stream, the behavior depends on whether or
- *         not you've enabled looping by calling {@link #loopCurrent}:</p>
- *         <ul>
- *         <li>If the looping mode was set to <code>false</code>, the player will transfer
- *         to the <strong>Paused</strong> state. If you registered an {@link EventCallback#onInfo
- *         onInfo} <a href="#Callbacks">callback</a>
- *         the player calls the callback with {@link #MEDIA_INFO_DATA_SOURCE_END} and enters
- *         the <strong>Paused</strong> state.
- *         </li>
- *         <li>If the looping mode was set to <code>true</code>,
- *         the MediaPlayer2 object remains in the <strong>Playing</strong> state and replays its
- *         data source from the beginning.</li>
- *         </ul>
- *         </li>
- *
- *     <li>{@link #PLAYER_STATE_PAUSED}: Audio/video playback pauses while in this state.
- *         Call {@link #play()} to resume playback from the position where it paused.</li>
- *
- *     <li>{@link #PLAYER_STATE_ERROR}: <p>In general, playback might fail due to various
- *          reasons such as unsupported audio/video format, poorly interleaved
- *          audio/video, resolution too high, streaming timeout, and others.
- *          In addition, due to programming errors, a playback
- *          control operation might be performed from an <a href="#InvalidStates">invalid state</a>.
- *          In these cases the player transitions to the <strong>Error</strong> state.</p>
- *
- *          <p>If you register an {@link EventCallback#onError onError}}
- *          <a href="#Callbacks">callback</a>,
- *          the callback will be performed when entering the state. When programming errors happen,
- *          such as calling {@link #prepare()} and
- *          {@link #setDataSource} methods
- *          from an <a href="#InvalidStates">invalid state</a>, the callback is called with
- *          {@link #CALL_STATUS_INVALID_OPERATION}. The MediaPlayer2 object enters the
- *          <strong>Error</strong> state whether or not a callback exists. </p>
- *
- *          <p>To recover from an error and reuse a MediaPlayer2 object that is in the <strong>
- *          Error</strong> state,
- *          call {@link #reset()}. The object will return to the <strong>Idle</strong>
- *          state and all state information will be lost.</p>
- *          </li>
- * </ol>
- *
- * <p>You should follow these best practices when coding an app that uses MediaPlayer2:</p>
- *
- * <ul>
- *
- * <li>Use <a href="#Callbacks">callbacks</a> to respond to state changes and errors.</li>
- *
- * <li>When  a MediaPlayer2 object is no longer being used, call {@link #close()} as soon as
- * possible to release the resources used by the internal player engine associated with the
- * MediaPlayer2. Failure to call {@link #close()} may cause subsequent instances of
- * MediaPlayer2 objects to fallback to software implementations or fail altogether.
- * You cannot use MediaPlayer2
- * after you call {@link #close()}. There is no way to bring it back to any other state.</li>
- *
- * <li>The current playback position can be retrieved with a call to
- * {@link #getCurrentPosition()},
- * which is helpful for applications such as a Music player that need to keep track of the playback
- * progress.</li>
- *
- * <li>The playback position can be adjusted with a call to {@link #seekTo}. Although the
- * asynchronous {@link #seekTo} call returns right away, the actual seek operation may take a
- * while to finish, especially for audio/video being streamed. If you register an
- * {@link EventCallback#onCallCompleted onCallCompleted} <a href="#Callbacks">callback</a>,
- * the callback is
- * called When the seek operation completes with {@link #CALL_COMPLETED_SEEK_TO}.</li>
- *
- * <li>You can call {@link #seekTo} from the <strong>Paused</strong> state.
- * In this case, if you are playing a video stream and
- * the requested position is valid  one video frame is displayed.</li>
- *
- * </ul>
- *
- * <h3 id="InvalidStates">Invalid method calls</h3>
- *
- * <p>The only methods you safely call from the <strong>Error</strong> state are
- * {@link #close},
- * {@link #reset},
- * {@link #notifyWhenCommandLabelReached},
- * {@link #clearPendingCommands},
- * {@link #registerEventCallback},
- * {@link #unregisterEventCallback}
- * and {@link #getState}.
- * Any other methods might throw an exception, return meaningless data, or invoke a
- * {@link EventCallback#onCallCompleted onCallCompleted} with an error code.</p>
- *
- * <p>Most methods can be called from any non-Error state. They will either perform their work or
- * silently have no effect. The following table lists the methods that will invoke a
- * {@link EventCallback#onCallCompleted onCallCompleted} with an error code
- * or throw an exception when they are called from the associated invalid states.</p>
- *
- * <table border="0" cellspacing="0" cellpadding="0">
- * <tr><th>Method Name</th>
- * <th>Invalid States</th></tr>
- *
- * <tr><td>setDataSource</td> <td>{Prepared, Paused, Playing}</td></tr>
- * <tr><td>prepare</td> <td>{Prepared, Paused, Playing}</td></tr>
- * <tr><td>play</td> <td>{Idle}</td></tr>
- * <tr><td>pause</td> <td>{Idle}</td></tr>
- * <tr><td>seekTo</td> <td>{Idle}</td></tr>
- * <tr><td>getCurrentPosition</td> <td>{Idle}</td></tr>
- * <tr><td>getDuration</td> <td>{Idle}</td></tr>
- * <tr><td>getBufferedPosition</td> <td>{Idle}</td></tr>
- * <tr><td>getTrackInfo</td> <td>{Idle}</td></tr>
- * <tr><td>getSelectedTrack</td> <td>{Idle}</td></tr>
- * <tr><td>selectTrack</td> <td>{Idle}</td></tr>
- * <tr><td>deselectTrack</td> <td>{Idle}</td></tr>
- * </table>
- *
- * <h3 id="Permissions">Permissions</h3>
- * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
- * when used with network-based content.
- *
- * <h3 id="Callbacks">Callbacks</h3>
- * <p>Many errors do not result in a transition to the  <strong>Error</strong> state.
- * It is good programming practice to register callback listeners using
- * {@link #registerEventCallback}.
- * You can receive a callback at any time and from any state.</p>
- *
- * <p>If it's important for your app to respond to state changes (for instance, to update the
- * controls on a transport UI), you should register an
- * {@link EventCallback#onCallCompleted onCallCompleted} and
- * detect state change commands by testing the <code>what</code> parameter for a callback from one
- * of the state transition methods: {@link #CALL_COMPLETED_PREPARE}, {@link #CALL_COMPLETED_PLAY},
- * and {@link #CALL_COMPLETED_PAUSE}.
- * Then check the <code>status</code> parameter. The value {@link #CALL_STATUS_NO_ERROR} indicates a
- * successful transition. Any other value will be an error. Call {@link #getState()} to
- * determine the current state. </p>
- *
- * @hide
- */
-public class MediaPlayer2 implements AutoCloseable, AudioRouting {
-    static {
-        System.loadLibrary("media2_jni");
-        native_init();
-    }
-
-    private static native void native_init();
-
-    private static final int NEXT_SOURCE_STATE_ERROR = -1;
-    private static final int NEXT_SOURCE_STATE_INIT = 0;
-    private static final int NEXT_SOURCE_STATE_PREPARING = 1;
-    private static final int NEXT_SOURCE_STATE_PREPARED = 2;
-
-    private static final String TAG = "MediaPlayer2";
-
-    private Context mContext;
-
-    private long mNativeContext;  // accessed by native methods
-    private long mNativeSurfaceTexture;  // accessed by native methods
-    private int mListenerContext;  // accessed by native methods
-    private SurfaceHolder mSurfaceHolder;
-    private PowerManager.WakeLock mWakeLock = null;
-    private boolean mScreenOnWhilePlaying;
-    private boolean mStayAwake;
-
-    private final Object mSrcLock = new Object();
-    //--- guarded by |mSrcLock| start
-    private SourceInfo mCurrentSourceInfo;
-    private final Queue<SourceInfo> mNextSourceInfos = new ConcurrentLinkedQueue<>();
-    //--- guarded by |mSrcLock| end
-    private final AtomicLong mSrcIdGenerator = new AtomicLong(0);
-
-    private volatile float mVolume = 1.0f;
-    private Size mVideoSize = new Size(0, 0);
-
-    private static ExecutorService sDrmThreadPool = Executors.newCachedThreadPool();
-
-    // Creating a dummy audio track, used for keeping session id alive
-    private final Object mSessionIdLock = new Object();
-    @GuardedBy("mSessionIdLock")
-    private AudioTrack mDummyAudioTrack;
-
-    private HandlerThread mHandlerThread;
-    private final TaskHandler mTaskHandler;
-    private final Object mTaskLock = new Object();
-    @GuardedBy("mTaskLock")
-    private final List<Task> mPendingTasks = new LinkedList<>();
-    @GuardedBy("mTaskLock")
-    private Task mCurrentTask;
-    private final AtomicLong mTaskIdGenerator = new AtomicLong(0);
-
-    @GuardedBy("mTaskLock")
-    boolean mIsPreviousCommandSeekTo = false;
-    // |mPreviousSeekPos| and |mPreviousSeekMode| are valid only when |mIsPreviousCommandSeekTo|
-    // is true, and they are accessed on |mHandlerThread| only.
-    long mPreviousSeekPos = -1;
-    int mPreviousSeekMode = SEEK_PREVIOUS_SYNC;
-
-    @GuardedBy("this")
-    private boolean mReleased;
-
-    private final CloseGuard mGuard = CloseGuard.get();
-
-    /**
-     * Default constructor.
-     * <p>When done with the MediaPlayer2, you should call {@link #close()},
-     * to free the resources. If not released, too many MediaPlayer2 instances may
-     * result in an exception.</p>
-     */
-    public MediaPlayer2(@NonNull Context context) {
-        mGuard.open("close");
-
-        mContext = context;
-        mHandlerThread = new HandlerThread("MediaPlayer2TaskThread");
-        mHandlerThread.start();
-        Looper looper = mHandlerThread.getLooper();
-        mTaskHandler = new TaskHandler(this, looper);
-        AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
-        int sessionId = am.generateAudioSessionId();
-        keepAudioSessionIdAlive(sessionId);
-
-        /* Native setup requires a weak reference to our object.
-         * It's easier to create it here than in C++.
-         */
-        native_setup(sessionId, new WeakReference<MediaPlayer2>(this));
-    }
-
-    private native void native_setup(int sessionId, Object mediaplayer2This);
-
-    /**
-     * Releases the resources held by this {@code MediaPlayer2} object.
-     *
-     * It is considered good practice to call this method when you're
-     * done using the MediaPlayer2. In particular, whenever an Activity
-     * of an application is paused (its onPause() method is called),
-     * or stopped (its onStop() method is called), this method should be
-     * invoked to release the MediaPlayer2 object, unless the application
-     * has a special need to keep the object around. In addition to
-     * unnecessary resources (such as memory and instances of codecs)
-     * being held, failure to call this method immediately if a
-     * MediaPlayer2 object is no longer needed may also lead to
-     * continuous battery consumption for mobile devices, and playback
-     * failure for other applications if no multiple instances of the
-     * same codec are supported on a device. Even if multiple instances
-     * of the same codec are supported, some performance degradation
-     * may be expected when unnecessary multiple instances are used
-     * at the same time.
-     *
-     * {@code close()} may be safely called after a prior {@code close()}.
-     * This class implements the Java {@code AutoCloseable} interface and
-     * may be used with try-with-resources.
-     */
-    // This is a synchronous call.
-    @Override
-    public void close() {
-        synchronized (mGuard) {
-            mGuard.close();
-        }
-        release();
-    }
-
-    private synchronized void release() {
-        if (mReleased) {
-            return;
-        }
-        stayAwake(false);
-        updateSurfaceScreenOn();
-        synchronized (mEventCbLock) {
-            mEventCallbackRecords.clear();
-        }
-        if (mHandlerThread != null) {
-            mHandlerThread.quitSafely();
-            mHandlerThread = null;
-        }
-
-        clearSourceInfos();
-
-        // Modular DRM clean up
-        synchronized (mDrmEventCallbackLock) {
-            mDrmEventCallback = null;
-        }
-        clearMediaDrmObjects();
-
-        native_release();
-
-        synchronized (mSessionIdLock) {
-            mDummyAudioTrack.release();
-        }
-
-        mReleased = true;
-    }
-
-    void clearMediaDrmObjects() {
-        Collection<MediaDrm> drmObjs = mDrmObjs.values();
-        synchronized (mDrmObjs) {
-            for (MediaDrm drmObj : drmObjs) {
-                drmObj.close();
-            }
-            mDrmObjs.clear();
-        }
-    }
-
-    private native void native_release();
-
-    // Have to declare protected for finalize() since it is protected
-    // in the base class Object.
-    @Override
-    protected void finalize() throws Throwable {
-        if (mGuard != null) {
-            mGuard.warnIfOpen();
-        }
-
-        close();
-        native_finalize();
-    }
-
-    private native void native_finalize();
-
-    /**
-     * Resets the MediaPlayer2 to its uninitialized state. After calling
-     * this method, you will have to initialize it again by setting the
-     * data source and calling prepare().
-     */
-    // This is a synchronous call.
-    public void reset() {
-        clearSourceInfos();
-        clearMediaDrmObjects();
-
-        stayAwake(false);
-        native_reset();
-
-        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
-        int sessionId = am.generateAudioSessionId();
-        keepAudioSessionIdAlive(sessionId);
-
-        // make sure none of the listeners get called anymore
-        if (mTaskHandler != null) {
-            mTaskHandler.removeCallbacksAndMessages(null);
-        }
-
-    }
-
-    private native void native_reset();
-
-    /**
-     * Starts or resumes playback. If playback had previously been paused,
-     * playback will continue from where it was paused. If playback had
-     * reached end of stream and been paused, or never started before,
-     * playback will start at the beginning.
-     *
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object play() {
-        return addTask(new Task(CALL_COMPLETED_PLAY, false) {
-            @Override
-            void process() {
-                stayAwake(true);
-                native_start();
-            }
-        });
-    }
-
-    private native void native_start() throws IllegalStateException;
-
-    /**
-     * Prepares the player for playback, asynchronously.
-     *
-     * After setting the datasource and the display surface, you need to call prepare().
-     *
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object prepare() {
-        return addTask(new Task(CALL_COMPLETED_PREPARE, true) {
-            @Override
-            void process() {
-                native_prepare();
-            }
-        });
-    }
-
-    private native void native_prepare();
-
-    /**
-     * Pauses playback. Call play() to resume.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object pause() {
-        return addTask(new Task(CALL_COMPLETED_PAUSE, false) {
-            @Override
-            void process() {
-                stayAwake(false);
-
-                native_pause();
-            }
-        });
-    }
-
-    private native void native_pause() throws IllegalStateException;
-
-    /**
-     * Tries to play next data source if applicable.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object skipToNext() {
-        return addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
-            @Override
-            void process() {
-                if (getState() == PLAYER_STATE_PLAYING) {
-                    native_pause();
-                }
-                playNextDataSource();
-            }
-        });
-    }
-
-    /**
-     * Gets the current playback position.
-     *
-     * @return the current position in milliseconds
-     */
-    public native long getCurrentPosition();
-
-    /**
-     * Gets the duration of the current data source.
-     * Same as {@link #getDuration(DataSourceDesc)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @return the duration in milliseconds, if no duration is available
-     *         (for example, if streaming live content), -1 is returned.
-     * @throws NullPointerException if current data source is null
-     */
-    public long getDuration() {
-        return getDuration(getCurrentDataSource());
-    }
-
-    /**
-     * Gets the duration of the dsd.
-     *
-     * @param dsd the descriptor of data source of which you want to get duration
-     * @return the duration in milliseconds, if no duration is available
-     *         (for example, if streaming live content), -1 is returned.
-     * @throws NullPointerException if dsd is null
-     */
-    public long getDuration(@NonNull DataSourceDesc dsd) {
-        if (dsd == null) {
-            throw new NullPointerException("non-null dsd is expected");
-        }
-        SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo == null) {
-            return -1;
-        }
-
-        return native_getDuration(sourceInfo.mId);
-    }
-
-    private native long native_getDuration(long srcId);
-
-    /**
-     * Gets the buffered media source position of current data source.
-     * Same as {@link #getBufferedPosition(DataSourceDesc)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @return the current buffered media source position in milliseconds
-     * @throws NullPointerException if current data source is null
-     */
-    public long getBufferedPosition() {
-        return getBufferedPosition(getCurrentDataSource());
-    }
-
-    /**
-     * Gets the buffered media source position of given dsd.
-     * For example a buffering update of 8000 milliseconds when 5000 milliseconds of the content
-     * has already been played indicates that the next 3000 milliseconds of the
-     * content to play has been buffered.
-     *
-     * @param dsd the descriptor of data source of which you want to get buffered position
-     * @return the current buffered media source position in milliseconds
-     * @throws NullPointerException if dsd is null
-     */
-    public long getBufferedPosition(@NonNull DataSourceDesc dsd) {
-        if (dsd == null) {
-            throw new NullPointerException("non-null dsd is expected");
-        }
-        SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo == null) {
-            return 0;
-        }
-
-        // Use cached buffered percent for now.
-        int bufferedPercentage = sourceInfo.mBufferedPercentage.get();
-
-        long duration = getDuration(dsd);
-        if (duration < 0) {
-            duration = 0;
-        }
-
-        return duration * bufferedPercentage / 100;
-    }
-
-    /**
-     * MediaPlayer2 has not been prepared or just has been reset.
-     * In this state, MediaPlayer2 doesn't fetch data.
-     */
-    public static final int PLAYER_STATE_IDLE = 1001;
-
-    /**
-     * MediaPlayer2 has been just prepared.
-     * In this state, MediaPlayer2 just fetches data from media source,
-     * but doesn't actively render data.
-     */
-    public static final int PLAYER_STATE_PREPARED = 1002;
-
-    /**
-     * MediaPlayer2 is paused.
-     * In this state, MediaPlayer2 has allocated resources to construct playback
-     * pipeline, but it doesn't actively render data.
-     */
-    public static final int PLAYER_STATE_PAUSED = 1003;
-
-    /**
-     * MediaPlayer2 is actively playing back data.
-     */
-    public static final int PLAYER_STATE_PLAYING = 1004;
-
-    /**
-     * MediaPlayer2 has hit some fatal error and cannot continue playback.
-     */
-    public static final int PLAYER_STATE_ERROR = 1005;
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "MEDIAPLAYER2_STATE", value = {
-        PLAYER_STATE_IDLE,
-        PLAYER_STATE_PREPARED,
-        PLAYER_STATE_PAUSED,
-        PLAYER_STATE_PLAYING,
-        PLAYER_STATE_ERROR })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediaPlayer2State {}
-
-    /**
-     * Gets the current player state.
-     *
-     * @return the current player state.
-     */
-    public @MediaPlayer2State int getState() {
-        return native_getState();
-    }
-
-    private native int native_getState();
-
-    /**
-     * Sets the audio attributes for this MediaPlayer2.
-     * See {@link AudioAttributes} for how to build and configure an instance of this class.
-     * You must call this method before {@link #play()} and {@link #pause()} in order
-     * for the audio attributes to become effective thereafter.
-     * @param attributes a non-null set of audio attributes
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setAudioAttributes(@NonNull AudioAttributes attributes) {
-        return addTask(new Task(CALL_COMPLETED_SET_AUDIO_ATTRIBUTES, false) {
-            @Override
-            void process() {
-                if (attributes == null) {
-                    final String msg = "Cannot set AudioAttributes to null";
-                    throw new IllegalArgumentException(msg);
-                }
-                native_setAudioAttributes(attributes);
-            }
-        });
-    }
-
-    // return true if the parameter is set successfully, false otherwise
-    private native boolean native_setAudioAttributes(AudioAttributes audioAttributes);
-
-    /**
-     * Gets the audio attributes for this MediaPlayer2.
-     * @return attributes a set of audio attributes
-     */
-    public @NonNull AudioAttributes getAudioAttributes() {
-        return native_getAudioAttributes();
-    }
-
-    private native AudioAttributes native_getAudioAttributes();
-
-    /**
-     * Sets the data source as described by a DataSourceDesc.
-     * When the data source is of {@link FileDataSourceDesc} type, the {@link ParcelFileDescriptor}
-     * in the {@link FileDataSourceDesc} will be closed by the player.
-     *
-     * @param dsd the descriptor of data source you want to play
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setDataSource(@NonNull DataSourceDesc dsd) {
-        return addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
-            @Override
-            void process() throws IOException {
-                checkDataSourceDesc(dsd);
-                int state = getState();
-                try {
-                    if (state != PLAYER_STATE_ERROR && state != PLAYER_STATE_IDLE) {
-                        throw new IllegalStateException("called in wrong state " + state);
-                    }
-
-                    synchronized (mSrcLock) {
-                        setCurrentSourceInfo_l(new SourceInfo(dsd));
-                        handleDataSource(true /* isCurrent */, dsd, mCurrentSourceInfo.mId);
-                    }
-                } finally {
-                    dsd.close();
-                }
-            }
-
-        });
-    }
-
-    /**
-     * Sets a single data source as described by a DataSourceDesc which will be played
-     * after current data source is finished.
-     * When the data source is of {@link FileDataSourceDesc} type, the {@link ParcelFileDescriptor}
-     * in the {@link FileDataSourceDesc} will be closed by the player.
-     *
-     * @param dsd the descriptor of data source you want to play after current one
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setNextDataSource(@NonNull DataSourceDesc dsd) {
-        return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
-            @Override
-            void process() {
-                checkDataSourceDesc(dsd);
-                synchronized (mSrcLock) {
-                    clearNextSourceInfos_l();
-                    mNextSourceInfos.add(new SourceInfo(dsd));
-                }
-                prepareNextDataSource();
-            }
-        });
-    }
-
-    /**
-     * Sets a list of data sources to be played sequentially after current data source is done.
-     * When the data source is of {@link FileDataSourceDesc} type, the {@link ParcelFileDescriptor}
-     * in the {@link FileDataSourceDesc} will be closed by the player.
-     *
-     * @param dsds the list of data sources you want to play after current one
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
-        return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCES, false) {
-            @Override
-            void process() {
-                if (dsds == null || dsds.size() == 0) {
-                    throw new IllegalArgumentException("data source list cannot be null or empty.");
-                }
-                boolean hasError = false;
-                for (DataSourceDesc dsd : dsds) {
-                    if (dsd == null) {
-                        hasError = true;
-                        continue;
-                    }
-                    if (dsd instanceof FileDataSourceDesc) {
-                        FileDataSourceDesc fdsd = (FileDataSourceDesc) dsd;
-                        if (fdsd.isPFDClosed()) {
-                            hasError = true;
-                            continue;
-                        }
-
-                        fdsd.incCount();
-                    }
-                }
-                if (hasError) {
-                    for (DataSourceDesc dsd : dsds) {
-                        if (dsd != null) {
-                            dsd.close();
-                        }
-                    }
-                    throw new IllegalArgumentException("invalid data source list");
-                }
-
-                synchronized (mSrcLock) {
-                    clearNextSourceInfos_l();
-                    for (DataSourceDesc dsd : dsds) {
-                        mNextSourceInfos.add(new SourceInfo(dsd));
-                    }
-                }
-                prepareNextDataSource();
-            }
-        });
-    }
-
-    // throws IllegalArgumentException if dsd is null or underline PFD of dsd has been closed.
-    private void checkDataSourceDesc(DataSourceDesc dsd) {
-        if (dsd == null) {
-            throw new IllegalArgumentException("dsd is expected to be non null");
-        }
-        if (dsd instanceof FileDataSourceDesc) {
-            FileDataSourceDesc fdsd = (FileDataSourceDesc) dsd;
-            if (fdsd.isPFDClosed()) {
-                throw new IllegalArgumentException("the underline FileDescriptor has been closed");
-            }
-            fdsd.incCount();
-        }
-    }
-
-    /**
-     * Removes all data sources pending to be played.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object clearNextDataSources() {
-        return addTask(new Task(CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES, false) {
-            @Override
-            void process() {
-                synchronized (mSrcLock) {
-                    clearNextSourceInfos_l();
-                }
-            }
-        });
-    }
-
-    /**
-     * Gets the current data source as described by a DataSourceDesc.
-     *
-     * @return the current DataSourceDesc
-     */
-    public @Nullable DataSourceDesc getCurrentDataSource() {
-        synchronized (mSrcLock) {
-            return mCurrentSourceInfo == null ? null : mCurrentSourceInfo.mDSD;
-        }
-    }
-
-    private void handleDataSource(boolean isCurrent, @NonNull DataSourceDesc dsd, long srcId)
-            throws IOException {
-        Media2Utils.checkArgument(dsd != null, "the DataSourceDesc cannot be null");
-
-        if (dsd instanceof FileDataSourceDesc) {
-            FileDataSourceDesc fileDSD = (FileDataSourceDesc) dsd;
-            ParcelFileDescriptor pfd = fileDSD.getParcelFileDescriptor();
-            if (pfd.getStatSize() == -1) {
-                // Underlying pipeline doesn't understand '-1' size. Create a wrapper for
-                // translation.
-                // TODO: Make native code handle '-1' size.
-                handleDataSource(isCurrent,
-                        srcId,
-                        new ProxyDataSourceCallback(pfd),
-                        fileDSD.getStartPosition(),
-                        fileDSD.getEndPosition());
-            } else {
-                handleDataSource(isCurrent,
-                        srcId,
-                        pfd,
-                        fileDSD.getOffset(),
-                        fileDSD.getLength(),
-                        fileDSD.getStartPosition(),
-                        fileDSD.getEndPosition());
-            }
-        } else if (dsd instanceof UriDataSourceDesc) {
-            UriDataSourceDesc uriDSD = (UriDataSourceDesc) dsd;
-            handleDataSource(isCurrent,
-                             srcId,
-                             mContext,
-                             uriDSD.getUri(),
-                             uriDSD.getHeaders(),
-                             uriDSD.getCookies(),
-                             uriDSD.getStartPosition(),
-                             uriDSD.getEndPosition());
-        } else {
-            throw new IllegalArgumentException("Unsupported DataSourceDesc. " + dsd.toString());
-        }
-    }
-
-    /**
-     * To provide cookies for the subsequent HTTP requests, you can install your own default cookie
-     * handler and use other variants of setDataSource APIs instead. Alternatively, you can use
-     * this API to pass the cookies as a list of HttpCookie. If the app has not installed
-     * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with
-     * the provided cookies. If the app has installed its own handler already, this API requires the
-     * handler to be of CookieManager type such that the API can update the manager’s CookieStore.
-     *
-     * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
-     * but that can be changed with key/value pairs through the headers parameter with
-     * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
-     * disallow or allow cross domain redirection.
-     *
-     * @throws IllegalArgumentException if cookies are provided and the installed handler is not
-     *                                  a CookieManager
-     * @throws IllegalStateException    if it is called in an invalid state
-     * @throws NullPointerException     if context or uri is null
-     * @throws IOException              if uri has a file scheme and an I/O error occurs
-     */
-    private void handleDataSource(
-            boolean isCurrent, long srcId,
-            @NonNull Context context, @NonNull Uri uri,
-            @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies,
-            long startPos, long endPos)
-            throws IOException {
-        // The context and URI usually belong to the calling user. Get a resolver for that user.
-        final ContentResolver resolver = context.getContentResolver();
-        final String scheme = uri.getScheme();
-        if (ContentResolver.SCHEME_FILE.equals(scheme)) {
-            handleDataSource(isCurrent, srcId, uri.getPath(), null, null, startPos, endPos);
-            return;
-        }
-
-        final int ringToneType = RingtoneManager.getDefaultType(uri);
-        try {
-            AssetFileDescriptor afd;
-            // Try requested Uri locally first
-            if (ContentResolver.SCHEME_CONTENT.equals(scheme) && ringToneType != -1) {
-                afd = RingtoneManager.openDefaultRingtoneUri(context, uri);
-                if (attemptDataSource(isCurrent, srcId, afd, startPos, endPos)) {
-                    return;
-                }
-                final Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(
-                        context, ringToneType);
-                afd = resolver.openAssetFileDescriptor(actualUri, "r");
-            } else {
-                afd = resolver.openAssetFileDescriptor(uri, "r");
-            }
-            if (attemptDataSource(isCurrent, srcId, afd, startPos, endPos)) {
-                return;
-            }
-        } catch (NullPointerException | SecurityException | IOException ex) {
-            Log.w(TAG, "Couldn't open " + uri == null ? "null uri" : uri.toSafeString(), ex);
-            // Fallback to media server
-        }
-        handleDataSource(isCurrent, srcId, uri.toString(), headers, cookies, startPos, endPos);
-    }
-
-    private boolean attemptDataSource(boolean isCurrent, long srcId, AssetFileDescriptor afd,
-            long startPos, long endPos) throws IOException {
-        try {
-            if (afd.getDeclaredLength() < 0) {
-                handleDataSource(isCurrent,
-                        srcId,
-                        ParcelFileDescriptor.dup(afd.getFileDescriptor()),
-                        0,
-                        DataSourceDesc.LONG_MAX,
-                        startPos,
-                        endPos);
-            } else {
-                handleDataSource(isCurrent,
-                        srcId,
-                        ParcelFileDescriptor.dup(afd.getFileDescriptor()),
-                        afd.getStartOffset(),
-                        afd.getDeclaredLength(),
-                        startPos,
-                        endPos);
-            }
-            return true;
-        } catch (NullPointerException | SecurityException | IOException ex) {
-            Log.w(TAG, "Couldn't open srcId:" + srcId + ": " + ex);
-            return false;
-        } finally {
-            if (afd != null) {
-                afd.close();
-            }
-        }
-    }
-
-    private void handleDataSource(
-            boolean isCurrent, long srcId,
-            String path, Map<String, String> headers, List<HttpCookie> cookies,
-            long startPos, long endPos)
-            throws IOException {
-        String[] keys = null;
-        String[] values = null;
-
-        if (headers != null) {
-            keys = new String[headers.size()];
-            values = new String[headers.size()];
-
-            int i = 0;
-            for (Map.Entry<String, String> entry: headers.entrySet()) {
-                keys[i] = entry.getKey();
-                values[i] = entry.getValue();
-                ++i;
-            }
-        }
-        handleDataSource(isCurrent, srcId, path, keys, values, cookies, startPos, endPos);
-    }
-
-    private void handleDataSource(boolean isCurrent, long srcId,
-            String path, String[] keys, String[] values, List<HttpCookie> cookies,
-            long startPos, long endPos)
-            throws IOException {
-        final Uri uri = Uri.parse(path);
-        final String scheme = uri.getScheme();
-        if ("file".equals(scheme)) {
-            path = uri.getPath();
-        } else if (scheme != null) {
-            // handle non-file sources
-            Media2Utils.storeCookies(cookies);
-            nativeHandleDataSourceUrl(
-                    isCurrent,
-                    srcId,
-                    Media2HTTPService.createHTTPService(path),
-                    path,
-                    keys,
-                    values,
-                    startPos,
-                    endPos);
-            return;
-        }
-
-        final File file = new File(path);
-        if (file.exists()) {
-            FileInputStream is = new FileInputStream(file);
-            FileDescriptor fd = is.getFD();
-            handleDataSource(isCurrent, srcId, ParcelFileDescriptor.dup(fd),
-                    0, DataSourceDesc.LONG_MAX, startPos, endPos);
-            is.close();
-        } else {
-            throw new IOException("handleDataSource failed.");
-        }
-    }
-
-    private native void nativeHandleDataSourceUrl(
-            boolean isCurrent, long srcId,
-            Media2HTTPService httpService, String path, String[] keys, String[] values,
-            long startPos, long endPos)
-            throws IOException;
-
-    /**
-     * Sets the data source (FileDescriptor) to use. The FileDescriptor must be
-     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
-     * to close the file descriptor. It is safe to do so as soon as this call returns.
-     *
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws IllegalArgumentException if fd is not a valid FileDescriptor
-     * @throws IOException if fd can not be read
-     */
-    private void handleDataSource(
-            boolean isCurrent, long srcId,
-            ParcelFileDescriptor pfd, long offset, long length,
-            long startPos, long endPos) throws IOException {
-        nativeHandleDataSourceFD(isCurrent, srcId, pfd.getFileDescriptor(), offset, length,
-                startPos, endPos);
-    }
-
-    private native void nativeHandleDataSourceFD(boolean isCurrent, long srcId,
-            FileDescriptor fd, long offset, long length,
-            long startPos, long endPos) throws IOException;
-
-    /**
-     * @throws IllegalStateException if it is called in an invalid state
-     * @throws IllegalArgumentException if dataSource is not a valid DataSourceCallback
-     */
-    private void handleDataSource(boolean isCurrent, long srcId, DataSourceCallback dataSource,
-            long startPos, long endPos) {
-        nativeHandleDataSourceCallback(isCurrent, srcId, dataSource, startPos, endPos);
-    }
-
-    private native void nativeHandleDataSourceCallback(
-            boolean isCurrent, long srcId, DataSourceCallback dataSource,
-            long startPos, long endPos);
-
-    // return true if there is a next data source, false otherwise.
-    // This function should be always called on |mHandlerThread|.
-    private boolean prepareNextDataSource() {
-        HandlerThread handlerThread = mHandlerThread;
-        if (handlerThread != null && Looper.myLooper() != handlerThread.getLooper()) {
-            Log.e(TAG, "prepareNextDataSource: called on wrong looper");
-        }
-
-        boolean hasNextDSD;
-        int state = getState();
-        synchronized (mSrcLock) {
-            hasNextDSD = !mNextSourceInfos.isEmpty();
-            if (state == PLAYER_STATE_ERROR || state == PLAYER_STATE_IDLE) {
-                // Current source has not been prepared yet.
-                return hasNextDSD;
-            }
-
-            SourceInfo nextSource = mNextSourceInfos.peek();
-            if (!hasNextDSD || nextSource.mStateAsNextSource != NEXT_SOURCE_STATE_INIT) {
-                // There is no next source or it's in preparing or prepared state.
-                return hasNextDSD;
-            }
-
-            try {
-                nextSource.mStateAsNextSource = NEXT_SOURCE_STATE_PREPARING;
-                handleDataSource(false /* isCurrent */, nextSource.mDSD, nextSource.mId);
-            } catch (Exception e) {
-                Message msg = mTaskHandler.obtainMessage(
-                        MEDIA_ERROR, MEDIA_ERROR_IO, MEDIA_ERROR_UNKNOWN, null);
-                mTaskHandler.handleMessage(msg, nextSource.mId);
-
-                SourceInfo nextSourceInfo = mNextSourceInfos.poll();
-                if (nextSource != null) {
-                    nextSourceInfo.close();
-                }
-                return prepareNextDataSource();
-            }
-        }
-        return hasNextDSD;
-    }
-
-    // This function should be always called on |mHandlerThread|.
-    private void playNextDataSource() {
-        HandlerThread handlerThread = mHandlerThread;
-        if (handlerThread != null && Looper.myLooper() != handlerThread.getLooper()) {
-            Log.e(TAG, "playNextDataSource: called on wrong looper");
-        }
-
-        boolean hasNextDSD = false;
-        synchronized (mSrcLock) {
-            if (!mNextSourceInfos.isEmpty()) {
-                hasNextDSD = true;
-                SourceInfo nextSourceInfo = mNextSourceInfos.peek();
-                if (nextSourceInfo.mStateAsNextSource == NEXT_SOURCE_STATE_PREPARED) {
-                    // Switch to next source only when it has been prepared.
-                    setCurrentSourceInfo_l(mNextSourceInfos.poll());
-
-                    long srcId = mCurrentSourceInfo.mId;
-                    try {
-                        nativePlayNextDataSource(srcId);
-                    } catch (Exception e) {
-                        Message msg2 = mTaskHandler.obtainMessage(
-                                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
-                        mTaskHandler.handleMessage(msg2, srcId);
-                        // Keep |mNextSourcePlayPending|
-                        hasNextDSD = prepareNextDataSource();
-                    }
-                    if (hasNextDSD) {
-                        stayAwake(true);
-
-                        // Now a new current src is playing.
-                        // Wait for MEDIA_INFO_DATA_SOURCE_START to prepare next source.
-                    }
-                } else if (nextSourceInfo.mStateAsNextSource == NEXT_SOURCE_STATE_INIT) {
-                    hasNextDSD = prepareNextDataSource();
-                }
-            }
-        }
-
-        if (!hasNextDSD) {
-            sendEvent(new EventNotifier() {
-                @Override
-                public void notify(EventCallback callback) {
-                    callback.onInfo(
-                            MediaPlayer2.this, null, MEDIA_INFO_DATA_SOURCE_LIST_END, 0);
-                }
-            });
-        }
-    }
-
-    private native void nativePlayNextDataSource(long srcId);
-
-    /**
-     * Configures the player to loop on the current data source.
-     * @param loop true if the current data source is meant to loop.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object loopCurrent(boolean loop) {
-        return addTask(new Task(CALL_COMPLETED_LOOP_CURRENT, false) {
-            @Override
-            void process() {
-                setLooping(loop);
-            }
-        });
-    }
-
-    private native void setLooping(boolean looping);
-
-    /**
-     * Sets the volume of the audio of the media to play, expressed as a linear multiplier
-     * on the audio samples.
-     * Note that this volume is specific to the player, and is separate from stream volume
-     * used across the platform.<br>
-     * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
-     * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
-     * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setPlayerVolume(float volume) {
-        return addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
-            @Override
-            void process() {
-                mVolume = volume;
-                native_setVolume(volume);
-            }
-        });
-    }
-
-    private native void native_setVolume(float volume);
-
-    /**
-     * Returns the current volume of this player.
-     * Note that it does not take into account the associated stream volume.
-     * @return the player volume.
-     */
-    public float getPlayerVolume() {
-        return mVolume;
-    }
-
-    /**
-     * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
-     */
-    public float getMaxPlayerVolume() {
-        return 1.0f;
-    }
-
-    /**
-     * Insert a task in the command queue to help the client to identify whether a batch
-     * of commands has been finished. When this command is processed, a notification
-     * {@link EventCallback#onCommandLabelReached onCommandLabelReached} will be fired with the
-     * given {@code label}.
-     *
-     * @see EventCallback#onCommandLabelReached
-     *
-     * @param label An application specific Object used to help to identify the completeness
-     * of a batch of commands.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object notifyWhenCommandLabelReached(@NonNull Object label) {
-        return addTask(new Task(CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED, false) {
-            @Override
-            void process() {
-                sendEvent(new EventNotifier() {
-                    @Override
-                    public void notify(EventCallback callback) {
-                        callback.onCommandLabelReached(
-                                MediaPlayer2.this, label);
-                    }
-                });
-            }
-        });
-    }
-
-    /**
-     * Sets the {@link SurfaceHolder} to use for displaying the video
-     * portion of the media.
-     *
-     * Either a surface holder or surface must be set if a display or video sink
-     * is needed. Not calling this method or {@link #setSurface(Surface)}
-     * when playing back a video will result in only the audio track being played.
-     * A null surface holder or surface will result in only the audio track being
-     * played.
-     *
-     * @param sh the SurfaceHolder to use for video display
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    public @NonNull Object setDisplay(@Nullable SurfaceHolder sh) {
-        return addTask(new Task(CALL_COMPLETED_SET_DISPLAY, false) {
-            @Override
-            void process() {
-                mSurfaceHolder = sh;
-                Surface surface;
-                if (sh != null) {
-                    surface = sh.getSurface();
-                } else {
-                    surface = null;
-                }
-                native_setVideoSurface(surface);
-                updateSurfaceScreenOn();
-            }
-        });
-    }
-
-    /**
-     * Sets the {@link Surface} to be used as the sink for the video portion of
-     * the media.  Setting a
-     * Surface will un-set any Surface or SurfaceHolder that was previously set.
-     * A null surface will result in only the audio track being played.
-     *
-     * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
-     * returned from {@link SurfaceTexture#getTimestamp()} will have an
-     * unspecified zero point.  These timestamps cannot be directly compared
-     * between different media sources, different instances of the same media
-     * source, or multiple runs of the same program.  The timestamp is normally
-     * monotonically increasing and is unaffected by time-of-day adjustments,
-     * but it is reset when the position is set.
-     *
-     * @param surface The {@link Surface} to be used for the video portion of
-     * the media.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setSurface(@Nullable Surface surface) {
-        return addTask(new Task(CALL_COMPLETED_SET_SURFACE, false) {
-            @Override
-            void process() {
-                if (mScreenOnWhilePlaying && surface != null) {
-                    Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface");
-                }
-                mSurfaceHolder = null;
-                native_setVideoSurface(surface);
-                updateSurfaceScreenOn();
-            }
-        });
-    }
-
-    private native void native_setVideoSurface(Surface surface);
-
-    /**
-     * Set the low-level power management behavior for this MediaPlayer2. This
-     * can be used when the MediaPlayer2 is not playing through a SurfaceHolder
-     * set with {@link #setDisplay(SurfaceHolder)} and thus can use the
-     * high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
-     *
-     * <p>This function has the MediaPlayer2 access the low-level power manager
-     * service to control the device's power usage while playing is occurring.
-     * The parameter is a {@link android.os.PowerManager.WakeLock}.
-     * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
-     * permission.
-     * By default, no attempt is made to keep the device awake during playback.
-     *
-     * @param wakeLock the power wake lock used during playback.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     * @see android.os.PowerManager
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setWakeLock(@NonNull PowerManager.WakeLock wakeLock) {
-        return addTask(new Task(CALL_COMPLETED_SET_WAKE_LOCK, false) {
-            @Override
-            void process() {
-                boolean wasHeld = false;
-
-                if (mWakeLock != null) {
-                    if (mWakeLock.isHeld()) {
-                        wasHeld = true;
-                        mWakeLock.release();
-                    }
-                }
-
-                mWakeLock = wakeLock;
-                if (mWakeLock != null) {
-                    mWakeLock.setReferenceCounted(false);
-                    if (wasHeld) {
-                        mWakeLock.acquire();
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * Control whether we should use the attached SurfaceHolder to keep the
-     * screen on while video playback is occurring.  This is the preferred
-     * method over {@link #setWakeLock} where possible, since it doesn't
-     * require that the application have permission for low-level wake lock
-     * access.
-     *
-     * @param screenOn Supply true to keep the screen on, false to allow it to turn off.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setScreenOnWhilePlaying(boolean screenOn) {
-        return addTask(new Task(CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING, false) {
-            @Override
-            void process() {
-                if (mScreenOnWhilePlaying != screenOn) {
-                    if (screenOn && mSurfaceHolder == null) {
-                        Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective"
-                                + " without a SurfaceHolder");
-                    }
-                    mScreenOnWhilePlaying = screenOn;
-                    updateSurfaceScreenOn();
-                }
-            }
-        });
-    }
-
-    private void stayAwake(boolean awake) {
-        if (mWakeLock != null) {
-            if (awake && !mWakeLock.isHeld()) {
-                mWakeLock.acquire();
-            } else if (!awake && mWakeLock.isHeld()) {
-                mWakeLock.release();
-            }
-        }
-        mStayAwake = awake;
-        updateSurfaceScreenOn();
-    }
-
-    private void updateSurfaceScreenOn() {
-        if (mSurfaceHolder != null) {
-            mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
-        }
-    }
-
-    /**
-     * Cancels a pending command.
-     *
-     * @param token the command to be canceled. This is the returned Object when command is issued.
-     * @return {@code false} if the task could not be cancelled; {@code true} otherwise.
-     * @throws IllegalArgumentException if argument token is null.
-     */
-    // This is a synchronous call.
-    public boolean cancelCommand(@NonNull Object token) {
-        if (token == null) {
-            throw new IllegalArgumentException("command token should not be null");
-        }
-        synchronized (mTaskLock) {
-            return mPendingTasks.remove(token);
-        }
-    }
-
-    /**
-     * Discards all pending commands.
-     */
-    // This is a synchronous call.
-    public void clearPendingCommands() {
-        synchronized (mTaskLock) {
-            mPendingTasks.clear();
-        }
-    }
-
-    //--------------------------------------------------------------------------
-    // Explicit Routing
-    //--------------------
-    private AudioDeviceInfo mPreferredDevice = null;
-
-    /**
-     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
-     * the output from this MediaPlayer2.
-     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
-     *  If deviceInfo is null, default routing is restored.
-     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
-     * does not correspond to a valid audio device.
-     */
-    // This is a synchronous call.
-    @Override
-    public boolean setPreferredDevice(@Nullable AudioDeviceInfo deviceInfo) {
-        boolean status = native_setPreferredDevice(deviceInfo);
-        if (status) {
-            synchronized (this) {
-                mPreferredDevice = deviceInfo;
-            }
-        }
-        return status;
-    }
-
-    private native boolean native_setPreferredDevice(AudioDeviceInfo device);
-
-    /**
-     * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
-     * is not guaranteed to correspond to the actual device being used for playback.
-     */
-    @Override
-    public @Nullable AudioDeviceInfo getPreferredDevice() {
-        synchronized (this) {
-            return mPreferredDevice;
-        }
-    }
-
-    /**
-     * Returns an {@link AudioDeviceInfo} identifying the current routing of this MediaPlayer2
-     * Note: The query is only valid if the MediaPlayer2 is currently playing.
-     * If the player is not playing, the returned device can be null or correspond to previously
-     * selected device when the player was last active.
-     */
-    @Override
-    public @Nullable native AudioDeviceInfo getRoutedDevice();
-
-    /**
-     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
-     * changes on this MediaPlayer2.
-     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
-     * notifications of rerouting events.
-     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
-     * the callback. If <code>null</code>, the handler on the main looper will be used.
-     */
-    // This is a synchronous call.
-    @Override
-    public void addOnRoutingChangedListener(@NonNull AudioRouting.OnRoutingChangedListener listener,
-            @Nullable Handler handler) {
-        if (listener == null) {
-            throw new IllegalArgumentException("addOnRoutingChangedListener: listener is NULL");
-        }
-        RoutingDelegate routingDelegate = new RoutingDelegate(this, listener, handler);
-        native_addDeviceCallback(routingDelegate);
-    }
-
-    private native void native_addDeviceCallback(RoutingDelegate rd);
-
-    /**
-     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
-     * to receive rerouting notifications.
-     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
-     * to remove.
-     */
-    // This is a synchronous call.
-    @Override
-    public void removeOnRoutingChangedListener(
-            @NonNull AudioRouting.OnRoutingChangedListener listener) {
-        if (listener == null) {
-            throw new IllegalArgumentException("removeOnRoutingChangedListener: listener is NULL");
-        }
-        native_removeDeviceCallback(listener);
-    }
-
-    private native void native_removeDeviceCallback(
-            AudioRouting.OnRoutingChangedListener listener);
-
-    /**
-     * Returns the size of the video.
-     *
-     * @return the size of the video. The width and height of size could be 0 if there is no video,
-     * or the size has not been determined yet.
-     * The {@code EventCallback} can be registered via
-     * {@link #registerEventCallback(Executor, EventCallback)} to provide a
-     * notification {@code EventCallback.onVideoSizeChanged} when the size
-     * is available.
-     */
-    public @NonNull Size getVideoSize() {
-        return mVideoSize;
-    }
-
-    /**
-     * Return Metrics data about the current player.
-     *
-     * @return a {@link PersistableBundle} containing the set of attributes and values
-     * available for the media being handled by this instance of MediaPlayer2
-     * The attributes are descibed in {@link MetricsConstants}.
-     *
-     * Additional vendor-specific fields may also be present in the return value.
-     */
-    public @Nullable PersistableBundle getMetrics() {
-        PersistableBundle bundle = native_getMetrics();
-        return bundle;
-    }
-
-    private native PersistableBundle native_getMetrics();
-
-    /**
-     * Gets the current buffering management params used by the source component.
-     * Calling it only after {@code setDataSource} has been called.
-     * Each type of data source might have different set of default params.
-     *
-     * @return the current buffering management params used by the source component.
-     * @throws IllegalStateException if the internal player engine has not been
-     * initialized, or {@code setDataSource} has not been called.
-     */
-    // TODO: make it public when ready
-    @NonNull
-    native BufferingParams getBufferingParams();
-
-    /**
-     * Sets buffering management params.
-     * The object sets its internal BufferingParams to the input, except that the input is
-     * invalid or not supported.
-     * Call it only after {@code setDataSource} has been called.
-     * The input is a hint to MediaPlayer2.
-     *
-     * @param params the buffering management params.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // TODO: make it public when ready
-    // This is an asynchronous call.
-    @NonNull Object setBufferingParams(@NonNull BufferingParams params) {
-        return addTask(new Task(CALL_COMPLETED_SET_BUFFERING_PARAMS, false) {
-            @Override
-            void process() {
-                Media2Utils.checkArgument(params != null, "the BufferingParams cannot be null");
-                native_setBufferingParams(params);
-            }
-        });
-    }
-
-    private native void native_setBufferingParams(@NonNull BufferingParams params);
-
-    /**
-     * Sets playback rate using {@link PlaybackParams}. The object sets its internal
-     * PlaybackParams to the input. This allows the object to resume at previous speed
-     * when play() is called. Speed of zero is not allowed. Calling it does not change
-     * the object state.
-     *
-     * @param params the playback params.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setPlaybackParams(@NonNull PlaybackParams params) {
-        return addTask(new Task(CALL_COMPLETED_SET_PLAYBACK_PARAMS, false) {
-            @Override
-            void process() {
-                Media2Utils.checkArgument(params != null, "the PlaybackParams cannot be null");
-                native_setPlaybackParams(params);
-            }
-        });
-    }
-
-    private native void native_setPlaybackParams(@NonNull PlaybackParams params);
-
-    /**
-     * Gets the playback params, containing the current playback rate.
-     *
-     * @return the playback params.
-     * @throws IllegalStateException if the internal player engine has not been initialized.
-     */
-    @NonNull
-    public native PlaybackParams getPlaybackParams();
-
-    /**
-     * Sets A/V sync mode.
-     *
-     * @param params the A/V sync params to apply
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setSyncParams(@NonNull SyncParams params) {
-        return addTask(new Task(CALL_COMPLETED_SET_SYNC_PARAMS, false) {
-            @Override
-            void process() {
-                Media2Utils.checkArgument(params != null, "the SyncParams cannot be null");
-                native_setSyncParams(params);
-            }
-        });
-    }
-
-    private native void native_setSyncParams(@NonNull SyncParams params);
-
-    /**
-     * Gets the A/V sync mode.
-     *
-     * @return the A/V sync params
-     * @throws IllegalStateException if the internal player engine has not been initialized.
-     */
-    @NonNull
-    public native SyncParams getSyncParams();
-
-    /**
-     * Moves the media to specified time position.
-     * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
-     *
-     * @param msec the offset in milliseconds from the start to seek to
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object seekTo(long msec) {
-        return seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
-    }
-
-    /**
-     * Seek modes used in method seekTo(long, int) to move media position
-     * to a specified location.
-     *
-     * Do not change these mode values without updating their counterparts
-     * in include/media/IMediaSource.h!
-     */
-    /**
-     * This mode is used with {@link #seekTo(long, int)} to move media position to
-     * a sync (or key) frame associated with a data source that is located
-     * right before or at the given time.
-     *
-     * @see #seekTo(long, int)
-     */
-    public static final int SEEK_PREVIOUS_SYNC    = 0x00;
-    /**
-     * This mode is used with {@link #seekTo(long, int)} to move media position to
-     * a sync (or key) frame associated with a data source that is located
-     * right after or at the given time.
-     *
-     * @see #seekTo(long, int)
-     */
-    public static final int SEEK_NEXT_SYNC        = 0x01;
-    /**
-     * This mode is used with {@link #seekTo(long, int)} to move media position to
-     * a sync (or key) frame associated with a data source that is located
-     * closest to (in time) or at the given time.
-     *
-     * @see #seekTo(long, int)
-     */
-    public static final int SEEK_CLOSEST_SYNC     = 0x02;
-    /**
-     * This mode is used with {@link #seekTo(long, int)} to move media position to
-     * a frame (not necessarily a key frame) associated with a data source that
-     * is located closest to or at the given time.
-     *
-     * @see #seekTo(long, int)
-     */
-    public static final int SEEK_CLOSEST          = 0x03;
-
-    /** @hide */
-    @IntDef(flag = false, prefix = "SEEK", value = {
-            SEEK_PREVIOUS_SYNC,
-            SEEK_NEXT_SYNC,
-            SEEK_CLOSEST_SYNC,
-            SEEK_CLOSEST,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SeekMode {}
-
-    /**
-     * Moves the media to specified time position by considering the given mode.
-     * <p>
-     * When seekTo is finished, the user will be notified via
-     * {@link EventCallback#onCallCompleted} with {@link #CALL_COMPLETED_SEEK_TO}.
-     * There is at most one active seekTo processed at any time. If there is a to-be-completed
-     * seekTo, new seekTo requests will be queued in such a way that only the last request
-     * is kept. When current seekTo is completed, the queued request will be processed if
-     * that request is different from just-finished seekTo operation, i.e., the requested
-     * position or mode is different.
-     *
-     * @param msec the offset in milliseconds from the start to seek to.
-     * When seeking to the given time position, there is no guarantee that the data source
-     * has a frame located at the position. When this happens, a frame nearby will be rendered.
-     * If msec is negative, time position zero will be used.
-     * If msec is larger than duration, duration will be used.
-     * @param mode the mode indicating where exactly to seek to.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object seekTo(long msec, @SeekMode int mode) {
-        return addTask(new Task(CALL_COMPLETED_SEEK_TO, true) {
-            @Override
-            void process() {
-                if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
-                    final String msg = "Illegal seek mode: " + mode;
-                    throw new IllegalArgumentException(msg);
-                }
-                // TODO: pass long to native, instead of truncating here.
-                long posMs = msec;
-                if (posMs > Integer.MAX_VALUE) {
-                    Log.w(TAG, "seekTo offset " + posMs + " is too large, cap to "
-                            + Integer.MAX_VALUE);
-                    posMs = Integer.MAX_VALUE;
-                } else if (posMs < Integer.MIN_VALUE) {
-                    Log.w(TAG, "seekTo offset " + posMs + " is too small, cap to "
-                            + Integer.MIN_VALUE);
-                    posMs = Integer.MIN_VALUE;
-                }
-
-                synchronized (mTaskLock) {
-                    if (mIsPreviousCommandSeekTo
-                            && mPreviousSeekPos == posMs
-                            && mPreviousSeekMode == mode) {
-                        throw new CommandSkippedException(
-                                "same as previous seekTo");
-                    }
-                }
-
-                native_seekTo(posMs, mode);
-
-                synchronized (mTaskLock) {
-                    mIsPreviousCommandSeekTo = true;
-                    mPreviousSeekPos = posMs;
-                    mPreviousSeekMode = mode;
-                }
-            }
-        });
-    }
-
-    private native void native_seekTo(long msec, int mode);
-
-    /**
-     * Get current playback position as a {@link MediaTimestamp}.
-     * <p>
-     * The MediaTimestamp represents how the media time correlates to the system time in
-     * a linear fashion using an anchor and a clock rate. During regular playback, the media
-     * time moves fairly constantly (though the anchor frame may be rebased to a current
-     * system time, the linear correlation stays steady). Therefore, this method does not
-     * need to be called often.
-     * <p>
-     * To help users get current playback position, this method always anchors the timestamp
-     * to the current {@link System#nanoTime system time}, so
-     * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
-     *
-     * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
-     *         is available, e.g. because the media player has not been initialized.
-     *
-     * @see MediaTimestamp
-     */
-    @Nullable
-    public MediaTimestamp getTimestamp() {
-        try {
-            // TODO: get the timestamp from native side
-            return new MediaTimestamp(
-                    getCurrentPosition() * 1000L,
-                    System.nanoTime(),
-                    getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f);
-        } catch (IllegalStateException e) {
-            return null;
-        }
-    }
-
-    /**
-     * Checks whether the MediaPlayer2 is looping or non-looping.
-     *
-     * @return true if the MediaPlayer2 is currently looping, false otherwise
-     */
-    // This is a synchronous call.
-    public native boolean isLooping();
-
-    /**
-     * Sets the audio session ID.
-     *
-     * @param sessionId the audio session ID.
-     * The audio session ID is a system wide unique identifier for the audio stream played by
-     * this MediaPlayer2 instance.
-     * The primary use of the audio session ID  is to associate audio effects to a particular
-     * instance of MediaPlayer2: if an audio session ID is provided when creating an audio effect,
-     * this effect will be applied only to the audio content of media players within the same
-     * audio session and not to the output mix.
-     * When created, a MediaPlayer2 instance automatically generates its own audio session ID.
-     * However, it is possible to force this player to be part of an already existing audio session
-     * by calling this method.
-     * This method must be called when player is in {@link #PLAYER_STATE_IDLE} or
-     * {@link #PLAYER_STATE_PREPARED} state in order to have sessionId take effect.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setAudioSessionId(int sessionId) {
-        final AudioTrack dummyAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
-                    AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 2,
-                    AudioTrack.MODE_STATIC, sessionId);
-        return addTask(new Task(CALL_COMPLETED_SET_AUDIO_SESSION_ID, false) {
-            @Override
-            void process() {
-                keepAudioSessionIdAlive(dummyAudioTrack);
-                native_setAudioSessionId(sessionId);
-            }
-        });
-    }
-
-    private native void native_setAudioSessionId(int sessionId);
-
-    /**
-     * Returns the audio session ID.
-     *
-     * @return the audio session ID. {@see #setAudioSessionId(int)}
-     * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer2 was
-     * contructed.
-     */
-    // This is a synchronous call.
-    public native int getAudioSessionId();
-
-    /**
-     * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
-     * effect which can be applied on any sound source that directs a certain amount of its
-     * energy to this effect. This amount is defined by setAuxEffectSendLevel().
-     * See {@link #setAuxEffectSendLevel(float)}.
-     * <p>After creating an auxiliary effect (e.g.
-     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
-     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method
-     * to attach the player to the effect.
-     * <p>To detach the effect from the player, call this method with a null effect id.
-     * <p>This method must be called after one of the overloaded <code> setDataSource </code>
-     * methods.
-     * @param effectId system wide unique id of the effect to attach
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object attachAuxEffect(int effectId) {
-        return addTask(new Task(CALL_COMPLETED_ATTACH_AUX_EFFECT, false) {
-            @Override
-            void process() {
-                native_attachAuxEffect(effectId);
-            }
-        });
-    }
-
-    private native void native_attachAuxEffect(int effectId);
-
-    /**
-     * Sets the send level of the player to the attached auxiliary effect.
-     * See {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
-     * <p>By default the send level is 0, so even if an effect is attached to the player
-     * this method must be called for the effect to be applied.
-     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
-     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
-     * so an appropriate conversion from linear UI input x to level is:
-     * x == 0 -> level = 0
-     * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
-     * @param level send level scalar
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     */
-    // This is an asynchronous call.
-    public @NonNull Object setAuxEffectSendLevel(float level) {
-        return addTask(new Task(CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL, false) {
-            @Override
-            void process() {
-                native_setAuxEffectSendLevel(level);
-            }
-        });
-    }
-
-    private native void native_setAuxEffectSendLevel(float level);
-
-    private static native void native_stream_event_onTearDown(
-            long nativeCallbackPtr, long userDataPtr);
-    private static native void native_stream_event_onStreamPresentationEnd(
-            long nativeCallbackPtr, long userDataPtr);
-    private static native void native_stream_event_onStreamDataRequest(
-            long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr);
-
-    /* Do not change these values (starting with INVOKE_ID) without updating
-     * their counterparts in include/media/mediaplayer2.h!
-     */
-    private static final int INVOKE_ID_GET_TRACK_INFO = 1;
-    private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE = 2;
-    private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3;
-    private static final int INVOKE_ID_SELECT_TRACK = 4;
-    private static final int INVOKE_ID_DESELECT_TRACK = 5;
-    private static final int INVOKE_ID_GET_SELECTED_TRACK = 7;
-
-    /**
-     * Invoke a generic method on the native player using opaque protocol
-     * buffer message for the request and reply. Both payloads' format is a
-     * convention between the java caller and the native player.
-     *
-     * @param msg PlayerMessage for the extension.
-     *
-     * @return PlayerMessage with the data returned by the
-     * native player.
-     */
-    private PlayerMessage invoke(PlayerMessage msg) {
-        byte[] ret = native_invoke(msg.toByteArray());
-        if (ret == null) {
-            return null;
-        }
-        try {
-            return PlayerMessage.parseFrom(ret);
-        } catch (InvalidProtocolBufferException e) {
-            return null;
-        }
-    }
-
-    private native byte[] native_invoke(byte[] request);
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "MEDIA_TRACK_TYPE", value = {
-            TrackInfo.MEDIA_TRACK_TYPE_VIDEO,
-            TrackInfo.MEDIA_TRACK_TYPE_AUDIO,
-            TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface TrackType {}
-
-    /**
-     * Class for MediaPlayer2 to return each audio/video/subtitle track's metadata.
-     *
-     * @see MediaPlayer2#getTrackInfo
-     */
-    public static class TrackInfo {
-        /**
-         * Gets the track type.
-         * @return TrackType which indicates if the track is video, audio, timed text.
-         */
-        public int getTrackType() {
-            return mTrackType;
-        }
-
-        /**
-         * Gets the language code of the track.
-         * @return a language code in either way of ISO-639-1 or ISO-639-2.
-         * When the language is unknown or could not be determined,
-         * ISO-639-2 language code, "und", is returned.
-         */
-        public @NonNull String getLanguage() {
-            String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
-            return language == null ? "und" : language;
-        }
-
-        /**
-         * Gets the {@link MediaFormat} of the track.  If the format is
-         * unknown or could not be determined, null is returned.
-         */
-        public @Nullable MediaFormat getFormat() {
-            if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
-                    || mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-                return mFormat;
-            }
-            return null;
-        }
-
-        public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0;
-        public static final int MEDIA_TRACK_TYPE_VIDEO = 1;
-        public static final int MEDIA_TRACK_TYPE_AUDIO = 2;
-
-        /** @hide */
-        public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
-
-        public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
-        public static final int MEDIA_TRACK_TYPE_METADATA = 5;
-
-        final int mId;
-        final int mTrackType;
-        final MediaFormat mFormat;
-
-        static TrackInfo create(int idx, Iterator<Value> in) {
-            int trackType = in.next().getInt32Value();
-            // TODO: build the full MediaFormat; currently we are using createSubtitleFormat
-            // even for audio/video tracks, meaning we only set the mime and language.
-            String mime = in.next().getStringValue();
-            String language = in.next().getStringValue();
-            MediaFormat format = MediaFormat.createSubtitleFormat(mime, language);
-
-            if (trackType == MEDIA_TRACK_TYPE_SUBTITLE) {
-                format.setInteger(MediaFormat.KEY_IS_AUTOSELECT, in.next().getInt32Value());
-                format.setInteger(MediaFormat.KEY_IS_DEFAULT, in.next().getInt32Value());
-                format.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.next().getInt32Value());
-            }
-            return new TrackInfo(idx, trackType, format);
-        }
-
-        /** @hide */
-        TrackInfo(int id, int type, MediaFormat format) {
-            mId = id;
-            mTrackType = type;
-            mFormat = format;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder out = new StringBuilder(128);
-            out.append(getClass().getName());
-            out.append('{');
-            switch (mTrackType) {
-                case MEDIA_TRACK_TYPE_VIDEO:
-                    out.append("VIDEO");
-                    break;
-                case MEDIA_TRACK_TYPE_AUDIO:
-                    out.append("AUDIO");
-                    break;
-                case MEDIA_TRACK_TYPE_TIMEDTEXT:
-                    out.append("TIMEDTEXT");
-                    break;
-                case MEDIA_TRACK_TYPE_SUBTITLE:
-                    out.append("SUBTITLE");
-                    break;
-                default:
-                    out.append("UNKNOWN");
-                    break;
-            }
-            out.append(", " + mFormat.toString());
-            out.append("}");
-            return out.toString();
-        }
-    };
-
-    /**
-     * Returns a List of track information of current data source.
-     * Same as {@link #getTrackInfo(DataSourceDesc)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @return List of track info. The total number of tracks is the array length.
-     * Must be called again if an external timed text source has been added after
-     * addTimedTextSource method is called.
-     * @throws IllegalStateException if it is called in an invalid state.
-     * @throws NullPointerException if current data source is null
-     */
-    public @NonNull List<TrackInfo> getTrackInfo() {
-        return getTrackInfo(getCurrentDataSource());
-    }
-
-    /**
-     * Returns a List of track information.
-     *
-     * @param dsd the descriptor of data source of which you want to get track info
-     * @return List of track info. The total number of tracks is the array length.
-     * Must be called again if an external timed text source has been added after
-     * addTimedTextSource method is called.
-     * @throws IllegalStateException if it is called in an invalid state.
-     * @throws NullPointerException if dsd is null
-     */
-    public @NonNull List<TrackInfo> getTrackInfo(@NonNull DataSourceDesc dsd) {
-        if (dsd == null) {
-            throw new NullPointerException("non-null dsd is expected");
-        }
-        SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo == null) {
-            return new ArrayList<TrackInfo>(0);
-        }
-
-        TrackInfo[] trackInfo = getInbandTrackInfo(sourceInfo);
-        return (trackInfo != null ? Arrays.asList(trackInfo) : new ArrayList<TrackInfo>(0));
-    }
-
-    private TrackInfo[] getInbandTrackInfo(SourceInfo sourceInfo) throws IllegalStateException {
-        PlayerMessage request = PlayerMessage.newBuilder()
-                .addValues(Value.newBuilder().setInt32Value(INVOKE_ID_GET_TRACK_INFO))
-                .addValues(Value.newBuilder().setInt64Value(sourceInfo.mId))
-                .build();
-        PlayerMessage response = invoke(request);
-        if (response == null) {
-            return null;
-        }
-        Iterator<Value> in = response.getValuesList().iterator();
-        int size = in.next().getInt32Value();
-        if (size == 0) {
-            return null;
-        }
-        TrackInfo[] trackInfo = new TrackInfo[size];
-        for (int i = 0; i < size; ++i) {
-            trackInfo[i] = TrackInfo.create(i, in);
-        }
-        return trackInfo;
-    }
-
-    /**
-     * Returns the index of the audio, video, or subtitle track currently selected for playback.
-     * The return value is an index into the array returned by {@link #getTrackInfo}, and can
-     * be used in calls to {@link #selectTrack(TrackInfo)} or {@link #deselectTrack(TrackInfo)}.
-     * Same as {@link #getSelectedTrack(DataSourceDesc, int)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO},
-     * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or
-     * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}
-     * @return metadata corresponding to the audio, video, or subtitle track currently selected for
-     * playback; {@code null} is returned when there is no selected track for {@code trackType} or
-     * when {@code trackType} is not one of audio, video, or subtitle.
-     * @throws IllegalStateException if called after {@link #close()}
-     * @throws NullPointerException if current data source is null
-     *
-     * @see #getTrackInfo()
-     * @see #selectTrack(TrackInfo)
-     * @see #deselectTrack(TrackInfo)
-     */
-    @Nullable
-    public TrackInfo getSelectedTrack(@TrackType int trackType) {
-        return getSelectedTrack(getCurrentDataSource(), trackType);
-    }
-
-    /**
-     * Returns the index of the audio, video, or subtitle track currently selected for playback.
-     * The return value is an index into the array returned by {@link #getTrackInfo}, and can
-     * be used in calls to {@link #selectTrack(DataSourceDesc, TrackInfo)} or
-     * {@link #deselectTrack(DataSourceDesc, TrackInfo)}.
-     *
-     * @param dsd the descriptor of data source of which you want to get selected track
-     * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO},
-     * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or
-     * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}
-     * @return metadata corresponding to the audio, video, or subtitle track currently selected for
-     * playback; {@code null} is returned when there is no selected track for {@code trackType} or
-     * when {@code trackType} is not one of audio, video, or subtitle.
-     * @throws IllegalStateException if called after {@link #close()}
-     * @throws NullPointerException if dsd is null
-     *
-     * @see #getTrackInfo(DataSourceDesc)
-     * @see #selectTrack(DataSourceDesc, TrackInfo)
-     * @see #deselectTrack(DataSourceDesc, TrackInfo)
-     */
-    @Nullable
-    public TrackInfo getSelectedTrack(@NonNull DataSourceDesc dsd, @TrackType int trackType) {
-        if (dsd == null) {
-            throw new NullPointerException("non-null dsd is expected");
-        }
-        SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo == null) {
-            return null;
-        }
-
-        PlayerMessage request = PlayerMessage.newBuilder()
-                .addValues(Value.newBuilder().setInt32Value(INVOKE_ID_GET_SELECTED_TRACK))
-                .addValues(Value.newBuilder().setInt64Value(sourceInfo.mId))
-                .addValues(Value.newBuilder().setInt32Value(trackType))
-                .build();
-        PlayerMessage response = invoke(request);
-        if (response == null) {
-            return null;
-        }
-        // TODO: return full TrackInfo data from native player instead of index
-        final int idx = response.getValues(0).getInt32Value();
-        final List<TrackInfo> trackInfos = getTrackInfo(dsd);
-        return trackInfos.isEmpty() ? null : trackInfos.get(idx);
-    }
-
-    /**
-     * Selects a track of current data source.
-     * Same as {@link #selectTrack(DataSourceDesc, TrackInfo)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo}
-     * object can be obtained from {@link #getTrackInfo()}.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     *
-     * This is an asynchronous call.
-     *
-     * @see MediaPlayer2#getTrackInfo()
-     */
-    @NonNull
-    public Object selectTrack(@NonNull TrackInfo trackInfo) {
-        return selectTrack(getCurrentDataSource(), trackInfo);
-    }
-
-    /**
-     * Selects a track.
-     * <p>
-     * If a MediaPlayer2 is in invalid state, it throws an IllegalStateException exception.
-     * If a MediaPlayer2 is in <em>Started</em> state, the selected track is presented immediately.
-     * If a MediaPlayer2 is not in Started state, it just marks the track to be played.
-     * </p>
-     * <p>
-     * In any valid state, if it is called multiple times on the same type of track (ie. Video,
-     * Audio, Timed Text), the most recent one will be chosen.
-     * </p>
-     * <p>
-     * The first audio and video tracks are selected by default if available, even though
-     * this method is not called. However, no timed text track will be selected until
-     * this function is called.
-     * </p>
-     * <p>
-     * Currently, only timed text tracks or audio tracks can be selected via this method.
-     * In addition, the support for selecting an audio track at runtime is pretty limited
-     * in that an audio track can only be selected in the <em>Prepared</em> state.
-     * </p>
-     * @param dsd the descriptor of data source of which you want to select track
-     * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo}
-     * object can be obtained from {@link #getTrackInfo()}.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     *
-     * This is an asynchronous call.
-     *
-     * @see MediaPlayer2#getTrackInfo(DataSourceDesc)
-     */
-    @NonNull
-    public Object selectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) {
-        return addTask(new Task(CALL_COMPLETED_SELECT_TRACK, false) {
-            @Override
-            void process() {
-                selectOrDeselectTrack(dsd, trackInfo.mId, true /* select */);
-            }
-        });
-    }
-
-    /**
-     * Deselect a track of current data source.
-     * Same as {@link #deselectTrack(DataSourceDesc, TrackInfo)} with
-     * {@code dsd = getCurrentDataSource()}.
-     *
-     * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo}
-     * object can be obtained from {@link #getTrackInfo()}.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     *
-     * This is an asynchronous call.
-     *
-     * @see MediaPlayer2#getTrackInfo()
-     */
-    @NonNull
-    public Object deselectTrack(@NonNull TrackInfo trackInfo) {
-        return deselectTrack(getCurrentDataSource(), trackInfo);
-    }
-
-    /**
-     * Deselect a track.
-     * <p>
-     * Currently, the track must be a timed text track and no audio or video tracks can be
-     * deselected. If the timed text track identified by index has not been
-     * selected before, it throws an exception.
-     * </p>
-     * @param dsd the descriptor of data source of which you want to deselect track
-     * @param trackInfo metadata corresponding to the track to be selected. A {@code trackInfo}
-     * object can be obtained from {@link #getTrackInfo()}.
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     *
-     * This is an asynchronous call.
-     *
-     * @see MediaPlayer2#getTrackInfo(DataSourceDesc)
-     */
-    @NonNull
-    public Object deselectTrack(@NonNull DataSourceDesc dsd, @NonNull TrackInfo trackInfo) {
-        return addTask(new Task(CALL_COMPLETED_DESELECT_TRACK, false) {
-            @Override
-            void process() {
-                selectOrDeselectTrack(dsd, trackInfo.mId, false /* select */);
-            }
-        });
-    }
-
-    private void selectOrDeselectTrack(@NonNull DataSourceDesc dsd, int index, boolean select) {
-        if (dsd == null) {
-            throw new IllegalArgumentException("non-null dsd is expected");
-        }
-        SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo == null) {
-            return;
-        }
-
-        PlayerMessage request = PlayerMessage.newBuilder()
-                .addValues(Value.newBuilder().setInt32Value(
-                            select ? INVOKE_ID_SELECT_TRACK : INVOKE_ID_DESELECT_TRACK))
-                .addValues(Value.newBuilder().setInt64Value(sourceInfo.mId))
-                .addValues(Value.newBuilder().setInt32Value(index))
-                .build();
-        invoke(request);
-    }
-
-    /* Do not change these values without updating their counterparts
-     * in include/media/mediaplayer2.h!
-     */
-    private static final int MEDIA_NOP = 0; // interface test message
-    private static final int MEDIA_PREPARED = 1;
-    private static final int MEDIA_PLAYBACK_COMPLETE = 2;
-    private static final int MEDIA_BUFFERING_UPDATE = 3;
-    private static final int MEDIA_SEEK_COMPLETE = 4;
-    private static final int MEDIA_SET_VIDEO_SIZE = 5;
-    private static final int MEDIA_STARTED = 6;
-    private static final int MEDIA_PAUSED = 7;
-    private static final int MEDIA_STOPPED = 8;
-    private static final int MEDIA_SKIPPED = 9;
-    private static final int MEDIA_DRM_PREPARED = 10;
-    private static final int MEDIA_NOTIFY_TIME = 98;
-    private static final int MEDIA_TIMED_TEXT = 99;
-    private static final int MEDIA_ERROR = 100;
-    private static final int MEDIA_INFO = 200;
-    private static final int MEDIA_SUBTITLE_DATA = 201;
-    private static final int MEDIA_META_DATA = 202;
-    private static final int MEDIA_DRM_INFO = 210;
-
-    private class TaskHandler extends Handler {
-        private MediaPlayer2 mMediaPlayer;
-
-        TaskHandler(MediaPlayer2 mp, Looper looper) {
-            super(looper);
-            mMediaPlayer = mp;
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            handleMessage(msg, 0);
-        }
-
-        public void handleMessage(Message msg, long srcId) {
-            if (mMediaPlayer.mNativeContext == 0) {
-                Log.w(TAG, "mediaplayer2 went away with unhandled events");
-                return;
-            }
-            final int what = msg.arg1;
-            final int extra = msg.arg2;
-
-            final SourceInfo sourceInfo = getSourceInfo(srcId);
-            if (sourceInfo == null) {
-                return;
-            }
-            final DataSourceDesc dsd = sourceInfo.mDSD;
-
-            switch(msg.what) {
-                case MEDIA_PREPARED:
-                case MEDIA_DRM_PREPARED:
-                {
-                    sourceInfo.mPrepareBarrier--;
-                    if (sourceInfo.mPrepareBarrier > 0) {
-                        break;
-                    } else if (sourceInfo.mPrepareBarrier < 0) {
-                        Log.w(TAG, "duplicated (drm) prepared events");
-                        break;
-                    }
-
-                    if (dsd != null) {
-                        sendEvent(new EventNotifier() {
-                            @Override
-                            public void notify(EventCallback callback) {
-                                callback.onInfo(
-                                        mMediaPlayer, dsd, MEDIA_INFO_PREPARED, 0);
-                            }
-                        });
-                    }
-
-                    synchronized (mSrcLock) {
-                        SourceInfo nextSourceInfo = mNextSourceInfos.peek();
-                        Log.i(TAG, "MEDIA_PREPARED: srcId=" + srcId
-                                + ", curSrc=" + mCurrentSourceInfo
-                                + ", nextSrc=" + nextSourceInfo);
-
-                        if (isCurrentSource(srcId)) {
-                            prepareNextDataSource();
-                        } else if (isNextSource(srcId)) {
-                            nextSourceInfo.mStateAsNextSource = NEXT_SOURCE_STATE_PREPARED;
-                            if (nextSourceInfo.mPlayPendingAsNextSource) {
-                                playNextDataSource();
-                            }
-                        }
-                    }
-
-                    synchronized (mTaskLock) {
-                        if (mCurrentTask != null
-                                && mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE
-                                && mCurrentTask.mDSD == dsd
-                                && mCurrentTask.mNeedToWaitForEventToComplete) {
-                            mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
-                            mCurrentTask = null;
-                            processPendingTask_l();
-                        }
-                    }
-                    return;
-                }
-
-                case MEDIA_DRM_INFO:
-                {
-                    if (msg.obj == null) {
-                        Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL");
-                    } else if (msg.obj instanceof byte[]) {
-                        // The PlayerMessage was parsed already in postEventFromNative
-
-                        final DrmInfo drmInfo;
-                        synchronized (sourceInfo) {
-                            if (sourceInfo.mDrmInfo != null) {
-                                drmInfo = sourceInfo.mDrmInfo.makeCopy();
-                            } else {
-                                drmInfo = null;
-                            }
-                        }
-
-                        // notifying the client outside the lock
-                        DrmPreparationInfo drmPrepareInfo = null;
-                        if (drmInfo != null) {
-                            try {
-                                drmPrepareInfo = sendDrmEventWait(
-                                        new DrmEventNotifier<DrmPreparationInfo>() {
-                                            @Override
-                                            public DrmPreparationInfo notifyWait(
-                                                    DrmEventCallback callback) {
-                                                return callback.onDrmInfo(mMediaPlayer, dsd,
-                                                        drmInfo);
-                                            }
-                                        });
-                            } catch (InterruptedException | ExecutionException
-                                    | TimeoutException e) {
-                                Log.w(TAG, "Exception while waiting for DrmPreparationInfo", e);
-                            }
-                        }
-                        if (sourceInfo.mDrmHandle.setPreparationInfo(drmPrepareInfo)) {
-                            sourceInfo.mPrepareBarrier++;
-                            final Task prepareDrmTask;
-                            prepareDrmTask = newPrepareDrmTask(dsd, drmPrepareInfo.mUUID);
-                            mTaskHandler.post(new Runnable() {
-                                @Override
-                                public void run() {
-                                    // Run as simple Runnable, not Task
-                                    try {
-                                        prepareDrmTask.process();
-                                    } catch (NoDrmSchemeException | IOException e) {
-                                        final String errMsg;
-                                        errMsg = "Unexpected Exception during prepareDrm";
-                                        throw new RuntimeException(errMsg, e);
-                                    }
-                                }
-                            });
-                        } else {
-                            Log.w(TAG, "No valid DrmPreparationInfo set");
-                        }
-                    } else {
-                        Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + msg.obj);
-                    }
-                    return;
-                }
-
-                case MEDIA_PLAYBACK_COMPLETE:
-                {
-                    if (isCurrentSource(srcId)) {
-                        sendEvent(new EventNotifier() {
-                            @Override
-                            public void notify(EventCallback callback) {
-                                callback.onInfo(
-                                        mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0);
-                            }
-                        });
-                        stayAwake(false);
-
-                        synchronized (mSrcLock) {
-                            SourceInfo nextSourceInfo = mNextSourceInfos.peek();
-                            if (nextSourceInfo != null) {
-                                nextSourceInfo.mPlayPendingAsNextSource = true;
-                            }
-                            Log.i(TAG, "MEDIA_PLAYBACK_COMPLETE: srcId=" + srcId
-                                    + ", curSrc=" + mCurrentSourceInfo
-                                    + ", nextSrc=" + nextSourceInfo);
-                        }
-
-                        playNextDataSource();
-                    }
-
-                    return;
-                }
-
-                case MEDIA_STOPPED:
-                case MEDIA_STARTED:
-                case MEDIA_PAUSED:
-                case MEDIA_SKIPPED:
-                case MEDIA_NOTIFY_TIME:
-                {
-                    // Do nothing. The client should have enough information with
-                    // {@link EventCallback#onMediaTimeDiscontinuity}.
-                    break;
-                }
-
-                case MEDIA_BUFFERING_UPDATE:
-                {
-                    final int percent = msg.arg1;
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onInfo(
-                                    mMediaPlayer, dsd, MEDIA_INFO_BUFFERING_UPDATE, percent);
-                        }
-                    });
-
-                    SourceInfo src = getSourceInfo(srcId);
-                    if (src != null) {
-                        src.mBufferedPercentage.set(percent);
-                    }
-
-                    return;
-                }
-
-                case MEDIA_SEEK_COMPLETE:
-                {
-                    synchronized (mTaskLock) {
-                        if (!mPendingTasks.isEmpty()
-                                && mPendingTasks.get(0).mMediaCallType != CALL_COMPLETED_SEEK_TO
-                                && getState() == PLAYER_STATE_PLAYING) {
-                            mIsPreviousCommandSeekTo = false;
-                        }
-
-                        if (mCurrentTask != null
-                                && mCurrentTask.mMediaCallType == CALL_COMPLETED_SEEK_TO
-                                && mCurrentTask.mNeedToWaitForEventToComplete) {
-                            mCurrentTask.sendCompleteNotification(CALL_STATUS_NO_ERROR);
-                            mCurrentTask = null;
-                            processPendingTask_l();
-                        }
-                    }
-                    return;
-                }
-
-                case MEDIA_SET_VIDEO_SIZE:
-                {
-                    final int width = msg.arg1;
-                    final int height = msg.arg2;
-
-                    mVideoSize = new Size(width, height);
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onVideoSizeChanged(
-                                    mMediaPlayer, dsd, mVideoSize);
-                        }
-                    });
-                    return;
-                }
-
-                case MEDIA_ERROR:
-                {
-                    Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onError(
-                                    mMediaPlayer, dsd, what, extra);
-                        }
-                    });
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onInfo(
-                                    mMediaPlayer, dsd, MEDIA_INFO_DATA_SOURCE_END, 0);
-                        }
-                    });
-                    stayAwake(false);
-                    return;
-                }
-
-                case MEDIA_INFO:
-                {
-                    switch (msg.arg1) {
-                        case MEDIA_INFO_VIDEO_TRACK_LAGGING:
-                            Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
-                            break;
-                    }
-
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onInfo(
-                                    mMediaPlayer, dsd, what, extra);
-                        }
-                    });
-
-                    if (msg.arg1 == MEDIA_INFO_DATA_SOURCE_START) {
-                        if (isCurrentSource(srcId)) {
-                            prepareNextDataSource();
-                        }
-                    }
-
-                    // No real default action so far.
-                    return;
-                }
-
-                case MEDIA_TIMED_TEXT:
-                {
-                    final TimedText text;
-                    if (msg.obj instanceof byte[]) {
-                        PlayerMessage playerMsg;
-                        try {
-                            playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj);
-                        } catch (InvalidProtocolBufferException e) {
-                            Log.w(TAG, "Failed to parse timed text.", e);
-                            return;
-                        }
-                        text = TimedTextUtil.parsePlayerMessage(playerMsg);
-                    } else {
-                        text = null;
-                    }
-
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onTimedText(
-                                    mMediaPlayer, dsd, text);
-                        }
-                    });
-                    return;
-                }
-
-                case MEDIA_SUBTITLE_DATA:
-                {
-                    if (msg.obj instanceof byte[]) {
-                        PlayerMessage playerMsg;
-                        try {
-                            playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj);
-                        } catch (InvalidProtocolBufferException e) {
-                            Log.w(TAG, "Failed to parse subtitle data.", e);
-                            return;
-                        }
-                        Iterator<Value> in = playerMsg.getValuesList().iterator();
-                        final int trackIndex = in.next().getInt32Value();
-                        TrackInfo trackInfo = getTrackInfo(dsd).get(trackIndex);
-                        final long startTimeUs = in.next().getInt64Value();
-                        final long durationTimeUs = in.next().getInt64Value();
-                        final byte[] subData = in.next().getBytesValue().toByteArray();
-                        SubtitleData data = new SubtitleData(trackInfo,
-                                startTimeUs, durationTimeUs, subData);
-                        sendEvent(new EventNotifier() {
-                            @Override
-                            public void notify(EventCallback callback) {
-                                callback.onSubtitleData(
-                                        mMediaPlayer, dsd, data);
-                            }
-                        });
-                    }
-                    return;
-                }
-
-                case MEDIA_META_DATA:
-                {
-                    final TimedMetaData data;
-                    if (msg.obj instanceof byte[]) {
-                        PlayerMessage playerMsg;
-                        try {
-                            playerMsg = PlayerMessage.parseFrom((byte[]) msg.obj);
-                        } catch (InvalidProtocolBufferException e) {
-                            Log.w(TAG, "Failed to parse timed meta data.", e);
-                            return;
-                        }
-                        Iterator<Value> in = playerMsg.getValuesList().iterator();
-                        data = new TimedMetaData(
-                                in.next().getInt64Value(),  // timestampUs
-                                in.next().getBytesValue().toByteArray());  // metaData
-                    } else {
-                        data = null;
-                    }
-
-                    sendEvent(new EventNotifier() {
-                        @Override
-                        public void notify(EventCallback callback) {
-                            callback.onTimedMetaDataAvailable(
-                                    mMediaPlayer, dsd, data);
-                        }
-                    });
-                    return;
-                }
-
-                case MEDIA_NOP: // interface test message - ignore
-                {
-                    break;
-                }
-
-                default:
-                {
-                    Log.e(TAG, "Unknown message type " + msg.what);
-                    return;
-                }
-            }
-        }
-    }
-
-    /*
-     * Called from native code when an interesting event happens.  This method
-     * just uses the TaskHandler system to post the event back to the main app thread.
-     * We use a weak reference to the original MediaPlayer2 object so that the native
-     * code is safe from the object disappearing from underneath it.  (This is
-     * the cookie passed to native_setup().)
-     */
-    private static void postEventFromNative(Object mediaplayer2Ref, long srcId,
-                                            int what, int arg1, int arg2, byte[] obj) {
-        final MediaPlayer2 mp = (MediaPlayer2) ((WeakReference) mediaplayer2Ref).get();
-        if (mp == null) {
-            return;
-        }
-
-        final SourceInfo sourceInfo = mp.getSourceInfo(srcId);
-        switch (what) {
-            case MEDIA_DRM_INFO:
-                // We need to derive mDrmInfo before prepare() returns so processing it here
-                // before the notification is sent to TaskHandler below. TaskHandler runs in the
-                // notification looper so its handleMessage might process the event after prepare()
-                // has returned.
-                Log.v(TAG, "postEventFromNative MEDIA_DRM_INFO");
-                if (obj != null && sourceInfo != null) {
-                    PlayerMessage playerMsg;
-                    try {
-                        playerMsg = PlayerMessage.parseFrom(obj);
-                    } catch (InvalidProtocolBufferException e) {
-                        Log.w(TAG, "MEDIA_DRM_INFO failed to parse msg.obj " + obj);
-                        break;
-                    }
-                    DrmInfo drmInfo = DrmInfo.create(playerMsg);
-                    synchronized (sourceInfo) {
-                        sourceInfo.mDrmInfo = drmInfo;
-                    }
-                } else {
-                    Log.w(TAG, "MEDIA_DRM_INFO sourceInfo " + sourceInfo
-                            + " msg.obj of unexpected type " + obj);
-                }
-                break;
-
-            case MEDIA_PREPARED:
-                // By this time, we've learned about DrmInfo's presence or absence. This is meant
-                // mainly for prepare() use case. For prepare(), this still can run to a race
-                // condition b/c MediaPlayerNative releases the prepare() lock before calling notify
-                // so we also set mDrmInfoResolved in prepare().
-                if (sourceInfo != null) {
-                    synchronized (sourceInfo) {
-                        sourceInfo.mDrmInfoResolved = true;
-                    }
-                }
-                break;
-        }
-
-        if (mp.mTaskHandler != null) {
-            Message m = mp.mTaskHandler.obtainMessage(what, arg1, arg2, obj);
-
-            mp.mTaskHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mp.mTaskHandler.handleMessage(m, srcId);
-                }
-            });
-        }
-    }
-
-    /**
-     * Class encapsulating subtitle data, as received through the
-     * {@link EventCallback#onSubtitleData} interface.
-     * <p>
-     * A {@link SubtitleData} object includes:
-     * <ul>
-     * <li> track metadadta in a {@link TrackInfo} object</li>
-     * <li> the start time (in microseconds) of the data</li>
-     * <li> the duration (in microseconds) of the data</li>
-     * <li> the actual data.</li>
-     * </ul>
-     * The data is stored in a byte-array, and is encoded in one of the supported in-band
-     * subtitle formats. The subtitle encoding is determined by the MIME type of the
-     * {@link TrackInfo} of the subtitle track, one of
-     * {@link MediaFormat#MIMETYPE_TEXT_CEA_608}, {@link MediaFormat#MIMETYPE_TEXT_CEA_708},
-     * {@link MediaFormat#MIMETYPE_TEXT_VTT}.
-     */
-    public static final class SubtitleData {
-
-        private TrackInfo mTrackInfo;
-        private long mStartTimeUs;
-        private long mDurationUs;
-        private byte[] mData;
-
-        private SubtitleData(TrackInfo trackInfo, long startTimeUs, long durationUs, byte[] data) {
-            mTrackInfo = trackInfo;
-            mStartTimeUs = startTimeUs;
-            mDurationUs = durationUs;
-            mData = (data != null ? data : new byte[0]);
-        }
-
-        /**
-         * @return metadata of track which contains this subtitle data
-         */
-        @NonNull
-        public TrackInfo getTrackInfo() {
-            return mTrackInfo;
-        }
-
-        /**
-         * @return media time at which the subtitle should start to be displayed in microseconds
-         */
-        public long getStartTimeUs() {
-            return mStartTimeUs;
-        }
-
-        /**
-         * @return the duration in microsecond during which the subtitle should be displayed
-         */
-        public long getDurationUs() {
-            return mDurationUs;
-        }
-
-        /**
-         * Returns the encoded data for the subtitle content.
-         * Encoding format depends on the subtitle type, refer to
-         * <a href="https://en.wikipedia.org/wiki/CEA-708">CEA 708</a>,
-         * <a href="https://en.wikipedia.org/wiki/EIA-608">CEA/EIA 608</a> and
-         * <a href="https://www.w3.org/TR/webvtt1/">WebVTT</a>, defined by the MIME type
-         * of the subtitle track.
-         * @return the encoded subtitle data
-         */
-        @NonNull
-        public byte[] getData() {
-            return mData;
-        }
-    }
-
-    /**
-     * Interface definition for callbacks to be invoked when the player has the corresponding
-     * events.
-     */
-    public static class EventCallback {
-        /**
-         * Called to indicate the video size
-         *
-         * The video size (width and height) could be 0 if there was no video,
-         * or the value was not determined yet.
-         *
-         * @param mp the MediaPlayer2 associated with this callback
-         * @param dsd the DataSourceDesc of this data source
-         * @param size the size of the video
-         */
-        public void onVideoSizeChanged(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd, @NonNull Size size) { }
-
-        /**
-         * Called to indicate an avaliable timed text
-         *
-         * @param mp the MediaPlayer2 associated with this callback
-         * @param dsd the DataSourceDesc of this data source
-         * @param text the timed text sample which contains the text
-         *             needed to be displayed and the display format.
-         * @hide
-         */
-        public void onTimedText(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd, @NonNull TimedText text) { }
-
-        /**
-         * Called to indicate avaliable timed metadata
-         * <p>
-         * This method will be called as timed metadata is extracted from the media,
-         * in the same order as it occurs in the media. The timing of this event is
-         * not controlled by the associated timestamp.
-         * <p>
-         * Currently only HTTP live streaming data URI's embedded with timed ID3 tags generates
-         * {@link TimedMetaData}.
-         *
-         * @see MediaPlayer2#selectTrack
-         * @see MediaPlayer2.OnTimedMetaDataAvailableListener
-         * @see TimedMetaData
-         *
-         * @param mp the MediaPlayer2 associated with this callback
-         * @param dsd the DataSourceDesc of this data source
-         * @param data the timed metadata sample associated with this event
-         */
-        public void onTimedMetaDataAvailable(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @NonNull TimedMetaData data) { }
-
-        /**
-         * Called to indicate an error.
-         *
-         * @param mp the MediaPlayer2 the error pertains to
-         * @param dsd the DataSourceDesc of this data source
-         * @param what the type of error that has occurred.
-         * @param extra an extra code, specific to the error. Typically
-         * implementation dependent.
-         */
-        public void onError(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @MediaError int what, int extra) { }
-
-        /**
-         * Called to indicate an info or a warning.
-         *
-         * @param mp the MediaPlayer2 the info pertains to.
-         * @param dsd the DataSourceDesc of this data source
-         * @param what the type of info or warning.
-         * @param extra an extra code, specific to the info. Typically
-         * implementation dependent.
-         */
-        public void onInfo(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @MediaInfo int what, int extra) { }
-
-        /**
-         * Called to acknowledge an API call.
-         *
-         * @param mp the MediaPlayer2 the call was made on.
-         * @param dsd the DataSourceDesc of this data source
-         * @param what the enum for the API call.
-         * @param status the returned status code for the call.
-         */
-        public void onCallCompleted(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd, @CallCompleted int what,
-                @CallStatus int status) { }
-
-        /**
-         * Called to indicate media clock has changed.
-         *
-         * @param mp the MediaPlayer2 the media time pertains to.
-         * @param dsd the DataSourceDesc of this data source
-         * @param timestamp the new media clock.
-         */
-        public void onMediaTimeDiscontinuity(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @NonNull MediaTimestamp timestamp) { }
-
-        /**
-         * Called to indicate {@link #notifyWhenCommandLabelReached(Object)} has been processed.
-         *
-         * @param mp the MediaPlayer2 {@link #notifyWhenCommandLabelReached(Object)} was called on.
-         * @param label the application specific Object given by
-         *        {@link #notifyWhenCommandLabelReached(Object)}.
-         */
-        public void onCommandLabelReached(@NonNull MediaPlayer2 mp, @NonNull Object label) { }
-
-        /**
-         * Called when when a player subtitle track has new subtitle data available.
-         * @param mp the player that reports the new subtitle data
-         * @param dsd the DataSourceDesc of this data source
-         * @param data the subtitle data
-         */
-        public void onSubtitleData(
-                @NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @NonNull SubtitleData data) { }
-    }
-
-    private final Object mEventCbLock = new Object();
-    private ArrayList<Pair<Executor, EventCallback>> mEventCallbackRecords =
-            new ArrayList<Pair<Executor, EventCallback>>();
-
-    /**
-     * Registers the callback to be invoked for various events covered by {@link EventCallback}.
-     *
-     * @param executor the executor through which the callback should be invoked
-     * @param eventCallback the callback that will be run
-     */
-    // This is a synchronous call.
-    public void registerEventCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull EventCallback eventCallback) {
-        if (eventCallback == null) {
-            throw new IllegalArgumentException("Illegal null EventCallback");
-        }
-        if (executor == null) {
-            throw new IllegalArgumentException(
-                    "Illegal null Executor for the EventCallback");
-        }
-        synchronized (mEventCbLock) {
-            for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                if (cb.first == executor && cb.second == eventCallback) {
-                    Log.w(TAG, "The callback has been registered before.");
-                    return;
-                }
-            }
-            mEventCallbackRecords.add(new Pair(executor, eventCallback));
-        }
-    }
-
-    /**
-     * Unregisters the {@link EventCallback}.
-     *
-     * @param eventCallback the callback to be unregistered
-     */
-    // This is a synchronous call.
-    public void unregisterEventCallback(@NonNull EventCallback eventCallback) {
-        synchronized (mEventCbLock) {
-            for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                if (cb.second == eventCallback) {
-                    mEventCallbackRecords.remove(cb);
-                }
-            }
-        }
-    }
-
-    private void sendEvent(final EventNotifier notifier) {
-        synchronized (mEventCbLock) {
-            try {
-                for (Pair<Executor, EventCallback> cb : mEventCallbackRecords) {
-                    cb.first.execute(() -> notifier.notify(cb.second));
-                }
-            } catch (RejectedExecutionException e) {
-                // The executor has been shut down.
-                Log.w(TAG, "The executor has been shut down. Ignoring event.");
-            }
-        }
-    }
-
-    private void sendDrmEvent(final DrmEventNotifier notifier) {
-        synchronized (mDrmEventCallbackLock) {
-            try {
-                Pair<Executor, DrmEventCallback> cb = mDrmEventCallback;
-                if (cb != null) {
-                    cb.first.execute(() -> notifier.notify(cb.second));
-                }
-            } catch (RejectedExecutionException e) {
-                // The executor has been shut down.
-                Log.w(TAG, "The executor has been shut down. Ignoring drm event.");
-            }
-        }
-    }
-
-    private <T> T sendDrmEventWait(final DrmEventNotifier<T> notifier)
-            throws InterruptedException, ExecutionException, TimeoutException {
-        return sendDrmEventWait(notifier, 0);
-    }
-
-    private <T> T sendDrmEventWait(final DrmEventNotifier<T> notifier, final long timeoutMs)
-            throws InterruptedException, ExecutionException, TimeoutException {
-        synchronized (mDrmEventCallbackLock) {
-            Pair<Executor, DrmEventCallback> cb = mDrmEventCallback;
-            if (cb != null) {
-                CompletableFuture<T> ret = new CompletableFuture<>();
-                cb.first.execute(() -> ret.complete(notifier.notifyWait(cb.second)));
-                return timeoutMs <= 0 ? ret.get() : ret.get(timeoutMs, TimeUnit.MILLISECONDS);
-            }
-        }
-        return null;
-    }
-
-    private interface EventNotifier {
-        void notify(EventCallback callback);
-    }
-
-    private interface DrmEventNotifier<T> {
-        default void notify(DrmEventCallback callback) { }
-        default T notifyWait(DrmEventCallback callback) {
-            return null;
-        }
-    }
-
-    /* Do not change these values without updating their counterparts
-     * in include/media/MediaPlayer2Types.h!
-     */
-    /** Unspecified media player error.
-     * @see EventCallback#onError
-     */
-    public static final int MEDIA_ERROR_UNKNOWN = 1;
-
-    /**
-     * The video is streamed and its container is not valid for progressive
-     * playback i.e the video's index (e.g moov atom) is not at the start of the
-     * file.
-     * @see EventCallback#onError
-     */
-    public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
-
-    /** File or network related operation errors. */
-    public static final int MEDIA_ERROR_IO = -1004;
-    /** Bitstream is not conforming to the related coding standard or file spec. */
-    public static final int MEDIA_ERROR_MALFORMED = -1007;
-    /** Bitstream is conforming to the related coding standard or file spec, but
-     * the media framework does not support the feature. */
-    public static final int MEDIA_ERROR_UNSUPPORTED = -1010;
-    /** Some operation takes too long to complete, usually more than 3-5 seconds. */
-    public static final int MEDIA_ERROR_TIMED_OUT = -110;
-
-    /** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
-     * system/core/include/utils/Errors.h
-     * @see EventCallback#onError
-     * @hide
-     */
-    public static final int MEDIA_ERROR_SYSTEM = -2147483648;
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "MEDIA_ERROR", value = {
-            MEDIA_ERROR_UNKNOWN,
-            MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK,
-            MEDIA_ERROR_IO,
-            MEDIA_ERROR_MALFORMED,
-            MEDIA_ERROR_UNSUPPORTED,
-            MEDIA_ERROR_TIMED_OUT,
-            MEDIA_ERROR_SYSTEM
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediaError {}
-
-    /* Do not change these values without updating their counterparts
-     * in include/media/MediaPlayer2Types.h!
-     */
-    /** Unspecified media player info.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_UNKNOWN = 1;
-
-    /** The player just started the playback of this datas source.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_DATA_SOURCE_START = 2;
-
-    /** The player just pushed the very first video frame for rendering.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
-
-    /** The player just rendered the very first audio sample.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_AUDIO_RENDERING_START = 4;
-
-    /** The player just completed the playback of this data source.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_DATA_SOURCE_END = 5;
-
-    /** The player just completed the playback of all data sources set by {@link #setDataSource},
-     * {@link #setNextDataSource} and {@link #setNextDataSources}.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_DATA_SOURCE_LIST_END = 6;
-
-    /** The player just completed an iteration of playback loop. This event is sent only when
-     *  looping is enabled by {@link #loopCurrent}.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_DATA_SOURCE_REPEAT = 7;
-
-    /** The player just prepared a data source.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_PREPARED = 100;
-
-    /** The video is too complex for the decoder: it can't decode frames fast
-     *  enough. Possibly only the audio plays fine at this stage.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
-
-    /** MediaPlayer2 is temporarily pausing playback internally in order to
-     * buffer more data.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_BUFFERING_START = 701;
-
-    /** MediaPlayer2 is resuming playback after filling buffers.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_BUFFERING_END = 702;
-
-    /** Estimated network bandwidth information (kbps) is available; currently this event fires
-     * simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
-     * when playing network files.
-     * @see EventCallback#onInfo
-     * @hide
-     */
-    public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
-
-    /**
-     * Update status in buffering a media source received through progressive downloading.
-     * The received buffering percentage indicates how much of the content has been buffered
-     * or played. For example a buffering update of 80 percent when half the content
-     * has already been played indicates that the next 30 percent of the
-     * content to play has been buffered.
-     *
-     * The {@code extra} parameter in {@code EventCallback.onInfo} is the
-     * percentage (0-100) of the content that has been buffered or played thus far.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_BUFFERING_UPDATE = 704;
-
-    /** Bad interleaving means that a media has been improperly interleaved or
-     * not interleaved at all, e.g has all the video samples first then all the
-     * audio ones. Video is playing but a lot of disk seeks may be happening.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
-
-    /** The media cannot be seeked (e.g live stream)
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
-
-    /** A new set of metadata is available.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_METADATA_UPDATE = 802;
-
-    /** Informs that audio is not playing. Note that playback of the video
-     * is not interrupted.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
-
-    /** Informs that video is not playing. Note that playback of the audio
-     * is not interrupted.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
-
-    /** Failed to handle timed text track properly.
-     * @see EventCallback#onInfo
-     *
-     * {@hide}
-     */
-    public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
-
-    /** Subtitle track was not supported by the media framework.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
-
-    /** Reading the subtitle track takes too long.
-     * @see EventCallback#onInfo
-     */
-    public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "MEDIA_INFO", value = {
-            MEDIA_INFO_UNKNOWN,
-            MEDIA_INFO_DATA_SOURCE_START,
-            MEDIA_INFO_VIDEO_RENDERING_START,
-            MEDIA_INFO_AUDIO_RENDERING_START,
-            MEDIA_INFO_DATA_SOURCE_END,
-            MEDIA_INFO_DATA_SOURCE_LIST_END,
-            MEDIA_INFO_PREPARED,
-            MEDIA_INFO_VIDEO_TRACK_LAGGING,
-            MEDIA_INFO_BUFFERING_START,
-            MEDIA_INFO_BUFFERING_END,
-            MEDIA_INFO_NETWORK_BANDWIDTH,
-            MEDIA_INFO_BUFFERING_UPDATE,
-            MEDIA_INFO_BAD_INTERLEAVING,
-            MEDIA_INFO_NOT_SEEKABLE,
-            MEDIA_INFO_METADATA_UPDATE,
-            MEDIA_INFO_AUDIO_NOT_PLAYING,
-            MEDIA_INFO_VIDEO_NOT_PLAYING,
-            MEDIA_INFO_TIMED_TEXT_ERROR,
-            MEDIA_INFO_UNSUPPORTED_SUBTITLE,
-            MEDIA_INFO_SUBTITLE_TIMED_OUT
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediaInfo {}
-
-    //--------------------------------------------------------------------------
-    /** The player just completed a call {@link #attachAuxEffect}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_ATTACH_AUX_EFFECT = 1;
-
-    /** The player just completed a call {@link #deselectTrack}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_DESELECT_TRACK = 2;
-
-    /** The player just completed a call {@link #loopCurrent}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_LOOP_CURRENT = 3;
-
-    /** The player just completed a call {@link #pause}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_PAUSE = 4;
-
-    /** The player just completed a call {@link #play}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_PLAY = 5;
-
-    /** The player just completed a call {@link #prepare}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_PREPARE = 6;
-
-    /** The player just completed a call {@link #seekTo}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SEEK_TO = 14;
-
-    /** The player just completed a call {@link #selectTrack}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SELECT_TRACK = 15;
-
-    /** The player just completed a call {@link #setAudioAttributes}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_AUDIO_ATTRIBUTES = 16;
-
-    /** The player just completed a call {@link #setAudioSessionId}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_AUDIO_SESSION_ID = 17;
-
-    /** The player just completed a call {@link #setAuxEffectSendLevel}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL = 18;
-
-    /** The player just completed a call {@link #setDataSource}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_DATA_SOURCE = 19;
-
-    /** The player just completed a call {@link #setNextDataSource}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCE = 22;
-
-    /** The player just completed a call {@link #setNextDataSources}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_NEXT_DATA_SOURCES = 23;
-
-    /** The player just completed a call {@link #setPlaybackParams}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_PLAYBACK_PARAMS = 24;
-
-    /** The player just completed a call {@link #setPlayerVolume}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_PLAYER_VOLUME = 26;
-
-    /** The player just completed a call {@link #setSurface}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_SURFACE = 27;
-
-    /** The player just completed a call {@link #setSyncParams}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_SYNC_PARAMS = 28;
-
-    /** The player just completed a call {@link #skipToNext}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SKIP_TO_NEXT = 29;
-
-    /** The player just completed a call {@link #clearNextDataSources}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES = 30;
-
-    /** The player just completed a call {@link #setBufferingParams}.
-     * @see EventCallback#onCallCompleted
-     * @hide
-     */
-    public static final int CALL_COMPLETED_SET_BUFFERING_PARAMS = 31;
-
-    /** The player just completed a call {@link #setDisplay}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_DISPLAY = 33;
-
-    /** The player just completed a call {@link #setWakeLock}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_WAKE_LOCK = 34;
-
-    /** The player just completed a call {@link #setScreenOnWhilePlaying}.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING = 35;
-
-    /**
-     * The start of the methods which have separate call complete callback.
-     * @hide
-     */
-    public static final int SEPARATE_CALL_COMPLETED_CALLBACK_START = 1000;
-
-    /** The player just completed a call {@link #notifyWhenCommandLabelReached}.
-     * @see EventCallback#onCommandLabelReached
-     * @hide
-     */
-    public static final int CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED =
-            SEPARATE_CALL_COMPLETED_CALLBACK_START;
-
-    /** The player just completed a call {@link #prepareDrm}.
-     * @see DrmEventCallback#onDrmPrepared
-     * @hide
-     */
-    public static final int CALL_COMPLETED_PREPARE_DRM =
-            SEPARATE_CALL_COMPLETED_CALLBACK_START + 1;
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "CALL_COMPLETED", value = {
-            CALL_COMPLETED_ATTACH_AUX_EFFECT,
-            CALL_COMPLETED_DESELECT_TRACK,
-            CALL_COMPLETED_LOOP_CURRENT,
-            CALL_COMPLETED_PAUSE,
-            CALL_COMPLETED_PLAY,
-            CALL_COMPLETED_PREPARE,
-            CALL_COMPLETED_SEEK_TO,
-            CALL_COMPLETED_SELECT_TRACK,
-            CALL_COMPLETED_SET_AUDIO_ATTRIBUTES,
-            CALL_COMPLETED_SET_AUDIO_SESSION_ID,
-            CALL_COMPLETED_SET_AUX_EFFECT_SEND_LEVEL,
-            CALL_COMPLETED_SET_DATA_SOURCE,
-            CALL_COMPLETED_SET_NEXT_DATA_SOURCE,
-            CALL_COMPLETED_SET_NEXT_DATA_SOURCES,
-            CALL_COMPLETED_SET_PLAYBACK_PARAMS,
-            CALL_COMPLETED_SET_PLAYER_VOLUME,
-            CALL_COMPLETED_SET_SURFACE,
-            CALL_COMPLETED_SET_SYNC_PARAMS,
-            CALL_COMPLETED_SKIP_TO_NEXT,
-            CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES,
-            CALL_COMPLETED_SET_BUFFERING_PARAMS,
-            CALL_COMPLETED_SET_DISPLAY,
-            CALL_COMPLETED_SET_WAKE_LOCK,
-            CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING,
-            CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED,
-            CALL_COMPLETED_PREPARE_DRM,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallCompleted {}
-
-    /** Status code represents that call is completed without an error.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_NO_ERROR = 0;
-
-    /** Status code represents that call is ended with an unknown error.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_ERROR_UNKNOWN = Integer.MIN_VALUE;
-
-    /** Status code represents that the player is not in valid state for the operation.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_INVALID_OPERATION = 1;
-
-    /** Status code represents that the argument is illegal.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_BAD_VALUE = 2;
-
-    /** Status code represents that the operation is not allowed.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_PERMISSION_DENIED = 3;
-
-    /** Status code represents a file or network related operation error.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_ERROR_IO = 4;
-
-    /** Status code represents that the call has been skipped. For example, a {@link #seekTo}
-     * request may be skipped if it is followed by another {@link #seekTo} request.
-     * @see EventCallback#onCallCompleted
-     */
-    public static final int CALL_STATUS_SKIPPED = 5;
-
-    /** Status code represents that DRM operation is called before preparing a DRM scheme through
-     *  {@code prepareDrm}.
-     * @see EventCallback#onCallCompleted
-     */
-    // TODO: change @code to @link when DRM is unhidden
-    public static final int CALL_STATUS_NO_DRM_SCHEME = 6;
-
-    /**
-     * @hide
-     */
-    @IntDef(flag = false, prefix = "CALL_STATUS", value = {
-            CALL_STATUS_NO_ERROR,
-            CALL_STATUS_ERROR_UNKNOWN,
-            CALL_STATUS_INVALID_OPERATION,
-            CALL_STATUS_BAD_VALUE,
-            CALL_STATUS_PERMISSION_DENIED,
-            CALL_STATUS_ERROR_IO,
-            CALL_STATUS_SKIPPED,
-            CALL_STATUS_NO_DRM_SCHEME})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface CallStatus {}
-
-    // Modular DRM begin
-
-    /**
-     * An immutable structure per {@link DataSourceDesc} with settings required to initiate a DRM
-     * protected playback session.
-     *
-     * @see DrmPreparationInfo.Builder
-     */
-    public static final class DrmPreparationInfo {
-
-        /**
-         * Mutable builder to create a {@link MediaPlayer2.DrmPreparationInfo} object.
-         *
-         * {@link Builder#Builder(UUID) UUID} must not be null; {@link #setKeyType keyType}
-         * must be one of {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}.
-         * <p>
-         * When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_STREAMING},
-         * {@link #setInitData(byte[]) initData} and {@link #setMimeType(String) mimeType}
-         * must not be null; When {@link #setKeyType keyType} is {@link MediaDrm#KEY_TYPE_OFFLINE},
-         * {@link #setKeySetId(byte[]) keySetId} must not be null.
-         */
-        public static final class Builder {
-
-            private final UUID mUUID;
-            private byte[] mKeySetId;
-            private byte[] mInitData;
-            private String mMimeType;
-            private int mKeyType;
-            private Map<String, String> mOptionalParameters;
-
-            /**
-             * @param uuid UUID of the crypto scheme selected to decrypt content. An UUID can be
-             * retrieved from the source listening to {@link DrmEventCallback#onDrmInfo}.
-             */
-            public Builder(@NonNull UUID uuid) {
-                this.mUUID = uuid;
-            }
-
-            /**
-             * Set identifier of a persisted offline key obtained from
-             * {@link MediaPlayer2.DrmEventCallback#onDrmPrepared}.
-             *
-             * A {@code keySetId} can be used to restore persisted offline keys into a new playback
-             * session of a DRM protected data source. When {@code keySetId} is set,
-             * {@code initData}, {@code mimeType}, {@code keyType}, {@code optionalParameters} are
-             * ignored.
-             *
-             * @param keySetId identifier of a persisted offline key
-             * @return this
-             */
-            public @NonNull Builder setKeySetId(@Nullable byte[] keySetId) {
-                this.mKeySetId = keySetId;
-                return this;
-            }
-
-            /**
-             * Set container-specific DRM initialization data. Its meaning is interpreted based on
-             * {@code mimeType}. For example, it could contain the content ID, key ID or other data
-             * obtained from the content metadata that is required to generate a
-             * {@link MediaDrm.KeyRequest}.
-             *
-             * @param initData container-specific DRM initialization data
-             * @return this
-             */
-            public @NonNull Builder setInitData(@Nullable byte[] initData) {
-                this.mInitData = initData;
-                return this;
-            }
-
-            /**
-             * Set mime type of the content
-             *
-             * @param mimeType mime type to the content
-             * @return this
-             */
-            public @NonNull Builder setMimeType(@Nullable String mimeType) {
-                this.mMimeType = mimeType;
-                return this;
-            }
-
-            /**
-             * Set type of the key request. The request may be to acquire keys
-             * for streaming, {@link MediaDrm#KEY_TYPE_STREAMING}, or for offline content,
-             * {@link MediaDrm#KEY_TYPE_OFFLINE}. Releasing previously acquired keys
-             * ({@link MediaDrm#KEY_TYPE_RELEASE}) is not allowed.
-             *
-             * @param keyType type of the key request
-             * @return this
-             */
-            public @NonNull Builder setKeyType(@MediaPlayer2.MediaDrmKeyType int keyType) {
-                this.mKeyType = keyType;
-                return this;
-            }
-
-            /**
-             * Set optional parameters to be included in a {@link MediaDrm.KeyRequest} message sent
-             * to the license server.
-             *
-             * @param optionalParameters optional parameters to be included in a key request
-             * @return this
-             */
-            public @NonNull Builder setOptionalParameters(
-                    @Nullable Map<String, String> optionalParameters) {
-                this.mOptionalParameters = optionalParameters;
-                return this;
-            }
-
-            /**
-             * @return an immutable {@link DrmPreparationInfo} based on settings of this builder
-             */
-            @NonNull
-            public DrmPreparationInfo build() {
-                final DrmPreparationInfo info = new DrmPreparationInfo(mUUID, mKeySetId, mInitData,
-                        mMimeType, mKeyType, mOptionalParameters);
-                if (!info.isValid()) {
-                    throw new IllegalArgumentException("invalid DrmPreparationInfo");
-                }
-                return info;
-            }
-
-        }
-
-        private final UUID mUUID;
-        private final byte[] mKeySetId;
-        private final byte[] mInitData;
-        private final String mMimeType;
-        private final int mKeyType;
-        private final Map<String, String> mOptionalParameters;
-
-        private DrmPreparationInfo(UUID mUUID, byte[] mKeySetId, byte[] mInitData, String mMimeType,
-                int mKeyType, Map<String, String> optionalParameters) {
-            this.mUUID = mUUID;
-            this.mKeySetId = mKeySetId;
-            this.mInitData = mInitData;
-            this.mMimeType = mMimeType;
-            this.mKeyType = mKeyType;
-            this.mOptionalParameters = optionalParameters;
-        }
-
-        boolean isValid() {
-            if (mUUID == null) {
-                return false;
-            }
-            if (mKeySetId != null) {
-                // offline restore case
-                return true;
-            }
-            if (mInitData != null && mMimeType != null) {
-                // new streaming license case
-                return true;
-            }
-            return false;
-        }
-
-        /**
-         * @return UUID of the crypto scheme selected to decrypt content.
-         */
-        @NonNull
-        public UUID getUuid() {
-            return mUUID;
-        }
-
-        /**
-         * @return identifier of the persisted offline key.
-         */
-        @Nullable
-        public byte[] getKeySetId() {
-            return mKeySetId;
-        }
-
-        /**
-         * @return container-specific DRM initialization data.
-         */
-        @Nullable
-        public byte[] getInitData() {
-            return mInitData;
-        }
-
-        /**
-         * @return mime type of the content
-         */
-        @Nullable
-        public String getMimeType() {
-            return mMimeType;
-        }
-
-        /**
-         * @return type of the key request.
-         */
-        @MediaPlayer2.MediaDrmKeyType
-        public int getKeyType() {
-            return mKeyType;
-        }
-
-        /**
-         * @return optional parameters to be included in the {@link MediaDrm.KeyRequest}.
-         */
-        @Nullable
-        public Map<String, String> getOptionalParameters() {
-            return mOptionalParameters;
-        }
-    }
-
-    /**
-     * Interface definition for callbacks to be invoked when the player has the corresponding
-     * DRM events.
-     */
-    public static abstract class DrmEventCallback {
-
-        /**
-         * Called to indicate DRM info is available. Return a {@link DrmPreparationInfo} object that
-         * bundles DRM initialization parameters.
-         *
-         * @param mp the {@code MediaPlayer2} associated with this callback
-         * @param dsd the {@link DataSourceDesc} of this data source
-         * @param drmInfo DRM info of the source including PSSH, and subset of crypto schemes
-         *        supported by this device
-         * @return a {@link DrmPreparationInfo} object to initialize DRM playback, or null to skip
-         *         DRM initialization
-         */
-        @Nullable
-        public abstract DrmPreparationInfo onDrmInfo(@NonNull MediaPlayer2 mp,
-                @NonNull DataSourceDesc dsd, @NonNull DrmInfo drmInfo);
-
-        /**
-         * Called to give the app the opportunity to configure DRM before the session is created.
-         *
-         * This facilitates configuration of the properties, like 'securityLevel', which
-         * has to be set after DRM scheme creation but before the DRM session is opened.
-         *
-         * The only allowed DRM calls in this listener are
-         * {@link MediaDrm#getPropertyString(String)},
-         * {@link MediaDrm#getPropertyByteArray(String)},
-         * {@link MediaDrm#setPropertyString(String, String)},
-         * {@link MediaDrm#setPropertyByteArray(String, byte[])},
-         * {@link MediaDrm#setOnExpirationUpdateListener},
-         * and {@link MediaDrm#setOnKeyStatusChangeListener}.
-         *
-         * @param mp the {@code MediaPlayer2} associated with this callback
-         * @param dsd the {@link DataSourceDesc} of this data source
-         * @param drm handle to get/set DRM properties and listeners for this data source
-         */
-        public void onDrmConfig(@NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @NonNull MediaDrm drm) { }
-
-        /**
-         * Called to indicate the DRM session for {@code dsd} is ready for key request/response
-         *
-         * @param mp the {@code MediaPlayer2} associated with this callback
-         * @param dsd the {@link DataSourceDesc} of this data source
-         * @param request a {@link MediaDrm.KeyRequest} prepared using the
-         *        {@link DrmPreparationInfo} returned from
-         *        {@link #onDrmInfo(MediaPlayer2, DataSourceDesc, DrmInfo)}
-         * @return the response to {@code request} (from license server); returning {@code null} or
-         *         throwing an {@link RuntimeException} from this callback would trigger an
-         *         {@link EventCallback#onError}.
-         */
-        @NonNull
-        public abstract byte[] onDrmKeyRequest(@NonNull MediaPlayer2 mp,
-                @NonNull DataSourceDesc dsd, @NonNull MediaDrm.KeyRequest request);
-
-        /**
-         * Called to notify the client that {@code mp} is ready to decrypt DRM protected data source
-         * {@code dsd} or if there is an error during DRM preparation
-         *
-         * @param mp the {@code MediaPlayer2} associated with this callback
-         * @param dsd the {@link DataSourceDesc} of this data source
-         * @param status the result of DRM preparation.
-         * @param keySetId optional identifier that can be used to restore DRM playback initiated
-         *        with a {@link MediaDrm#KEY_TYPE_OFFLINE} key request.
-         *
-         * @see DrmPreparationInfo.Builder#setKeySetId(byte[])
-         */
-        public void onDrmPrepared(@NonNull MediaPlayer2 mp, @NonNull DataSourceDesc dsd,
-                @PrepareDrmStatusCode int status, @Nullable byte[] keySetId) { }
-
-    }
-
-    private final Object mDrmEventCallbackLock = new Object();
-    private Pair<Executor, DrmEventCallback> mDrmEventCallback;
-
-    /**
-     * Registers the callback to be invoked for various DRM events.
-     *
-     * This is a synchronous call.
-     *
-     * @param eventCallback the callback that will be run
-     * @param executor the executor through which the callback should be invoked
-     */
-    public void setDrmEventCallback(@NonNull @CallbackExecutor Executor executor,
-            @NonNull DrmEventCallback eventCallback) {
-        if (eventCallback == null) {
-            throw new IllegalArgumentException("Illegal null EventCallback");
-        }
-        if (executor == null) {
-            throw new IllegalArgumentException(
-                    "Illegal null Executor for the EventCallback");
-        }
-        synchronized (mDrmEventCallbackLock) {
-            mDrmEventCallback = new Pair<Executor, DrmEventCallback>(executor, eventCallback);
-        }
-    }
-
-    /**
-     * Clear the {@link DrmEventCallback}.
-     *
-     * This is a synchronous call.
-     */
-    public void clearDrmEventCallback() {
-        synchronized (mDrmEventCallbackLock) {
-            mDrmEventCallback = null;
-        }
-    }
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * DRM preparation has succeeded.
-     */
-    public static final int PREPARE_DRM_STATUS_SUCCESS = 0;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * The device required DRM provisioning but couldn't reach the provisioning server.
-     */
-    public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * The device required DRM provisioning but the provisioning server denied the request.
-     */
-    public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * The DRM preparation has failed .
-     */
-    public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * The crypto scheme UUID is not supported by the device.
-     */
-    public static final int PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME = 4;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * The hardware resources are not available, due to being in use.
-     */
-    public static final int PREPARE_DRM_STATUS_RESOURCE_BUSY = 5;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * Restoring persisted offline keys failed.
-     */
-    public static final int PREPARE_DRM_STATUS_RESTORE_ERROR = 6;
-
-    /**
-     * A status code for {@link DrmEventCallback#onDrmPrepared} listener.
-     * <p>
-     *
-     * Error during key request/response exchange with license server.
-     */
-    public static final int PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR = 7;
-
-    /** @hide */
-    @IntDef(flag = false, prefix = "PREPARE_DRM_STATUS", value = {
-        PREPARE_DRM_STATUS_SUCCESS,
-        PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
-        PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
-        PREPARE_DRM_STATUS_PREPARATION_ERROR,
-        PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME,
-        PREPARE_DRM_STATUS_RESOURCE_BUSY,
-        PREPARE_DRM_STATUS_RESTORE_ERROR,
-        PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface PrepareDrmStatusCode {}
-
-    /** @hide */
-    @IntDef({
-        MediaDrm.KEY_TYPE_STREAMING,
-        MediaDrm.KEY_TYPE_OFFLINE,
-        MediaDrm.KEY_TYPE_RELEASE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediaDrmKeyType {}
-
-    /** @hide */
-    @StringDef({
-        MediaDrm.PROPERTY_VENDOR,
-        MediaDrm.PROPERTY_VERSION,
-        MediaDrm.PROPERTY_DESCRIPTION,
-        MediaDrm.PROPERTY_ALGORITHMS,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface MediaDrmStringProperty {}
-
-    /**
-     * Retrieves the DRM Info associated with the given source
-     *
-     * @param dsd The DRM protected data source
-     *
-     * @throws IllegalStateException if called before being prepared
-     * @hide
-     */
-    @TestApi
-    public DrmInfo getDrmInfo(@NonNull DataSourceDesc dsd) {
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            DrmInfo drmInfo = null;
-
-            // there is not much point if the app calls getDrmInfo within an OnDrmInfoListener;
-            // regardless below returns drmInfo anyway instead of raising an exception
-            synchronized (sourceInfo) {
-                if (!sourceInfo.mDrmInfoResolved && sourceInfo.mDrmInfo == null) {
-                    final String msg = "The Player has not been prepared yet";
-                    Log.v(TAG, msg);
-                    throw new IllegalStateException(msg);
-                }
-
-                if (sourceInfo.mDrmInfo != null) {
-                    drmInfo  = sourceInfo.mDrmInfo.makeCopy();
-                }
-            }   // synchronized
-
-            return drmInfo;
-        }
-        return null;
-    }
-
-    /**
-     * Prepares the DRM for the given data source
-     * <p>
-     * If {@link DrmEventCallback} is registered, it will be called during
-     * preparation to allow configuration of the DRM properties before opening the
-     * DRM session. It should be used only for a series of
-     * {@link #getDrmPropertyString(DataSourceDesc, String)} and
-     * {@link #setDrmPropertyString(DataSourceDesc, String, String)} calls
-     * and refrain from any lengthy operation.
-     * <p>
-     * If the device has not been provisioned before, this call also provisions the device
-     * which involves accessing the provisioning server and can take a variable time to
-     * complete depending on the network connectivity.
-     * When needed, the provisioning will be launched  in the background.
-     * The listener {@link DrmEventCallback#onDrmPrepared}
-     * will be called when provisioning and preparation are finished. The application should
-     * check the status code returned with {@link DrmEventCallback#onDrmPrepared} to proceed.
-     * <p>
-     * The registered {@link DrmEventCallback#onDrmPrepared} is called to indicate the DRM
-     * session being ready. The application should not make any assumption about its call
-     * sequence (e.g., before or after prepareDrm returns).
-     * <p>
-     *
-     * @param dsd The DRM protected data source
-     *
-     * @param uuid The UUID of the crypto scheme. If not known beforehand, it can be retrieved
-     * from the source listening to {@link DrmEventCallback#onDrmInfo}.
-     *
-     * @return a token which can be used to cancel the operation later with {@link #cancelCommand}.
-     * @hide
-     */
-    // This is an asynchronous call.
-    @TestApi
-    public @NonNull Object prepareDrm(@NonNull DataSourceDesc dsd, @NonNull UUID uuid) {
-        return addTask(newPrepareDrmTask(dsd, uuid));
-    }
-
-    private Task newPrepareDrmTask(DataSourceDesc dsd, UUID uuid) {
-        return new Task(CALL_COMPLETED_PREPARE_DRM, true) {
-            @Override
-            void process() {
-                final SourceInfo sourceInfo = getSourceInfo(dsd);
-                int status = PREPARE_DRM_STATUS_PREPARATION_ERROR;
-                boolean finishPrepare = true;
-
-                if (sourceInfo == null) {
-                    Log.e(TAG, "prepareDrm(): DataSource not found.");
-                } else if (sourceInfo.mDrmInfo == null) {
-                    // only allowing if tied to a protected source;
-                    // might relax for releasing offline keys
-                    Log.e(TAG, "prepareDrm(): Wrong usage: The player must be prepared and "
-                            + "DRM info be retrieved before this call.");
-                } else {
-                    status = PREPARE_DRM_STATUS_SUCCESS;
-                }
-
-                try {
-                    if (status == PREPARE_DRM_STATUS_SUCCESS) {
-                        sourceInfo.mDrmHandle.prepare(uuid);
-                    }
-                } catch (ResourceBusyException e) {
-                    status = PREPARE_DRM_STATUS_RESOURCE_BUSY;
-                } catch (UnsupportedSchemeException e) {
-                    status = PREPARE_DRM_STATUS_UNSUPPORTED_SCHEME;
-                } catch (NotProvisionedException e) {
-                    Log.w(TAG, "prepareDrm: NotProvisionedException");
-
-                    // handle provisioning internally; it'll reset mPrepareDrmInProgress
-                    status = sourceInfo.mDrmHandle.handleProvisioninig(uuid, mTaskId);
-
-                    if (status == PREPARE_DRM_STATUS_SUCCESS) {
-                        // License will be setup in provisioning
-                        finishPrepare = false;
-                    } else {
-                        synchronized (sourceInfo.mDrmHandle) {
-                            sourceInfo.mDrmHandle.cleanDrmObj();
-                        }
-
-                        switch (status) {
-                            case PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR:
-                                Log.e(TAG, "prepareDrm: Provisioning was required but failed "
-                                        + "due to a network error.");
-                                break;
-
-                            case PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR:
-                                Log.e(TAG, "prepareDrm: Provisioning was required but the request "
-                                        + "was denied by the server.");
-                                break;
-
-                            case PREPARE_DRM_STATUS_PREPARATION_ERROR:
-                            default:
-                                Log.e(TAG, "prepareDrm: Post-provisioning preparation failed.");
-                                break;
-                        }
-                    }
-                } catch (Exception e) {
-                    status = PREPARE_DRM_STATUS_PREPARATION_ERROR;
-                }
-
-                if (finishPrepare) {
-                    sourceInfo.mDrmHandle.finishPrepare(status);
-                    synchronized (mTaskLock) {
-                        mCurrentTask = null;
-                        processPendingTask_l();
-                    }
-                }
-
-            }
-        };
-    }
-
-    /**
-     * Releases the DRM session for the given data source
-     * <p>
-     * The player has to have an active DRM session and be in stopped, or prepared
-     * state before this call is made.
-     * A {@link #reset()} call will release the DRM session implicitly.
-     *
-     * @param dsd The DRM protected data source
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session to release
-     * @hide
-     */
-    // This is a synchronous call.
-    @TestApi
-    public void releaseDrm(@NonNull DataSourceDesc dsd)
-            throws NoDrmSchemeException {
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            sourceInfo.mDrmHandle.release();
-        }
-    }
-
-    private native void native_releaseDrm(long mSrcId);
-
-    /**
-     * A key request/response exchange occurs between the app and a license server
-     * to obtain or release keys used to decrypt the given data source.
-     * <p>
-     * {@code getDrmKeyRequest()} is used to obtain an opaque key request byte array that is
-     * delivered to the license server.  The opaque key request byte array is returned
-     * in KeyRequest.data.  The recommended URL to deliver the key request to is
-     * returned in {@code KeyRequest.defaultUrl}.
-     * <p>
-     * After the app has received the key request response from the server,
-     * it should deliver to the response to the DRM engine plugin using the method
-     * {@link #provideDrmKeyResponse(DataSourceDesc, byte[], byte[])}.
-     *
-     * @param dsd the DRM protected data source
-     *
-     * @param keySetId is the key-set identifier of the offline keys being released when keyType is
-     * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
-     * keyType is {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}.
-     *
-     * @param initData is the container-specific initialization data when the keyType is
-     * {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. Its meaning is
-     * interpreted based on the mime type provided in the mimeType parameter.  It could
-     * contain, for example, the content ID, key ID or other data obtained from the content
-     * metadata that is required in generating the key request.
-     * When the keyType is {@link MediaDrm#KEY_TYPE_RELEASE}, it should be set to null.
-     *
-     * @param mimeType identifies the mime type of the content
-     *
-     * @param keyType specifies the type of the request. The request may be to acquire
-     * keys for streaming, {@link MediaDrm#KEY_TYPE_STREAMING}, or for offline content
-     * {@link MediaDrm#KEY_TYPE_OFFLINE}, or to release previously acquired
-     * keys ({@link MediaDrm#KEY_TYPE_RELEASE}), which are identified by a keySetId.
-     *
-     * @param optionalParameters are included in the key request message to
-     * allow a client application to provide additional message parameters to the server.
-     * This may be {@code null} if no additional parameters are to be sent.
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session
-     * @hide
-     */
-    @TestApi
-    public MediaDrm.KeyRequest getDrmKeyRequest(
-            @NonNull DataSourceDesc dsd,
-            @Nullable byte[] keySetId, @Nullable byte[] initData,
-            @Nullable String mimeType, @MediaDrmKeyType int keyType,
-            @Nullable Map<String, String> optionalParameters)
-            throws NoDrmSchemeException {
-        Log.v(TAG, "getDrmKeyRequest: " +
-                " keySetId: " + keySetId + " initData:" + initData + " mimeType: " + mimeType +
-                " keyType: " + keyType + " optionalParameters: " + optionalParameters);
-
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            return sourceInfo.mDrmHandle.getDrmKeyRequest(
-                    keySetId, initData, mimeType, keyType, optionalParameters);
-        }
-        return null;
-    }
-
-    /**
-     * A key response is received from the license server by the app for the given DRM protected
-     * data source, then provided to the DRM engine plugin using {@code provideDrmKeyResponse}.
-     * <p>
-     * When the response is for an offline key request, a key-set identifier is returned that
-     * can be used to later restore the keys to a new session with the method
-     * {@link #restoreDrmKeys(DataSourceDesc, byte[])}.
-     * When the response is for a streaming or release request, null is returned.
-     *
-     * @param dsd the DRM protected data source
-     *
-     * @param keySetId When the response is for a release request, keySetId identifies the saved
-     * key associated with the release request (i.e., the same keySetId passed to the earlier
-     * {@link # getDrmKeyRequest(DataSourceDesc, byte[], byte[], String, int, Map)} call).
-     * It MUST be null when the response is for either streaming or offline key requests.
-     *
-     * @param response the byte array response from the server
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session
-     * @throws DeniedByServerException if the response indicates that the
-     * server rejected the request
-     * @hide
-     */
-    // This is a synchronous call.
-    @TestApi
-    public byte[] provideDrmKeyResponse(
-            @NonNull DataSourceDesc dsd,
-            @Nullable byte[] keySetId, @NonNull byte[] response)
-            throws NoDrmSchemeException, DeniedByServerException {
-        Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId + " response: " + response);
-
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            return sourceInfo.mDrmHandle.provideDrmKeyResponse(keySetId, response);
-        }
-        return null;
-    }
-
-    /**
-     * Restore persisted offline keys into a new session for the given DRM protected data source.
-     * {@code keySetId} identifies the keys to load, obtained from a prior call to
-     * {@link #provideDrmKeyResponse(DataSourceDesc, byte[], byte[])}.
-     *
-     * @param dsd the DRM protected data source
-     *
-     * @param keySetId identifies the saved key set to restore
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session
-     * @hide
-     */
-    // This is a synchronous call.
-    @TestApi
-    public void restoreDrmKeys(
-            @NonNull DataSourceDesc dsd,
-            @NonNull byte[] keySetId)
-            throws NoDrmSchemeException {
-        Log.v(TAG, "restoreDrmKeys: keySetId: " + keySetId);
-
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            sourceInfo.mDrmHandle.restoreDrmKeys(keySetId);
-        }
-    }
-
-    /**
-     * Read a DRM engine plugin String property value, given the DRM protected data source
-     * and property name string.
-     *
-     * @param dsd the DRM protected data source
-     *
-     * @param propertyName the property name
-     *
-     * Standard fields names are:
-     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
-     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session
-     * @hide
-     */
-    @TestApi
-    public String getDrmPropertyString(
-            @NonNull DataSourceDesc dsd,
-            @NonNull @MediaDrmStringProperty String propertyName)
-            throws NoDrmSchemeException {
-        Log.v(TAG, "getDrmPropertyString: propertyName: " + propertyName);
-
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            return sourceInfo.mDrmHandle.getDrmPropertyString(propertyName);
-        }
-        return null;
-    }
-
-    /**
-     * Set a DRM engine plugin String property value for the given data source.
-     *
-     * @param dsd the DRM protected data source
-     * @param propertyName the property name
-     * @param value the property value
-     *
-     * Standard fields names are:
-     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
-     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
-     *
-     * @throws NoDrmSchemeException if there is no active DRM session
-     * @hide
-     */
-    // This is a synchronous call.
-    @TestApi
-    public void setDrmPropertyString(
-            @NonNull DataSourceDesc dsd,
-            @NonNull @MediaDrmStringProperty String propertyName, @NonNull String value)
-            throws NoDrmSchemeException {
-        // TODO: this implementation only works when dsd is the only data source
-        Log.v(TAG, "setDrmPropertyString: propertyName: " + propertyName + " value: " + value);
-
-        final SourceInfo sourceInfo = getSourceInfo(dsd);
-        if (sourceInfo != null) {
-            sourceInfo.mDrmHandle.setDrmPropertyString(propertyName, value);
-        }
-    }
-
-    /**
-     * Encapsulates the DRM properties of the source.
-     */
-    public static final class DrmInfo {
-        private Map<UUID, byte[]> mMapPssh;
-        private UUID[] mSupportedSchemes;
-
-        /**
-         * Returns the PSSH info of the data source for each supported DRM scheme.
-         */
-        public @NonNull Map<UUID, byte[]> getPssh() {
-            return mMapPssh;
-        }
-
-        /**
-         * Returns the intersection of the data source and the device DRM schemes.
-         * It effectively identifies the subset of the source's DRM schemes which
-         * are supported by the device too.
-         */
-        public @NonNull List<UUID> getSupportedSchemes() {
-            return Arrays.asList(mSupportedSchemes);
-        }
-
-        private DrmInfo(Map<UUID, byte[]> pssh, UUID[] supportedSchemes) {
-            mMapPssh = pssh;
-            mSupportedSchemes = supportedSchemes;
-        }
-
-        private static DrmInfo create(PlayerMessage msg) {
-            Log.v(TAG, "DrmInfo.create(" + msg + ")");
-
-            Iterator<Value> in = msg.getValuesList().iterator();
-            byte[] pssh = in.next().getBytesValue().toByteArray();
-
-            Log.v(TAG, "DrmInfo.create() PSSH: " + DrmInfo.arrToHex(pssh));
-            Map<UUID, byte[]> mapPssh = DrmInfo.parsePSSH(pssh, pssh.length);
-            Log.v(TAG, "DrmInfo.create() PSSH: " + mapPssh);
-
-            int supportedDRMsCount = in.next().getInt32Value();
-            UUID[] supportedSchemes = new UUID[supportedDRMsCount];
-            for (int i = 0; i < supportedDRMsCount; i++) {
-                byte[] uuid = new byte[16];
-                in.next().getBytesValue().copyTo(uuid, 0);
-
-                supportedSchemes[i] = DrmInfo.bytesToUUID(uuid);
-
-                Log.v(TAG, "DrmInfo() supportedScheme[" + i + "]: " + supportedSchemes[i]);
-            }
-
-            Log.v(TAG, "DrmInfo.create() psshsize: " + pssh.length
-                    + " supportedDRMsCount: " + supportedDRMsCount);
-            return new DrmInfo(mapPssh, supportedSchemes);
-        }
-
-        private DrmInfo makeCopy() {
-            return new DrmInfo(this.mMapPssh, this.mSupportedSchemes);
-        }
-
-        private static String arrToHex(byte[] bytes) {
-            String out = "0x";
-            for (int i = 0; i < bytes.length; i++) {
-                out += String.format("%02x", bytes[i]);
-            }
-
-            return out;
-        }
-
-        private static UUID bytesToUUID(byte[] uuid) {
-            long msb = 0, lsb = 0;
-            for (int i = 0; i < 8; i++) {
-                msb |= (((long) uuid[i]     & 0xff) << (8 * (7 - i)));
-                lsb |= (((long) uuid[i + 8] & 0xff) << (8 * (7 - i)));
-            }
-
-            return new UUID(msb, lsb);
-        }
-
-        private static Map<UUID, byte[]> parsePSSH(byte[] pssh, int psshsize) {
-            Map<UUID, byte[]> result = new HashMap<UUID, byte[]>();
-
-            final int uuidSize = 16;
-            final int dataLenSize = 4;
-
-            int len = psshsize;
-            int numentries = 0;
-            int i = 0;
-
-            while (len > 0) {
-                if (len < uuidSize) {
-                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
-                                             + "UUID: (%d < 16) pssh: %d", len, psshsize));
-                    return null;
-                }
-
-                byte[] subset = Arrays.copyOfRange(pssh, i, i + uuidSize);
-                UUID uuid = bytesToUUID(subset);
-                i += uuidSize;
-                len -= uuidSize;
-
-                // get data length
-                if (len < 4) {
-                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
-                                             + "datalen: (%d < 4) pssh: %d", len, psshsize));
-                    return null;
-                }
-
-                subset = Arrays.copyOfRange(pssh, i, i + dataLenSize);
-                int datalen = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN)
-                        ? ((subset[3] & 0xff) << 24) | ((subset[2] & 0xff) << 16)
-                        | ((subset[1] & 0xff) <<  8) |  (subset[0] & 0xff)        :
-                        ((subset[0] & 0xff) << 24) | ((subset[1] & 0xff) << 16)
-                        | ((subset[2] & 0xff) <<  8) |  (subset[3] & 0xff);
-                i += dataLenSize;
-                len -= dataLenSize;
-
-                if (len < datalen) {
-                    Log.w(TAG, String.format("parsePSSH: len is too short to parse "
-                                             + "data: (%d < %d) pssh: %d", len, datalen, psshsize));
-                    return null;
-                }
-
-                byte[] data = Arrays.copyOfRange(pssh, i, i + datalen);
-
-                // skip the data
-                i += datalen;
-                len -= datalen;
-
-                Log.v(TAG, String.format("parsePSSH[%d]: <%s, %s> pssh: %d",
-                                         numentries, uuid, arrToHex(data), psshsize));
-                numentries++;
-                result.put(uuid, data);
-            }
-
-            return result;
-        }
-    };  // DrmInfo
-
-    /**
-     * Thrown when a DRM method is called when there is no active DRM session.
-     * Extends MediaDrm.MediaDrmException
-     */
-    public static final class NoDrmSchemeException extends MediaDrmException {
-        public NoDrmSchemeException(@Nullable String detailMessage) {
-            super(detailMessage);
-        }
-    }
-
-    private native void native_prepareDrm(
-            long srcId, @NonNull byte[] uuid, @NonNull byte[] drmSessionId);
-
-    // Instantiated from the native side
-    @SuppressWarnings("unused")
-    private static class StreamEventCallback extends AudioTrack.StreamEventCallback {
-        public long mJAudioTrackPtr;
-        public long mNativeCallbackPtr;
-        public long mUserDataPtr;
-
-        StreamEventCallback(long jAudioTrackPtr, long nativeCallbackPtr, long userDataPtr) {
-            super();
-            mJAudioTrackPtr = jAudioTrackPtr;
-            mNativeCallbackPtr = nativeCallbackPtr;
-            mUserDataPtr = userDataPtr;
-        }
-
-        @Override
-        public void onTearDown(AudioTrack track) {
-            native_stream_event_onTearDown(mNativeCallbackPtr, mUserDataPtr);
-        }
-
-        @Override
-        public void onPresentationEnded(AudioTrack track) {
-            native_stream_event_onStreamPresentationEnd(mNativeCallbackPtr, mUserDataPtr);
-        }
-
-        @Override
-        public void onDataRequest(AudioTrack track, int size) {
-            native_stream_event_onStreamDataRequest(
-                    mJAudioTrackPtr, mNativeCallbackPtr, mUserDataPtr);
-        }
-    }
-
-    /**
-     * Returns a byte[] containing the remainder of 'in', closing it when done.
-     */
-    private static byte[] readInputStreamFully(InputStream in) throws IOException {
-        try {
-            return readInputStreamFullyNoClose(in);
-        } finally {
-            in.close();
-        }
-    }
-
-    /**
-     * Returns a byte[] containing the remainder of 'in'.
-     */
-    private static byte[] readInputStreamFullyNoClose(InputStream in) throws IOException {
-        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-        byte[] buffer = new byte[1024];
-        int count;
-        while ((count = in.read(buffer)) != -1) {
-            bytes.write(buffer, 0, count);
-        }
-        return bytes.toByteArray();
-    }
-
-    private static byte[] getByteArrayFromUUID(@NonNull UUID uuid) {
-        long msb = uuid.getMostSignificantBits();
-        long lsb = uuid.getLeastSignificantBits();
-
-        byte[] uuidBytes = new byte[16];
-        for (int i = 0; i < 8; ++i) {
-            uuidBytes[i] = (byte) (msb >>> (8 * (7 - i)));
-            uuidBytes[8 + i] = (byte) (lsb >>> (8 * (7 - i)));
-        }
-
-        return uuidBytes;
-    }
-
-    private static class TimedTextUtil {
-        // These keys must be in sync with the keys in TextDescription2.h
-        private static final int KEY_START_TIME                     = 7; // int
-        private static final int KEY_STRUCT_TEXT_POS               = 14; // TextPos
-        private static final int KEY_STRUCT_TEXT                   = 16; // Text
-        private static final int KEY_GLOBAL_SETTING               = 101;
-        private static final int KEY_LOCAL_SETTING                = 102;
-
-        private static TimedText parsePlayerMessage(PlayerMessage playerMsg) {
-            if (playerMsg.getValuesCount() == 0) {
-                return null;
-            }
-
-            String textChars = null;
-            Rect textBounds = null;
-            Iterator<Value> in = playerMsg.getValuesList().iterator();
-            int type = in.next().getInt32Value();
-            if (type == KEY_LOCAL_SETTING) {
-                type = in.next().getInt32Value();
-                if (type != KEY_START_TIME) {
-                    return null;
-                }
-                int startTimeMs = in.next().getInt32Value();
-
-                type = in.next().getInt32Value();
-                if (type != KEY_STRUCT_TEXT) {
-                    return null;
-                }
-
-                byte[] text = in.next().getBytesValue().toByteArray();
-                if (text == null || text.length == 0) {
-                    textChars = null;
-                } else {
-                    textChars = new String(text);
-                }
-
-            } else if (type != KEY_GLOBAL_SETTING) {
-                Log.w(TAG, "Invalid timed text key found: " + type);
-                return null;
-            }
-            if (in.hasNext()) {
-                type = in.next().getInt32Value();
-                if (type == KEY_STRUCT_TEXT_POS) {
-                    int top = in.next().getInt32Value();
-                    int left = in.next().getInt32Value();
-                    int bottom = in.next().getInt32Value();
-                    int right = in.next().getInt32Value();
-                    textBounds = new Rect(left, top, right, bottom);
-                }
-            }
-            return null;
-            /* TimedText c-tor usage is temporarily commented out.
-             * TODO(b/117527789): use SUBTITLE path for MEDIA_MIMETYPE_TEXT_3GPP track
-             *                    and remove TimedText path from MediaPlayer2.
-            return new TimedText(textChars, textBounds);
-            */
-        }
-    }
-
-    private Object addTask(Task task) {
-        synchronized (mTaskLock) {
-            mPendingTasks.add(task);
-            processPendingTask_l();
-        }
-        return task;
-    }
-
-    @GuardedBy("mTaskLock")
-    private void processPendingTask_l() {
-        if (mCurrentTask != null) {
-            return;
-        }
-        if (!mPendingTasks.isEmpty()) {
-            Task task = mPendingTasks.remove(0);
-            mCurrentTask = task;
-            mTaskHandler.post(task);
-        }
-    }
-
-    private abstract class Task implements Runnable {
-        final long mTaskId = mTaskIdGenerator.getAndIncrement();
-        private final int mMediaCallType;
-        private final boolean mNeedToWaitForEventToComplete;
-        private DataSourceDesc mDSD;
-
-        Task(int mediaCallType, boolean needToWaitForEventToComplete) {
-            mMediaCallType = mediaCallType;
-            mNeedToWaitForEventToComplete = needToWaitForEventToComplete;
-        }
-
-        abstract void process() throws IOException, NoDrmSchemeException;
-
-        @Override
-        public void run() {
-            int status = CALL_STATUS_NO_ERROR;
-            try {
-                if (mMediaCallType != CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED
-                        && getState() == PLAYER_STATE_ERROR) {
-                    status = CALL_STATUS_INVALID_OPERATION;
-                } else {
-                    if (mMediaCallType == CALL_COMPLETED_SEEK_TO) {
-                        synchronized (mTaskLock) {
-                            if (!mPendingTasks.isEmpty()) {
-                                Task nextTask = mPendingTasks.get(0);
-                                if (nextTask.mMediaCallType == mMediaCallType) {
-                                    throw new CommandSkippedException(
-                                            "consecutive seekTo is skipped except last one");
-                                }
-                            }
-                        }
-                    }
-                    process();
-                }
-            } catch (IllegalStateException e) {
-                status = CALL_STATUS_INVALID_OPERATION;
-            } catch (IllegalArgumentException e) {
-                status = CALL_STATUS_BAD_VALUE;
-            } catch (SecurityException e) {
-                status = CALL_STATUS_PERMISSION_DENIED;
-            } catch (IOException e) {
-                status = CALL_STATUS_ERROR_IO;
-            } catch (NoDrmSchemeException e) {
-                status = CALL_STATUS_NO_DRM_SCHEME;
-            } catch (CommandSkippedException e) {
-                status = CALL_STATUS_SKIPPED;
-            } catch (Exception e) {
-                status = CALL_STATUS_ERROR_UNKNOWN;
-            }
-            mDSD = getCurrentDataSource();
-
-            if (mMediaCallType != CALL_COMPLETED_SEEK_TO) {
-                synchronized (mTaskLock) {
-                    mIsPreviousCommandSeekTo = false;
-                }
-            }
-
-            // TODO: Make native implementations asynchronous and let them send notifications.
-            if (!mNeedToWaitForEventToComplete || status != CALL_STATUS_NO_ERROR) {
-
-                sendCompleteNotification(status);
-
-                synchronized (mTaskLock) {
-                    mCurrentTask = null;
-                    processPendingTask_l();
-                }
-            }
-        }
-
-        private void sendCompleteNotification(int status) {
-            // In {@link #notifyWhenCommandLabelReached} case, a separate callback
-            // {@link #onCommandLabelReached} is already called in {@code process()}.
-            // CALL_COMPLETED_PREPARE_DRM is sent via DrmEventCallback#onDrmPrepared
-            if (mMediaCallType == CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED
-                    || mMediaCallType == CALL_COMPLETED_PREPARE_DRM) {
-                return;
-            }
-            sendEvent(new EventNotifier() {
-                @Override
-                public void notify(EventCallback callback) {
-                    callback.onCallCompleted(
-                            MediaPlayer2.this, mDSD, mMediaCallType, status);
-                }
-            });
-        }
-    };
-
-    private final class CommandSkippedException extends RuntimeException {
-        CommandSkippedException(String detailMessage) {
-            super(detailMessage);
-        }
-    };
-
-    // Modular DRM
-    private final Map<UUID, MediaDrm> mDrmObjs = Collections.synchronizedMap(new HashMap<>());
-    private class DrmHandle {
-
-        static final int PROVISION_TIMEOUT_MS = 60000;
-
-        final DataSourceDesc mDSD;
-        final long mSrcId;
-
-        //--- guarded by |this| start
-        MediaDrm mDrmObj;
-        byte[] mDrmSessionId;
-        UUID mActiveDrmUUID;
-        boolean mDrmConfigAllowed;
-        boolean mDrmProvisioningInProgress;
-        boolean mPrepareDrmInProgress;
-        Future<?> mProvisionResult;
-        DrmPreparationInfo mPrepareInfo;
-        //--- guarded by |this| end
-
-        DrmHandle(DataSourceDesc dsd, long srcId) {
-            mDSD = dsd;
-            mSrcId = srcId;
-        }
-
-        void prepare(UUID uuid) throws UnsupportedSchemeException,
-                ResourceBusyException, NotProvisionedException, InterruptedException,
-                ExecutionException, TimeoutException {
-            Log.v(TAG, "prepareDrm: uuid: " + uuid);
-
-            synchronized (this) {
-                if (mActiveDrmUUID != null) {
-                    final String msg = "prepareDrm(): Wrong usage: There is already "
-                            + "an active DRM scheme with " + uuid;
-                    Log.e(TAG, msg);
-                    throw new IllegalStateException(msg);
-                }
-
-                if (mPrepareDrmInProgress) {
-                    final String msg = "prepareDrm(): Wrong usage: There is already "
-                            + "a pending prepareDrm call.";
-                    Log.e(TAG, msg);
-                    throw new IllegalStateException(msg);
-                }
-
-                if (mDrmProvisioningInProgress) {
-                    final String msg = "prepareDrm(): Unexpectd: Provisioning already in progress";
-                    Log.e(TAG, msg);
-                    throw new IllegalStateException(msg);
-                }
-
-                // shouldn't need this; just for safeguard
-                cleanDrmObj();
-
-                mPrepareDrmInProgress = true;
-
-                try {
-                    // only creating the DRM object to allow pre-openSession configuration
-                    prepareDrm_createDrmStep(uuid);
-                } catch (Exception e) {
-                    Log.w(TAG, "prepareDrm(): Exception ", e);
-                    mPrepareDrmInProgress = false;
-                    throw e;
-                }
-
-                mDrmConfigAllowed = true;
-            }  // synchronized
-
-            // call the callback outside the lock
-            sendDrmEventWait(new DrmEventNotifier<Void>() {
-                @Override
-                public Void notifyWait(DrmEventCallback callback) {
-                    callback.onDrmConfig(MediaPlayer2.this, mDSD, mDrmObj);
-                    return null;
-                }
-            });
-
-            synchronized (this) {
-                mDrmConfigAllowed = false;
-                boolean earlyExit = false;
-
-                try {
-                    prepareDrm_openSessionStep(uuid);
-
-                    this.mActiveDrmUUID = uuid;
-                    mPrepareDrmInProgress = false;
-                } catch (IllegalStateException e) {
-                    final String msg = "prepareDrm(): Wrong usage: The player must be "
-                            + "in the prepared state to call prepareDrm().";
-                    Log.e(TAG, msg);
-                    earlyExit = true;
-                    mPrepareDrmInProgress = false;
-                    throw new IllegalStateException(msg);
-                } catch (NotProvisionedException e) {
-                    Log.w(TAG, "prepareDrm: NotProvisionedException", e);
-                    throw e;
-                } catch (Exception e) {
-                    Log.e(TAG, "prepareDrm: Exception " + e);
-                    earlyExit = true;
-                    mPrepareDrmInProgress = false;
-                    throw e;
-                } finally {
-                    if (earlyExit) {  // clean up object if didn't succeed
-                        cleanDrmObj();
-                    }
-                }  // finally
-            }  // synchronized
-        }
-
-        void prepareDrm_createDrmStep(UUID uuid)
-                throws UnsupportedSchemeException {
-            Log.v(TAG, "prepareDrm_createDrmStep: UUID: " + uuid);
-
-            try {
-                mDrmObj = mDrmObjs.computeIfAbsent(uuid, scheme -> {
-                    try {
-                        return new MediaDrm(scheme);
-                    } catch (UnsupportedSchemeException e) {
-                        throw new IllegalArgumentException(e);
-                    }
-                });
-                Log.v(TAG, "prepareDrm_createDrmStep: Created mDrmObj=" + mDrmObj);
-            } catch (Exception e) { // UnsupportedSchemeException
-                Log.e(TAG, "prepareDrm_createDrmStep: MediaDrm failed with " + e);
-                throw e;
-            }
-        }
-
-        void prepareDrm_openSessionStep(UUID uuid)
-                throws NotProvisionedException, ResourceBusyException {
-            Log.v(TAG, "prepareDrm_openSessionStep: uuid: " + uuid);
-
-            // TODO:
-            // don't need an open session for a future specialKeyReleaseDrm mode but we should do
-            // it anyway so it raises provisioning error if needed. We'd rather handle provisioning
-            // at prepareDrm/openSession rather than getDrmKeyRequest/provideDrmKeyResponse
-            try {
-                mDrmSessionId = mDrmObj.openSession();
-                Log.v(TAG, "prepareDrm_openSessionStep: mDrmSessionId=" + mDrmSessionId);
-
-                // Sending it down to native/mediaserver to create the crypto object
-                // This call could simply fail due to bad player state, e.g., after play().
-                final MediaPlayer2 mp2 = MediaPlayer2.this;
-                mp2.native_prepareDrm(mSrcId, getByteArrayFromUUID(uuid), mDrmSessionId);
-                Log.v(TAG, "prepareDrm_openSessionStep: native_prepareDrm/Crypto succeeded");
-
-            } catch (Exception e) { //ResourceBusyException, NotProvisionedException
-                Log.e(TAG, "prepareDrm_openSessionStep: open/crypto failed with " + e);
-                throw e;
-            }
-
-        }
-
-        int handleProvisioninig(UUID uuid, long taskId) {
-            synchronized (this) {
-                if (mDrmProvisioningInProgress) {
-                    Log.e(TAG, "handleProvisioninig: Unexpected mDrmProvisioningInProgress");
-                    return PREPARE_DRM_STATUS_PREPARATION_ERROR;
-                }
-
-                MediaDrm.ProvisionRequest provReq = mDrmObj.getProvisionRequest();
-                if (provReq == null) {
-                    Log.e(TAG, "handleProvisioninig: getProvisionRequest returned null.");
-                    return PREPARE_DRM_STATUS_PREPARATION_ERROR;
-                }
-
-                Log.v(TAG, "handleProvisioninig provReq "
-                        + " data: " + provReq.getData() + " url: " + provReq.getDefaultUrl());
-
-                // networking in a background thread
-                mDrmProvisioningInProgress = true;
-
-                mProvisionResult = sDrmThreadPool.submit(newProvisioningTask(uuid, taskId));
-
-                return PREPARE_DRM_STATUS_SUCCESS;
-            }
-        }
-
-        void provision(UUID uuid, long taskId) {
-
-            MediaDrm.ProvisionRequest provReq = mDrmObj.getProvisionRequest();
-            String urlStr = provReq.getDefaultUrl();
-            urlStr += "&signedRequest=" + new String(provReq.getData());
-            Log.v(TAG, "handleProvisioninig: Thread is initialised url: " + urlStr);
-
-            byte[] response = null;
-            boolean provisioningSucceeded = false;
-            int status = PREPARE_DRM_STATUS_PREPARATION_ERROR;
-            try {
-                URL url = new URL(urlStr);
-                final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-                try {
-                    connection.setRequestMethod("POST");
-                    connection.setDoOutput(false);
-                    connection.setDoInput(true);
-                    connection.setConnectTimeout(PROVISION_TIMEOUT_MS);
-                    connection.setReadTimeout(PROVISION_TIMEOUT_MS);
-
-                    connection.connect();
-                    response = readInputStreamFully(connection.getInputStream());
-
-                    Log.v(TAG, "handleProvisioninig: Thread run: response " +
-                            response.length + " " + response);
-                } catch (Exception e) {
-                    status = PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR;
-                    Log.w(TAG, "handleProvisioninig: Thread run: connect " + e + " url: " + url);
-                } finally {
-                    connection.disconnect();
-                }
-            } catch (Exception e)   {
-                status = PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR;
-                Log.w(TAG, "handleProvisioninig: Thread run: openConnection " + e);
-            }
-
-            if (response != null) {
-                try {
-                    mDrmObj.provideProvisionResponse(response);
-                    Log.v(TAG, "handleProvisioninig: Thread run: " +
-                            "provideProvisionResponse SUCCEEDED!");
-
-                    provisioningSucceeded = true;
-                } catch (Exception e) {
-                    status = PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR;
-                    Log.w(TAG, "handleProvisioninig: Thread run: " +
-                            "provideProvisionResponse " + e);
-                }
-            }
-
-            boolean succeeded = false;
-
-            synchronized (this) {
-                // continuing with prepareDrm
-                if (provisioningSucceeded) {
-                    succeeded = resumePrepare(uuid);
-                    status = (succeeded) ?
-                            PREPARE_DRM_STATUS_SUCCESS :
-                            PREPARE_DRM_STATUS_PREPARATION_ERROR;
-                }
-                mDrmProvisioningInProgress = false;
-                mPrepareDrmInProgress = false;
-                if (!succeeded) {
-                    cleanDrmObj();  // cleaning up if it hasn't gone through while in the lock
-                }
-            }  // synchronized
-
-            // calling the callback outside the lock
-            finishPrepare(status);
-
-            synchronized (mTaskLock) {
-                if (mCurrentTask != null
-                        && mCurrentTask.mTaskId == taskId
-                        && mCurrentTask.mMediaCallType == CALL_COMPLETED_PREPARE_DRM
-                        && mCurrentTask.mNeedToWaitForEventToComplete) {
-                    mCurrentTask = null;
-                    processPendingTask_l();
-                }
-            }
-        }
-
-        Runnable newProvisioningTask(UUID uuid, long taskId) {
-            return new Runnable() {
-                @Override
-                public void run() {
-                    provision(uuid, taskId);
-                }
-            };
-        }
-
-        boolean resumePrepare(UUID uuid) {
-            Log.v(TAG, "resumePrepareDrm: uuid: " + uuid);
-
-            // mDrmLock is guaranteed to be held
-            boolean success = false;
-            try {
-                // resuming
-                prepareDrm_openSessionStep(uuid);
-
-                this.mActiveDrmUUID = uuid;
-
-                success = true;
-            } catch (Exception e) {
-                Log.w(TAG, "handleProvisioninig: Thread run native_prepareDrm resume failed:" + e);
-                // mDrmObj clean up is done by the caller
-            }
-
-            return success;
-        }
-
-        synchronized boolean setPreparationInfo(DrmPreparationInfo prepareInfo) {
-            if (prepareInfo == null || !prepareInfo.isValid() || mPrepareInfo != null) {
-                return false;
-            }
-            mPrepareInfo = prepareInfo;
-            return true;
-        }
-
-        void finishPrepare(int status) {
-            if (status != PREPARE_DRM_STATUS_SUCCESS) {
-                notifyPrepared(status, null);
-                return;
-            }
-
-            if (mPrepareInfo == null) {
-                // Deprecated: this can only happen when using MediaPlayer Version 1 APIs
-                notifyPrepared(status, null);
-                return;
-            }
-
-            final byte[] keySetId = mPrepareInfo.mKeySetId;
-            if (keySetId != null) {
-                try {
-                    mDrmObj.restoreKeys(mDrmSessionId, keySetId);
-                    notifyPrepared(PREPARE_DRM_STATUS_SUCCESS, keySetId);
-                } catch (Exception e) {
-                    notifyPrepared(PREPARE_DRM_STATUS_RESTORE_ERROR, keySetId);
-                }
-                return;
-            }
-
-            sDrmThreadPool.submit(newKeyExchangeTask());
-        }
-
-        Runnable newKeyExchangeTask() {
-            return new Runnable() {
-                @Override
-                public void run() {
-                    final byte[] initData = mPrepareInfo.mInitData;
-                    final String mimeType = mPrepareInfo.mMimeType;
-                    final int keyType = mPrepareInfo.mKeyType;
-                    final Map<String, String> optionalParams = mPrepareInfo.mOptionalParameters;
-                    byte[] keySetId = null;
-                    try {
-                        KeyRequest req;
-                        req = getDrmKeyRequest(null, initData, mimeType, keyType, optionalParams);
-                        byte[] response = sendDrmEventWait(new DrmEventNotifier<byte[]>() {
-                            @Override
-                            public byte[] notifyWait(DrmEventCallback callback) {
-                                final MediaPlayer2 mp = MediaPlayer2.this;
-                                return callback.onDrmKeyRequest(mp, mDSD, req);
-                            }
-                        });
-                        keySetId = provideDrmKeyResponse(null, response);
-                    } catch (Exception e) {
-                    }
-                    if (keySetId == null) {
-                        notifyPrepared(PREPARE_DRM_STATUS_KEY_EXCHANGE_ERROR, null);
-                    } else {
-                        notifyPrepared(PREPARE_DRM_STATUS_SUCCESS, keySetId);
-                    }
-                }
-            };
-        }
-
-        void notifyPrepared(final int status, byte[] keySetId) {
-
-            Message msg;
-            if (status == PREPARE_DRM_STATUS_SUCCESS) {
-                msg = mTaskHandler.obtainMessage(
-                        MEDIA_DRM_PREPARED, 0, 0, null);
-            } else {
-                msg = mTaskHandler.obtainMessage(
-                        MEDIA_ERROR, status, MEDIA_ERROR_UNKNOWN, null);
-            }
-            mTaskHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mTaskHandler.handleMessage(msg, mSrcId);
-                }
-            });
-
-            sendDrmEvent(new DrmEventNotifier() {
-                @Override
-                public void notify(DrmEventCallback callback) {
-                    callback.onDrmPrepared(MediaPlayer2.this, mDSD, status,
-                            keySetId);
-                }
-            });
-
-        }
-
-        void cleanDrmObj() {
-            // the caller holds mDrmLock
-            Log.v(TAG, "cleanDrmObj: mDrmObj=" + mDrmObj + " mDrmSessionId=" + mDrmSessionId);
-
-            if (mDrmSessionId != null)    {
-                mDrmObj.closeSession(mDrmSessionId);
-                mDrmSessionId = null;
-            }
-        }
-
-        void release() throws NoDrmSchemeException {
-            synchronized (this) {
-                Log.v(TAG, "releaseDrm:");
-
-                if (mActiveDrmUUID == null) {
-                    Log.e(TAG, "releaseDrm(): No active DRM scheme to release.");
-                    throw new NoDrmSchemeException(
-                            "releaseDrm: No active DRM scheme to release.");
-                }
-
-                try {
-                    // we don't have the player's state in this layer. The below call raises
-                    // exception if we're in a non-stopped/prepared state.
-
-                    // for cleaning native/mediaserver crypto object
-                    native_releaseDrm(mSrcId);
-
-                    // for cleaning client-side MediaDrm object; only called if above has succeeded
-                    cleanDrmObj();
-
-                    this.mActiveDrmUUID = null;
-                } catch (IllegalStateException e) {
-                    Log.w(TAG, "releaseDrm: Exception ", e);
-                    throw new IllegalStateException(
-                            "releaseDrm: The player is not in a valid state.");
-                } catch (Exception e) {
-                    Log.e(TAG, "releaseDrm: Exception ", e);
-                }
-            }  // synchronized
-        }
-
-        void cleanup() {
-            synchronized (this) {
-                Log.v(TAG, "cleanupDrm: " +
-                        " mProvisioningTask=" + mProvisionResult +
-                        " mPrepareDrmInProgress=" + mPrepareDrmInProgress +
-                        " mActiveDrmScheme=" + mActiveDrmUUID);
-
-                if (mProvisionResult != null) {
-                    // timeout; relying on HttpUrlConnection
-                    try {
-                        mProvisionResult.get();
-                    }
-                    catch (InterruptedException | ExecutionException e) {
-                        Log.w(TAG, "resetDrmState: ProvThread.join Exception " + e);
-                    }
-                }
-
-                // set to false to avoid duplicate release calls
-                this.mActiveDrmUUID = null;
-
-                native_releaseDrm(mSrcId);
-                cleanDrmObj();
-            }   // synchronized
-        }
-
-        Runnable newCleanupTask() {
-            return new Runnable() {
-                @Override
-                public void run() {
-                    cleanup();
-                }
-            };
-        }
-
-        MediaDrm.KeyRequest getDrmKeyRequest(
-                byte[] keySetId, byte[] initData,
-                String mimeType, int keyType,
-                Map<String, String> optionalParameters)
-                throws NoDrmSchemeException {
-            synchronized (this) {
-                if (mActiveDrmUUID == null) {
-                    Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
-                    throw new NoDrmSchemeException(
-                            "getDrmKeyRequest: Has to set a DRM scheme first.");
-                }
-
-                try {
-                    byte[] scope = (keyType != MediaDrm.KEY_TYPE_RELEASE) ?
-                            mDrmSessionId : // sessionId for KEY_TYPE_STREAMING/OFFLINE
-                            keySetId;                  // keySetId for KEY_TYPE_RELEASE
-
-                    HashMap<String, String> hmapOptionalParameters =
-                            (optionalParameters != null)
-                            ? new HashMap<String, String>(optionalParameters)
-                            : null;
-
-                    MediaDrm.KeyRequest request = mDrmObj.getKeyRequest(
-                            scope, initData, mimeType, keyType, hmapOptionalParameters);
-                    Log.v(TAG, "getDrmKeyRequest:   --> request: " + request);
-
-                    return request;
-
-                } catch (NotProvisionedException e) {
-                    Log.w(TAG, "getDrmKeyRequest NotProvisionedException: " +
-                            "Unexpected. Shouldn't have reached here.");
-                    throw new IllegalStateException("getDrmKeyRequest: provisioning error.");
-                } catch (Exception e) {
-                    Log.w(TAG, "getDrmKeyRequest Exception " + e);
-                    throw e;
-                }
-
-            }
-        }
-
-        byte[] provideDrmKeyResponse(byte[] keySetId, byte[] response)
-                throws NoDrmSchemeException, DeniedByServerException {
-            synchronized (this) {
-
-                if (mActiveDrmUUID == null) {
-                    Log.e(TAG, "getDrmKeyRequest NoDrmSchemeException");
-                    throw new NoDrmSchemeException(
-                            "getDrmKeyRequest: Has to set a DRM scheme first.");
-                }
-
-                try {
-                    byte[] scope = (keySetId == null) ?
-                                    mDrmSessionId : // sessionId for KEY_TYPE_STREAMING/OFFLINE
-                                    keySetId;                  // keySetId for KEY_TYPE_RELEASE
-
-                    byte[] keySetResult = mDrmObj.provideKeyResponse(scope, response);
-
-                    Log.v(TAG, "provideDrmKeyResponse: keySetId: " + keySetId
-                            + " response: " + response + " --> " + keySetResult);
-
-
-                    return keySetResult;
-
-                } catch (NotProvisionedException e) {
-                    Log.w(TAG, "provideDrmKeyResponse NotProvisionedException: " +
-                            "Unexpected. Shouldn't have reached here.");
-                    throw new IllegalStateException("provideDrmKeyResponse: " +
-                            "Unexpected provisioning error.");
-                } catch (Exception e) {
-                    Log.w(TAG, "provideDrmKeyResponse Exception " + e);
-                    throw e;
-                }
-            }
-        }
-
-        void restoreDrmKeys(byte[] keySetId)
-                throws NoDrmSchemeException {
-            synchronized (this) {
-                if (mActiveDrmUUID == null) {
-                    Log.w(TAG, "restoreDrmKeys NoDrmSchemeException");
-                    throw new NoDrmSchemeException(
-                            "restoreDrmKeys: Has to set a DRM scheme first.");
-                }
-
-                try {
-                    mDrmObj.restoreKeys(mDrmSessionId, keySetId);
-                } catch (Exception e) {
-                    Log.w(TAG, "restoreKeys Exception " + e);
-                    throw e;
-                }
-            }
-        }
-
-        String getDrmPropertyString(String propertyName)
-                throws NoDrmSchemeException {
-            String v;
-            synchronized (this) {
-
-                if (mActiveDrmUUID == null && !mDrmConfigAllowed) {
-                    Log.w(TAG, "getDrmPropertyString NoDrmSchemeException");
-                    throw new NoDrmSchemeException(
-                            "getDrmPropertyString: Has to prepareDrm() first.");
-                }
-
-                try {
-                    v = mDrmObj.getPropertyString(propertyName);
-                } catch (Exception e) {
-                    Log.w(TAG, "getDrmPropertyString Exception " + e);
-                    throw e;
-                }
-            }   // synchronized
-
-            Log.v(TAG, "getDrmPropertyString: propertyName: " + propertyName + " --> value: " + v);
-
-            return v;
-        }
-
-        void setDrmPropertyString(String propertyName, String value)
-                throws NoDrmSchemeException {
-            synchronized (this) {
-
-                if ( mActiveDrmUUID == null && !mDrmConfigAllowed ) {
-                    Log.w(TAG, "setDrmPropertyString NoDrmSchemeException");
-                    throw new NoDrmSchemeException(
-                            "setDrmPropertyString: Has to prepareDrm() first.");
-                }
-
-                try {
-                    mDrmObj.setPropertyString(propertyName, value);
-                } catch ( Exception e ) {
-                    Log.w(TAG, "setDrmPropertyString Exception " + e);
-                    throw e;
-                }
-            }
-        }
-
-    }
-
-    final class SourceInfo {
-        final DataSourceDesc mDSD;
-        final long mId = mSrcIdGenerator.getAndIncrement();
-        AtomicInteger mBufferedPercentage = new AtomicInteger(0);
-        boolean mClosed = false;
-        int mPrepareBarrier = 1;
-
-        // m*AsNextSource (below) only applies to pending data sources in the playlist;
-        // the meanings of mCurrentSourceInfo.{mStateAsNextSource,mPlayPendingAsNextSource}
-        // are undefined.
-        int mStateAsNextSource = NEXT_SOURCE_STATE_INIT;
-        boolean mPlayPendingAsNextSource = false;
-
-        // Modular DRM
-        final DrmHandle mDrmHandle;
-        DrmInfo mDrmInfo;
-        boolean mDrmInfoResolved;
-
-        SourceInfo(DataSourceDesc dsd) {
-            this.mDSD = dsd;
-            mDrmHandle = new DrmHandle(dsd, mId);
-        }
-
-        void close() {
-            synchronized (this) {
-                if (!mClosed) {
-                    if (mDSD != null) {
-                        mDSD.close();
-                    }
-                    mClosed = true;
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return String.format("%s(%d)", SourceInfo.class.getName(), mId);
-        }
-
-    }
-
-    private SourceInfo getSourceInfo(long srcId) {
-        synchronized (mSrcLock) {
-            if (isCurrentSource(srcId)) {
-                return mCurrentSourceInfo;
-            }
-            if (isNextSource(srcId)) {
-                return mNextSourceInfos.peek();
-            }
-        }
-        return null;
-    }
-
-    private SourceInfo getSourceInfo(DataSourceDesc dsd) {
-        synchronized (mSrcLock) {
-            if (isCurrentSource(dsd)) {
-                return mCurrentSourceInfo;
-            }
-            if (isNextSource(dsd)) {
-                return mNextSourceInfos.peek();
-            }
-        }
-        return null;
-    }
-
-    private boolean isCurrentSource(long srcId) {
-        synchronized (mSrcLock) {
-            return mCurrentSourceInfo != null && mCurrentSourceInfo.mId == srcId;
-        }
-    }
-
-    private boolean isCurrentSource(DataSourceDesc dsd) {
-        synchronized (mSrcLock) {
-            return mCurrentSourceInfo != null && mCurrentSourceInfo.mDSD == dsd;
-        }
-    }
-
-    private boolean isNextSource(long srcId) {
-        SourceInfo nextSourceInfo = mNextSourceInfos.peek();
-        return nextSourceInfo != null && nextSourceInfo.mId == srcId;
-    }
-
-    private boolean isNextSource(DataSourceDesc dsd) {
-        SourceInfo nextSourceInfo = mNextSourceInfos.peek();
-        return nextSourceInfo != null && nextSourceInfo.mDSD == dsd;
-    }
-
-    @GuardedBy("mSrcLock")
-    private void setCurrentSourceInfo_l(SourceInfo sourceInfo) {
-        cleanupSourceInfo(mCurrentSourceInfo);
-        mCurrentSourceInfo = sourceInfo;
-    }
-
-    @GuardedBy("mSrcLock")
-    private void clearNextSourceInfos_l() {
-        while (!mNextSourceInfos.isEmpty()) {
-            cleanupSourceInfo(mNextSourceInfos.poll());
-        }
-    }
-
-    private void cleanupSourceInfo(SourceInfo sourceInfo) {
-        if (sourceInfo != null) {
-            sourceInfo.close();
-            Runnable task = sourceInfo.mDrmHandle.newCleanupTask();
-            sDrmThreadPool.submit(task);
-        }
-    }
-
-    private void clearSourceInfos() {
-        synchronized (mSrcLock) {
-            setCurrentSourceInfo_l(null);
-            clearNextSourceInfos_l();
-        }
-    }
-
-    public static final class MetricsConstants {
-        private MetricsConstants() {}
-
-        /**
-         * Key to extract the MIME type of the video track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a String.
-         */
-        public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
-
-        /**
-         * Key to extract the codec being used to decode the video track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a String.
-         */
-        public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
-
-        /**
-         * Key to extract the width (in pixels) of the video track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String WIDTH = "android.media.mediaplayer.width";
-
-        /**
-         * Key to extract the height (in pixels) of the video track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String HEIGHT = "android.media.mediaplayer.height";
-
-        /**
-         * Key to extract the count of video frames played
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String FRAMES = "android.media.mediaplayer.frames";
-
-        /**
-         * Key to extract the count of video frames dropped
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
-
-        /**
-         * Key to extract the MIME type of the audio track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a String.
-         */
-        public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
-
-        /**
-         * Key to extract the codec being used to decode the audio track
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a String.
-         */
-        public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
-
-        /**
-         * Key to extract the duration (in milliseconds) of the
-         * media being played
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a long.
-         */
-        public static final String DURATION = "android.media.mediaplayer.durationMs";
-
-        /**
-         * Key to extract the playing time (in milliseconds) of the
-         * media being played
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is a long.
-         */
-        public static final String PLAYING = "android.media.mediaplayer.playingMs";
-
-        /**
-         * Key to extract the count of errors encountered while
-         * playing the media
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String ERRORS = "android.media.mediaplayer.err";
-
-        /**
-         * Key to extract an (optional) error code detected while
-         * playing the media
-         * from the {@link MediaPlayer2#getMetrics} return value.
-         * The value is an integer.
-         */
-        public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
-
-    }
-
-    private void keepAudioSessionIdAlive(int sessionId) {
-        synchronized (mSessionIdLock) {
-            if (mDummyAudioTrack != null) {
-                if (mDummyAudioTrack.getAudioSessionId() == sessionId) {
-                    return;
-                }
-                mDummyAudioTrack.release();
-            }
-            // TODO: parameters can be optimized
-            mDummyAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
-                    AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 2,
-                    AudioTrack.MODE_STATIC, sessionId);
-        }
-    }
-
-    private void keepAudioSessionIdAlive(AudioTrack at) {
-        synchronized (mSessionIdLock) {
-            if (mDummyAudioTrack != null) {
-                if (mDummyAudioTrack.getAudioSessionId() == at.getAudioSessionId()) {
-                    at.release();
-                    return;
-                }
-                mDummyAudioTrack.release();
-            }
-            mDummyAudioTrack = at;
-        }
-    }
-}
diff --git a/media/apex/java/android/media/MediaPlayer2Utils.java b/media/apex/java/android/media/MediaPlayer2Utils.java
deleted file mode 100644
index ac34260..0000000
--- a/media/apex/java/android/media/MediaPlayer2Utils.java
+++ /dev/null
@@ -1,43 +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 android.media;
-
-/**
- * Helper class used by native code to reduce JNI calls from native side.
- * @hide
- */
-public class MediaPlayer2Utils {
-    /**
-     * Returns whether audio offloading is supported for the given audio format.
-     *
-     * @param encoding the type of encoding defined in {@link AudioFormat}
-     * @param sampleRate the sampling rate of the stream
-     * @param channelMask the channel mask defined in {@link AudioFormat}
-     */
-    // @CalledByNative
-    public static boolean isOffloadedAudioPlaybackSupported(
-            int encoding, int sampleRate, int channelMask) {
-        final AudioFormat format = new AudioFormat.Builder()
-                .setEncoding(encoding)
-                .setSampleRate(sampleRate)
-                .setChannelMask(channelMask)
-                .build();
-        //TODO MP2 needs to pass AudioAttributes for this query, instead of using default attr
-        return AudioManager.isOffloadedPlaybackSupported(format,
-                (new AudioAttributes.Builder()).build());
-    }
-}
diff --git a/media/apex/java/android/media/UriDataSourceDesc.java b/media/apex/java/android/media/UriDataSourceDesc.java
deleted file mode 100644
index adf7a7d..0000000
--- a/media/apex/java/android/media/UriDataSourceDesc.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.Uri;
-
-import java.net.HttpCookie;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Structure of data source descriptor for sources using URI.
- *
- * Used by {@link MediaPlayer2#setDataSource}, {@link MediaPlayer2#setNextDataSource} and
- * {@link MediaPlayer2#setNextDataSources} to set data source for playback.
- *
- * <p>Users should use {@link Builder} to change {@link UriDataSourceDesc}.
- * @hide
- */
-public class UriDataSourceDesc extends DataSourceDesc {
-    private Uri mUri;
-    private Map<String, String> mHeader;
-    private List<HttpCookie> mCookies;
-
-    UriDataSourceDesc(String mediaId, long startPositionMs, long endPositionMs,
-            Uri uri, Map<String, String> header, List<HttpCookie> cookies) {
-        super(mediaId, startPositionMs, endPositionMs);
-        mUri = uri;
-        mHeader = header;
-        mCookies = cookies;
-    }
-
-    /**
-     * Return the Uri of this data source.
-     * @return the Uri of this data source
-     */
-    public @NonNull Uri getUri() {
-        return mUri;
-    }
-
-    /**
-     * Return the Uri headers of this data source.
-     * @return the Uri headers of this data source
-     */
-    public @Nullable Map<String, String> getHeaders() {
-        if (mHeader == null) {
-            return null;
-        }
-        return new HashMap<String, String>(mHeader);
-    }
-
-    /**
-     * Return the Uri cookies of this data source.
-     * @return the Uri cookies of this data source
-     */
-    public @Nullable List<HttpCookie> getCookies() {
-        if (mCookies == null) {
-            return null;
-        }
-        return new ArrayList<HttpCookie>(mCookies);
-    }
-}
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 84fe27d..378064d 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -113,88 +113,6 @@
     ],
 }
 
-cc_library_shared {
-    name: "libmedia2_jni",
-
-    srcs: [
-        "android_media_DataSourceCallback.cpp",
-        "android_media_MediaMetricsJNI.cpp",
-        "android_media_MediaPlayer2.cpp",
-        "android_media_SyncParams.cpp",
-    ],
-
-    shared_libs: [
-        // NDK or LLNDK or NDK-compliant
-        "libandroid",
-        "libbinder_ndk",
-        "libcgrouprc",
-        "libmediandk",
-        "libmediametrics",
-        "libnativehelper_compat_libc++",
-        "liblog",
-        "libvndksupport",
-    ],
-
-    header_libs: [
-        "libhardware_headers",
-        "libnativewindow_headers",
-    ],
-
-    static_libs: [
-        // MediaCas
-        "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
-        "libhidlbase",
-        "libhidlmemory",
-        "libbinderthreadstate",
-
-        // MediaPlayer2 implementation
-        "libbase",
-        "libcrypto",
-        "libcutils",
-        "libjsoncpp",
-        "libmedia_player2_util",
-        "libmediaplayer2",
-        "libmediaplayer2-protos",
-        "libmediandk_utils",
-        "libmediautils",
-        "libprocessgroup",
-        "libprotobuf-cpp-lite",
-        "libstagefright_esds",
-        "libstagefright_foundation_without_imemory",
-        "libstagefright_httplive",
-        "libstagefright_id3",
-        "libstagefright_mpeg2support",
-        "libstagefright_nuplayer2",
-        "libstagefright_player2",
-        "libstagefright_rtsp_player2",
-        "libstagefright_timedtext2",
-        "libutils",
-        "libmedia2_jni_core",
-    ],
-
-    group_static_libs: true,
-
-    include_dirs: [
-        "frameworks/base/core/jni",
-        "frameworks/native/include/media/openmax",
-        "system/media/camera/include",
-    ],
-
-    export_include_dirs: ["."],
-
-    cflags: [
-        "-Wall",
-        "-Werror",
-        "-Wno-error=deprecated-declarations",
-        "-Wunused",
-        "-Wunreachable-code",
-        "-fvisibility=hidden",
-    ],
-
-    ldflags: ["-Wl,--exclude-libs=ALL,-error-limit=0"],
-}
-
 subdirs = [
     "audioeffect",
     "soundpool",
diff --git a/media/jni/android_media_DataSourceCallback.cpp b/media/jni/android_media_DataSourceCallback.cpp
deleted file mode 100644
index c91d409..0000000
--- a/media/jni/android_media_DataSourceCallback.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2017, 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.
- */
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "JDataSourceCallback-JNI"
-#include <utils/Log.h>
-
-#include "android_media_DataSourceCallback.h"
-
-#include "log/log.h"
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-
-#include <drm/drm_framework_common.h>
-#include <mediaplayer2/JavaVMHelper.h>
-#include <media/stagefright/foundation/ADebug.h>
-#include <nativehelper/ScopedLocalRef.h>
-
-namespace android {
-
-static const size_t kBufferSize = 64 * 1024;
-
-JDataSourceCallback::JDataSourceCallback(JNIEnv* env, jobject source)
-    : mJavaObjStatus(OK),
-      mSizeIsCached(false),
-      mCachedSize(0) {
-    mDataSourceCallbackObj = env->NewGlobalRef(source);
-    CHECK(mDataSourceCallbackObj != NULL);
-
-    ScopedLocalRef<jclass> media2DataSourceClass(env, env->GetObjectClass(mDataSourceCallbackObj));
-    CHECK(media2DataSourceClass.get() != NULL);
-
-    mReadAtMethod = env->GetMethodID(media2DataSourceClass.get(), "readAt", "(J[BII)I");
-    CHECK(mReadAtMethod != NULL);
-    mGetSizeMethod = env->GetMethodID(media2DataSourceClass.get(), "getSize", "()J");
-    CHECK(mGetSizeMethod != NULL);
-    mCloseMethod = env->GetMethodID(media2DataSourceClass.get(), "close", "()V");
-    CHECK(mCloseMethod != NULL);
-
-    ScopedLocalRef<jbyteArray> tmp(env, env->NewByteArray(kBufferSize));
-    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
-    CHECK(mByteArrayObj != NULL);
-}
-
-JDataSourceCallback::~JDataSourceCallback() {
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mDataSourceCallbackObj);
-    env->DeleteGlobalRef(mByteArrayObj);
-}
-
-status_t JDataSourceCallback::initCheck() const {
-    return OK;
-}
-
-ssize_t JDataSourceCallback::readAt(off64_t offset, void *data, size_t size) {
-    Mutex::Autolock lock(mLock);
-
-    if (mJavaObjStatus != OK) {
-        return -1;
-    }
-    if (size > kBufferSize) {
-        size = kBufferSize;
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    jint numread = env->CallIntMethod(mDataSourceCallbackObj, mReadAtMethod,
-            (jlong)offset, mByteArrayObj, (jint)0, (jint)size);
-    if (env->ExceptionCheck()) {
-        ALOGW("An exception occurred in readAt()");
-        jniLogException(env, ANDROID_LOG_WARN, LOG_TAG);
-        env->ExceptionClear();
-        mJavaObjStatus = UNKNOWN_ERROR;
-        return -1;
-    }
-    if (numread < 0) {
-        if (numread != -1) {
-            ALOGW("An error occurred in readAt()");
-            mJavaObjStatus = UNKNOWN_ERROR;
-            return -1;
-        } else {
-            // numread == -1 indicates EOF
-            return 0;
-        }
-    }
-    if ((size_t)numread > size) {
-        ALOGE("readAt read too many bytes.");
-        mJavaObjStatus = UNKNOWN_ERROR;
-        return -1;
-    }
-
-    ALOGV("readAt %lld / %zu => %d.", (long long)offset, size, numread);
-    env->GetByteArrayRegion(mByteArrayObj, 0, numread, (jbyte*)data);
-    return numread;
-}
-
-status_t JDataSourceCallback::getSize(off64_t* size) {
-    Mutex::Autolock lock(mLock);
-
-    if (mJavaObjStatus != OK) {
-        return UNKNOWN_ERROR;
-    }
-    if (mSizeIsCached) {
-        *size = mCachedSize;
-        return OK;
-    }
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    *size = env->CallLongMethod(mDataSourceCallbackObj, mGetSizeMethod);
-    if (env->ExceptionCheck()) {
-        ALOGW("An exception occurred in getSize()");
-        jniLogException(env, ANDROID_LOG_WARN, LOG_TAG);
-        env->ExceptionClear();
-        // After returning an error, size shouldn't be used by callers.
-        *size = UNKNOWN_ERROR;
-        mJavaObjStatus = UNKNOWN_ERROR;
-        return UNKNOWN_ERROR;
-    }
-
-    // The minimum size should be -1, which indicates unknown size.
-    if (*size < 0) {
-        *size = -1;
-    }
-
-    mCachedSize = *size;
-    mSizeIsCached = true;
-    return OK;
-}
-
-void JDataSourceCallback::close() {
-    Mutex::Autolock lock(mLock);
-
-    JNIEnv* env = JavaVMHelper::getJNIEnv();
-    env->CallVoidMethod(mDataSourceCallbackObj, mCloseMethod);
-    // The closed state is effectively the same as an error state.
-    mJavaObjStatus = UNKNOWN_ERROR;
-}
-
-String8 JDataSourceCallback::toString() {
-    return String8::format("JDataSourceCallback(pid %d, uid %d)", getpid(), getuid());
-}
-
-String8 JDataSourceCallback::getMIMEType() const {
-    return String8("application/octet-stream");
-}
-
-}  // namespace android
diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp
index de60b08..e7487c3 100644
--- a/media/jni/android_media_MediaMetricsJNI.cpp
+++ b/media/jni/android_media_MediaMetricsJNI.cpp
@@ -23,9 +23,8 @@
 #include <media/MediaAnalyticsItem.h>
 
 
-// This source file is compiled and linked into both:
+// This source file is compiled and linked into:
 // core/jni/ (libandroid_runtime.so)
-// media/jni (libmedia2_jni.so)
 
 namespace android {
 
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
deleted file mode 100644
index 3069161..0000000
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
-**
-** Copyright 2017, 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.
-*/
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "MediaPlayer2-JNI"
-#include "utils/Log.h"
-
-#include <sys/stat.h>
-
-#include <media/AudioResamplerPublic.h>
-#include <media/DataSourceDesc.h>
-#include <media/MediaHTTPService.h>
-#include <media/MediaAnalyticsItem.h>
-#include <media/NdkWrapper.h>
-#include <media/stagefright/Utils.h>
-#include <media/stagefright/foundation/ByteUtils.h>  // for FOURCC definition
-#include <mediaplayer2/JAudioTrack.h>
-#include <mediaplayer2/JavaVMHelper.h>
-#include <mediaplayer2/JMedia2HTTPService.h>
-#include <mediaplayer2/mediaplayer2.h>
-#include <stdio.h>
-#include <assert.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <utils/threads.h>
-#include "jni.h"
-#include <nativehelper/JNIHelp.h>
-#include "android/native_window_jni.h"
-#include "log/log.h"
-#include "utils/Errors.h"  // for status_t
-#include "utils/KeyedVector.h"
-#include "utils/String8.h"
-#include "android_media_BufferingParams.h"
-#include "android_media_DataSourceCallback.h"
-#include "android_media_MediaMetricsJNI.h"
-#include "android_media_PlaybackParams.h"
-#include "android_media_SyncParams.h"
-#include "android_media_VolumeShaper.h"
-
-#include "android_os_Parcel.h"
-#include "android_util_Binder.h"
-#include <binder/Parcel.h>
-
-#include "mediaplayer2.pb.h"
-
-using android::media::MediaPlayer2Proto::PlayerMessage;
-
-// Modular DRM begin
-#define FIND_CLASS(var, className) \
-var = env->FindClass(className); \
-LOG_FATAL_IF(! (var), "Unable to find class " className);
-
-#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
-var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
-LOG_FATAL_IF(! (var), "Unable to find method " fieldName);
-
-struct StateExceptionFields {
-    jmethodID init;
-    jclass classId;
-};
-
-static StateExceptionFields gStateExceptionFields;
-// Modular DRM end
-
-// ----------------------------------------------------------------------------
-
-using namespace android;
-
-using media::VolumeShaper;
-
-// ----------------------------------------------------------------------------
-
-struct fields_t {
-    jfieldID    context;               // passed from Java to native, used for creating JWakeLock
-    jfieldID    nativeContext;         // mNativeContext in MediaPlayer2.java
-    jfieldID    surface_texture;
-
-    jmethodID   post_event;
-
-    jmethodID   proxyConfigGetHost;
-    jmethodID   proxyConfigGetPort;
-    jmethodID   proxyConfigGetExclusionList;
-};
-static fields_t fields;
-
-static BufferingParams::fields_t gBufferingParamsFields;
-static PlaybackParams::fields_t gPlaybackParamsFields;
-static SyncParams::fields_t gSyncParamsFields;
-static VolumeShaperHelper::fields_t gVolumeShaperFields;
-
-static Mutex sLock;
-
-static bool ConvertKeyValueArraysToKeyedVector(
-        JNIEnv *env, jobjectArray keys, jobjectArray values,
-        KeyedVector<String8, String8>* keyedVector) {
-
-    int nKeyValuePairs = 0;
-    bool failed = false;
-    if (keys != NULL && values != NULL) {
-        nKeyValuePairs = env->GetArrayLength(keys);
-        failed = (nKeyValuePairs != env->GetArrayLength(values));
-    }
-
-    if (!failed) {
-        failed = ((keys != NULL && values == NULL) ||
-                  (keys == NULL && values != NULL));
-    }
-
-    if (failed) {
-        ALOGE("keys and values arrays have different length");
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return false;
-    }
-
-    for (int i = 0; i < nKeyValuePairs; ++i) {
-        // No need to check on the ArrayIndexOutOfBoundsException, since
-        // it won't happen here.
-        jstring key = (jstring) env->GetObjectArrayElement(keys, i);
-        jstring value = (jstring) env->GetObjectArrayElement(values, i);
-
-        const char* keyStr = env->GetStringUTFChars(key, NULL);
-        if (!keyStr) {  // OutOfMemoryError
-            return false;
-        }
-
-        const char* valueStr = env->GetStringUTFChars(value, NULL);
-        if (!valueStr) {  // OutOfMemoryError
-            env->ReleaseStringUTFChars(key, keyStr);
-            return false;
-        }
-
-        keyedVector->add(String8(keyStr), String8(valueStr));
-
-        env->ReleaseStringUTFChars(key, keyStr);
-        env->ReleaseStringUTFChars(value, valueStr);
-        env->DeleteLocalRef(key);
-        env->DeleteLocalRef(value);
-    }
-    return true;
-}
-
-// ----------------------------------------------------------------------------
-// ref-counted object for callbacks
-class JNIMediaPlayer2Listener: public MediaPlayer2Listener
-{
-public:
-    JNIMediaPlayer2Listener(JNIEnv* env, jobject thiz, jobject weak_thiz);
-    ~JNIMediaPlayer2Listener();
-    virtual void notify(int64_t srcId, int msg, int ext1, int ext2,
-                        const PlayerMessage *obj = NULL) override;
-private:
-    JNIMediaPlayer2Listener();
-    jclass      mClass;     // Reference to MediaPlayer2 class
-    jobject     mObject;    // Weak ref to MediaPlayer2 Java object to call on
-};
-
-JNIMediaPlayer2Listener::JNIMediaPlayer2Listener(JNIEnv* env, jobject thiz, jobject weak_thiz)
-{
-
-    // Hold onto the MediaPlayer2 class for use in calling the static method
-    // that posts events to the application thread.
-    jclass clazz = env->GetObjectClass(thiz);
-    if (clazz == NULL) {
-        ALOGE("Can't find android/media/MediaPlayer2");
-        jniThrowException(env, "java/lang/Exception", NULL);
-        return;
-    }
-    mClass = (jclass)env->NewGlobalRef(clazz);
-
-    // We use a weak reference so the MediaPlayer2 object can be garbage collected.
-    // The reference is only used as a proxy for callbacks.
-    mObject  = env->NewGlobalRef(weak_thiz);
-}
-
-JNIMediaPlayer2Listener::~JNIMediaPlayer2Listener()
-{
-    // remove global references
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    env->DeleteGlobalRef(mObject);
-    env->DeleteGlobalRef(mClass);
-}
-
-void JNIMediaPlayer2Listener::notify(int64_t srcId, int msg, int ext1, int ext2,
-        const PlayerMessage* obj)
-{
-    JNIEnv *env = JavaVMHelper::getJNIEnv();
-    if (obj != NULL) {
-        int size = obj->ByteSize();
-        jbyte* temp = new jbyte[size];
-        obj->SerializeToArray(temp, size);
-
-        // return the response as a byte array.
-        jbyteArray out = env->NewByteArray(size);
-        env->SetByteArrayRegion(out, 0, size, temp);
-        env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
-                srcId, msg, ext1, ext2, out);
-        delete[] temp;
-    } else {
-        env->CallStaticVoidMethod(mClass, fields.post_event, mObject,
-                srcId, msg, ext1, ext2, NULL);
-    }
-    if (env->ExceptionCheck()) {
-        ALOGW("An exception occurred while notifying an event.");
-        jniLogException(env, ANDROID_LOG_WARN, LOG_TAG);
-        env->ExceptionClear();
-    }
-}
-
-// ----------------------------------------------------------------------------
-
-static sp<MediaPlayer2> getMediaPlayer(JNIEnv* env, jobject thiz)
-{
-    Mutex::Autolock l(sLock);
-    MediaPlayer2* const p = (MediaPlayer2*)env->GetLongField(thiz, fields.nativeContext);
-    return sp<MediaPlayer2>(p);
-}
-
-static sp<MediaPlayer2> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer2>& player)
-{
-    Mutex::Autolock l(sLock);
-    sp<MediaPlayer2> old = (MediaPlayer2*)env->GetLongField(thiz, fields.nativeContext);
-    if (player.get()) {
-        player->incStrong((void*)setMediaPlayer);
-    }
-    if (old != 0) {
-        old->decStrong((void*)setMediaPlayer);
-    }
-    env->SetLongField(thiz, fields.nativeContext, (jlong)player.get());
-    return old;
-}
-
-// If exception is NULL and opStatus is not OK, this method sends an error
-// event to the client application; otherwise, if exception is not NULL and
-// opStatus is not OK, this method throws the given exception to the client
-// application.
-static void process_media_player_call(
-    JNIEnv *env, jobject thiz, status_t opStatus, const char* exception, const char *message)
-{
-    if (exception == NULL) {  // Don't throw exception. Instead, send an event.
-        if (opStatus != (status_t) OK) {
-            sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-            if (mp != 0) {
-                int64_t srcId = 0;
-                mp->getSrcId(&srcId);
-                mp->notify(srcId, MEDIA2_ERROR, opStatus, 0);
-            }
-        }
-    } else {  // Throw exception!
-        if ( opStatus == (status_t) INVALID_OPERATION ) {
-            jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        } else if ( opStatus == (status_t) BAD_VALUE ) {
-            jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        } else if ( opStatus == (status_t) PERMISSION_DENIED ) {
-            jniThrowException(env, "java/lang/SecurityException", NULL);
-        } else if ( opStatus != (status_t) OK ) {
-            if (strlen(message) > 230) {
-               // if the message is too long, don't bother displaying the status code
-               jniThrowException( env, exception, message);
-            } else {
-               char msg[256];
-                // append the status code to the message
-               sprintf(msg, "%s: status=0x%X", message, opStatus);
-               jniThrowException( env, exception, msg);
-            }
-        }
-    }
-}
-
-static void
-android_media_MediaPlayer2_handleDataSourceUrl(
-        JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId,
-        jobject httpServiceObj, jstring path, jobjectArray keys, jobjectArray values,
-        jlong startPos, jlong endPos) {
-
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    if (path == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    const char *tmp = env->GetStringUTFChars(path, NULL);
-    if (tmp == NULL) {  // Out of memory
-        return;
-    }
-    ALOGV("handleDataSourceUrl: path %s, srcId %lld, start %lld, end %lld",
-          tmp, (long long)srcId, (long long)startPos, (long long)endPos);
-
-    if (strncmp(tmp, "content://", 10) == 0) {
-        ALOGE("handleDataSourceUrl: content scheme is not supported in native code");
-        jniThrowException(env, "java/io/IOException",
-                          "content scheme is not supported in native code");
-        return;
-    }
-
-    sp<DataSourceDesc> dsd = new DataSourceDesc();
-    dsd->mId = srcId;
-    dsd->mType = DataSourceDesc::TYPE_URL;
-    dsd->mUrl = tmp;
-    dsd->mStartPositionMs = startPos;
-    dsd->mEndPositionMs = endPos;
-
-    env->ReleaseStringUTFChars(path, tmp);
-    tmp = NULL;
-
-    // We build a KeyedVector out of the key and val arrays
-    if (!ConvertKeyValueArraysToKeyedVector(
-            env, keys, values, &dsd->mHeaders)) {
-        return;
-    }
-
-    sp<MediaHTTPService> httpService;
-    if (httpServiceObj != NULL) {
-        httpService = new JMedia2HTTPService(env, httpServiceObj);
-    }
-    dsd->mHttpService = httpService;
-
-    status_t err;
-    if (isCurrent) {
-        err = mp->setDataSource(dsd);
-    } else {
-        err = mp->prepareNextDataSource(dsd);
-    }
-    process_media_player_call(env, thiz, err,
-            "java/io/IOException", "handleDataSourceUrl failed." );
-}
-
-static void
-android_media_MediaPlayer2_handleDataSourceFD(
-        JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId,
-        jobject fileDescriptor, jlong offset, jlong length,
-        jlong startPos, jlong endPos) {
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    if (fileDescriptor == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-    int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
-    ALOGV("handleDataSourceFD: srcId=%lld, fd=%d (%s), offset=%lld, length=%lld, "
-          "start=%lld, end=%lld",
-          (long long)srcId, fd, nameForFd(fd).c_str(), (long long)offset, (long long)length,
-          (long long)startPos, (long long)endPos);
-
-    struct stat sb;
-    int ret = fstat(fd, &sb);
-    if (ret != 0) {
-        ALOGE("handleDataSourceFD: fstat(%d) failed: %d, %s", fd, ret, strerror(errno));
-        jniThrowException(env, "java/io/IOException", "handleDataSourceFD failed fstat");
-        return;
-    }
-
-    ALOGV("st_dev  = %llu", static_cast<unsigned long long>(sb.st_dev));
-    ALOGV("st_mode = %u", sb.st_mode);
-    ALOGV("st_uid  = %lu", static_cast<unsigned long>(sb.st_uid));
-    ALOGV("st_gid  = %lu", static_cast<unsigned long>(sb.st_gid));
-    ALOGV("st_size = %llu", static_cast<unsigned long long>(sb.st_size));
-
-    if (offset >= sb.st_size) {
-        ALOGE("handleDataSourceFD: offset is out of range");
-        jniThrowException(env, "java/lang/IllegalArgumentException",
-                          "handleDataSourceFD failed, offset is out of range.");
-        return;
-    }
-    if (offset + length > sb.st_size) {
-        length = sb.st_size - offset;
-        ALOGV("handleDataSourceFD: adjusted length = %lld", (long long)length);
-    }
-
-    sp<DataSourceDesc> dsd = new DataSourceDesc();
-    dsd->mId = srcId;
-    dsd->mType = DataSourceDesc::TYPE_FD;
-    dsd->mFD = fd;
-    dsd->mFDOffset = offset;
-    dsd->mFDLength = length;
-    dsd->mStartPositionMs = startPos;
-    dsd->mEndPositionMs = endPos;
-
-    status_t err;
-    if (isCurrent) {
-        err = mp->setDataSource(dsd);
-    } else {
-        err = mp->prepareNextDataSource(dsd);
-    }
-    process_media_player_call(env, thiz, err,
-            "java/io/IOException", "handleDataSourceFD failed." );
-}
-
-static void
-android_media_MediaPlayer2_handleDataSourceCallback(
-    JNIEnv *env, jobject thiz, jboolean isCurrent, jlong srcId, jobject dataSource,
-    jlong startPos, jlong endPos)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    if (dataSource == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-    sp<DataSource> callbackDataSource = new JDataSourceCallback(env, dataSource);
-    sp<DataSourceDesc> dsd = new DataSourceDesc();
-    dsd->mId = srcId;
-    dsd->mType = DataSourceDesc::TYPE_CALLBACK;
-    dsd->mCallbackSource = callbackDataSource;
-    dsd->mStartPositionMs = startPos;
-    dsd->mEndPositionMs = endPos;
-
-    status_t err;
-    if (isCurrent) {
-        err = mp->setDataSource(dsd);
-    } else {
-        err = mp->prepareNextDataSource(dsd);
-    }
-    process_media_player_call(env, thiz, err,
-            "java/lang/RuntimeException", "handleDataSourceCallback failed." );
-}
-
-static sp<ANativeWindowWrapper>
-getVideoSurfaceTexture(JNIEnv* env, jobject thiz) {
-    ANativeWindow * const p = (ANativeWindow*)env->GetLongField(thiz, fields.surface_texture);
-    return new ANativeWindowWrapper(p);
-}
-
-static void
-decVideoSurfaceRef(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return;
-    }
-
-    ANativeWindow * const old_anw = (ANativeWindow*)env->GetLongField(thiz, fields.surface_texture);
-    if (old_anw != NULL) {
-        ANativeWindow_release(old_anw);
-        env->SetLongField(thiz, fields.surface_texture, (jlong)NULL);
-    }
-}
-
-static void
-setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlayerMustBeAlive)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        if (mediaPlayerMustBeAlive) {
-            jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        }
-        return;
-    }
-
-    decVideoSurfaceRef(env, thiz);
-
-    ANativeWindow* anw = NULL;
-    if (jsurface) {
-        anw = ANativeWindow_fromSurface(env, jsurface);
-        if (anw == NULL) {
-            jniThrowException(env, "java/lang/IllegalArgumentException",
-                    "The surface has been released");
-            return;
-        }
-    }
-
-    env->SetLongField(thiz, fields.surface_texture, (jlong)anw);
-
-    // This will fail if the media player has not been initialized yet. This
-    // can be the case if setDisplay() on MediaPlayer2.java has been called
-    // before setDataSource(). The redundant call to setVideoSurfaceTexture()
-    // in prepare/prepare covers for this case.
-    mp->setVideoSurfaceTexture(new ANativeWindowWrapper(anw));
-}
-
-static void
-android_media_MediaPlayer2_setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface)
-{
-    setVideoSurface(env, thiz, jsurface, true /* mediaPlayerMustBeAlive */);
-}
-
-static jobject
-android_media_MediaPlayer2_getBufferingParams(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    BufferingParams bp;
-    BufferingSettings &settings = bp.settings;
-    process_media_player_call(
-            env, thiz, mp->getBufferingSettings(&settings),
-            "java/lang/IllegalStateException", "unexpected error");
-    if (env->ExceptionCheck()) {
-        return nullptr;
-    }
-    ALOGV("getBufferingSettings:{%s}", settings.toString().string());
-
-    return bp.asJobject(env, gBufferingParamsFields);
-}
-
-static void
-android_media_MediaPlayer2_setBufferingParams(JNIEnv *env, jobject thiz, jobject params)
-{
-    if (params == NULL) {
-        return;
-    }
-
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    BufferingParams bp;
-    bp.fillFromJobject(env, gBufferingParamsFields, params);
-    ALOGV("setBufferingParams:{%s}", bp.settings.toString().string());
-
-    process_media_player_call(
-            env, thiz, mp->setBufferingSettings(bp.settings),
-            "java/lang/IllegalStateException", "unexpected error");
-}
-
-static void
-android_media_MediaPlayer2_playNextDataSource(JNIEnv *env, jobject thiz, jlong srcId)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    process_media_player_call(env, thiz, mp->playNextDataSource((int64_t)srcId),
-            "java/io/IOException", "playNextDataSource failed." );
-}
-
-static void
-android_media_MediaPlayer2_prepare(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    // Handle the case where the display surface was set before the mp was
-    // initialized. We try again to make it stick.
-    sp<ANativeWindowWrapper> st = getVideoSurfaceTexture(env, thiz);
-    mp->setVideoSurfaceTexture(st);
-
-    process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
-}
-
-static void
-android_media_MediaPlayer2_start(JNIEnv *env, jobject thiz)
-{
-    ALOGV("start");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->start(), NULL, NULL );
-}
-
-static void
-android_media_MediaPlayer2_pause(JNIEnv *env, jobject thiz)
-{
-    ALOGV("pause");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->pause(), NULL, NULL );
-}
-
-static void
-android_media_MediaPlayer2_setPlaybackParams(JNIEnv *env, jobject thiz, jobject params)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    PlaybackParams pbp;
-    pbp.fillFromJobject(env, gPlaybackParamsFields, params);
-    ALOGV("setPlaybackParams: %d:%f %d:%f %d:%u %d:%u",
-            pbp.speedSet, pbp.audioRate.mSpeed,
-            pbp.pitchSet, pbp.audioRate.mPitch,
-            pbp.audioFallbackModeSet, pbp.audioRate.mFallbackMode,
-            pbp.audioStretchModeSet, pbp.audioRate.mStretchMode);
-
-    AudioPlaybackRate rate;
-    status_t err = mp->getPlaybackSettings(&rate);
-    if (err == OK) {
-        bool updatedRate = false;
-        if (pbp.speedSet) {
-            rate.mSpeed = pbp.audioRate.mSpeed;
-            updatedRate = true;
-        }
-        if (pbp.pitchSet) {
-            rate.mPitch = pbp.audioRate.mPitch;
-            updatedRate = true;
-        }
-        if (pbp.audioFallbackModeSet) {
-            rate.mFallbackMode = pbp.audioRate.mFallbackMode;
-            updatedRate = true;
-        }
-        if (pbp.audioStretchModeSet) {
-            rate.mStretchMode = pbp.audioRate.mStretchMode;
-            updatedRate = true;
-        }
-        if (updatedRate) {
-            err = mp->setPlaybackSettings(rate);
-        }
-    }
-    process_media_player_call(
-            env, thiz, err,
-            "java/lang/IllegalStateException", "unexpected error");
-}
-
-static jobject
-android_media_MediaPlayer2_getPlaybackParams(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    PlaybackParams pbp;
-    AudioPlaybackRate &audioRate = pbp.audioRate;
-    process_media_player_call(
-            env, thiz, mp->getPlaybackSettings(&audioRate),
-            "java/lang/IllegalStateException", "unexpected error");
-    if (env->ExceptionCheck()) {
-        return nullptr;
-    }
-    ALOGV("getPlaybackSettings: %f %f %d %d",
-            audioRate.mSpeed, audioRate.mPitch, audioRate.mFallbackMode, audioRate.mStretchMode);
-
-    pbp.speedSet = true;
-    pbp.pitchSet = true;
-    pbp.audioFallbackModeSet = true;
-    pbp.audioStretchModeSet = true;
-
-    return pbp.asJobject(env, gPlaybackParamsFields);
-}
-
-static void
-android_media_MediaPlayer2_setSyncParams(JNIEnv *env, jobject thiz, jobject params)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    SyncParams scp;
-    scp.fillFromJobject(env, gSyncParamsFields, params);
-    ALOGV("setSyncParams: %d:%d %d:%d %d:%f %d:%f",
-          scp.syncSourceSet, scp.sync.mSource,
-          scp.audioAdjustModeSet, scp.sync.mAudioAdjustMode,
-          scp.toleranceSet, scp.sync.mTolerance,
-          scp.frameRateSet, scp.frameRate);
-
-    AVSyncSettings avsync;
-    float videoFrameRate;
-    status_t err = mp->getSyncSettings(&avsync, &videoFrameRate);
-    if (err == OK) {
-        bool updatedSync = scp.frameRateSet;
-        if (scp.syncSourceSet) {
-            avsync.mSource = scp.sync.mSource;
-            updatedSync = true;
-        }
-        if (scp.audioAdjustModeSet) {
-            avsync.mAudioAdjustMode = scp.sync.mAudioAdjustMode;
-            updatedSync = true;
-        }
-        if (scp.toleranceSet) {
-            avsync.mTolerance = scp.sync.mTolerance;
-            updatedSync = true;
-        }
-        if (updatedSync) {
-            err = mp->setSyncSettings(avsync, scp.frameRateSet ? scp.frameRate : -1.f);
-        }
-    }
-    process_media_player_call(
-            env, thiz, err,
-            "java/lang/IllegalStateException", "unexpected error");
-}
-
-static jobject
-android_media_MediaPlayer2_getSyncParams(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    SyncParams scp;
-    scp.frameRate = -1.f;
-    process_media_player_call(
-            env, thiz, mp->getSyncSettings(&scp.sync, &scp.frameRate),
-            "java/lang/IllegalStateException", "unexpected error");
-    if (env->ExceptionCheck()) {
-        return nullptr;
-    }
-
-    ALOGV("getSyncSettings: %d %d %f %f",
-            scp.sync.mSource, scp.sync.mAudioAdjustMode, scp.sync.mTolerance, scp.frameRate);
-
-    // sanity check params
-    if (scp.sync.mSource >= AVSYNC_SOURCE_MAX
-            || scp.sync.mAudioAdjustMode >= AVSYNC_AUDIO_ADJUST_MODE_MAX
-            || scp.sync.mTolerance < 0.f
-            || scp.sync.mTolerance >= AVSYNC_TOLERANCE_MAX) {
-        jniThrowException(env,  "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    scp.syncSourceSet = true;
-    scp.audioAdjustModeSet = true;
-    scp.toleranceSet = true;
-    scp.frameRateSet = scp.frameRate >= 0.f;
-
-    return scp.asJobject(env, gSyncParamsFields);
-}
-
-static void
-android_media_MediaPlayer2_seekTo(JNIEnv *env, jobject thiz, jlong msec, jint mode)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    ALOGV("seekTo: %lld(msec), mode=%d", (long long)msec, mode);
-    process_media_player_call(env, thiz, mp->seekTo((int64_t)msec, (MediaPlayer2SeekMode)mode),
-                              NULL, NULL);
-}
-
-static jint
-android_media_MediaPlayer2_getState(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return MEDIAPLAYER2_STATE_IDLE;
-    }
-    return (jint)mp->getState();
-}
-
-static jobject
-android_media_MediaPlayer2_native_getMetrics(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return 0;
-    }
-
-    char *buffer = NULL;
-    size_t length = 0;
-    status_t status = mp->getMetrics(&buffer, &length);
-    if (status != OK) {
-        ALOGD("getMetrics() failed: %d", status);
-        return (jobject) NULL;
-    }
-
-    jobject mybundle = MediaMetricsJNI::writeAttributesToBundle(env, NULL, buffer, length);
-
-    free(buffer);
-
-    return mybundle;
-}
-
-static jlong
-android_media_MediaPlayer2_getCurrentPosition(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return 0;
-    }
-    int64_t msec;
-    process_media_player_call( env, thiz, mp->getCurrentPosition(&msec), NULL, NULL );
-    ALOGV("getCurrentPosition: %lld (msec)", (long long)msec);
-    return (jlong) msec;
-}
-
-static jlong
-android_media_MediaPlayer2_getDuration(JNIEnv *env, jobject thiz, jlong srcId)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return 0;
-    }
-    int64_t msec;
-    process_media_player_call( env, thiz, mp->getDuration(srcId, &msec), NULL, NULL );
-    ALOGV("getDuration: %lld (msec)", (long long)msec);
-    return (jlong) msec;
-}
-
-static void
-android_media_MediaPlayer2_reset(JNIEnv *env, jobject thiz)
-{
-    ALOGV("reset");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
-}
-
-static jboolean
-android_media_MediaPlayer2_setAudioAttributes(JNIEnv *env, jobject thiz, jobject attributes)
-{
-    ALOGV("setAudioAttributes");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return false;
-    }
-    status_t err = mp->setAudioAttributes(attributes);
-    return err == OK;
-}
-
-static jobject
-android_media_MediaPlayer2_getAudioAttributes(JNIEnv *env, jobject thiz)
-{
-    ALOGV("getAudioAttributes");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    return mp->getAudioAttributes();
-}
-
-static void
-android_media_MediaPlayer2_setLooping(JNIEnv *env, jobject thiz, jboolean looping)
-{
-    ALOGV("setLooping: %d", looping);
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->setLooping(looping), NULL, NULL );
-}
-
-static jboolean
-android_media_MediaPlayer2_isLooping(JNIEnv *env, jobject thiz)
-{
-    ALOGV("isLooping");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return JNI_FALSE;
-    }
-    return mp->isLooping() ? JNI_TRUE : JNI_FALSE;
-}
-
-static void
-android_media_MediaPlayer2_setVolume(JNIEnv *env, jobject thiz, jfloat volume)
-{
-    ALOGV("setVolume: volume %f", (float) volume);
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->setVolume((float) volume), NULL, NULL );
-}
-
-static jbyteArray
-android_media_MediaPlayer2_invoke(JNIEnv *env, jobject thiz, jbyteArray requestData) {
-    sp<MediaPlayer2> media_player = getMediaPlayer(env, thiz);
-    if (media_player == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return NULL;
-    }
-
-    // Get the byte[] pointer and data length.
-    jbyte* pData = env->GetByteArrayElements(requestData, NULL);
-    jsize pDataLen = env->GetArrayLength(requestData);
-
-    // Deserialize from the byte stream.
-    PlayerMessage request;
-    PlayerMessage response;
-    request.ParseFromArray(pData, pDataLen);
-
-    process_media_player_call( env, thiz, media_player->invoke(request, &response),
-            "java.lang.RuntimeException", NULL );
-    if (env->ExceptionCheck()) {
-        return NULL;
-    }
-
-    int size = response.ByteSize();
-    jbyte* temp = new jbyte[size];
-    response.SerializeToArray(temp, size);
-
-    // return the response as a byte array.
-    jbyteArray out = env->NewByteArray(size);
-    env->SetByteArrayRegion(out, 0, size, temp);
-    delete[] temp;
-
-    return out;
-}
-
-// This function gets some field IDs, which in turn causes class initialization.
-// It is called from a static block in MediaPlayer2, which won't run until the
-// first time an instance of this class is used.
-static void
-android_media_MediaPlayer2_native_init(JNIEnv *env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/media/MediaPlayer2");
-    if (clazz == NULL) {
-        return;
-    }
-
-    fields.context = env->GetFieldID(clazz, "mContext", "Landroid/content/Context;");
-    if (fields.context == NULL) {
-        return;
-    }
-
-    fields.nativeContext = env->GetFieldID(clazz, "mNativeContext", "J");
-    if (fields.nativeContext == NULL) {
-        return;
-    }
-
-    fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative",
-                                               "(Ljava/lang/Object;JIII[B)V");
-    if (fields.post_event == NULL) {
-        return;
-    }
-
-    fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "J");
-    if (fields.surface_texture == NULL) {
-        return;
-    }
-
-    env->DeleteLocalRef(clazz);
-
-    clazz = env->FindClass("android/net/ProxyInfo");
-    if (clazz == NULL) {
-        return;
-    }
-
-    fields.proxyConfigGetHost =
-        env->GetMethodID(clazz, "getHost", "()Ljava/lang/String;");
-
-    fields.proxyConfigGetPort =
-        env->GetMethodID(clazz, "getPort", "()I");
-
-    fields.proxyConfigGetExclusionList =
-        env->GetMethodID(clazz, "getExclusionListAsString", "()Ljava/lang/String;");
-
-    env->DeleteLocalRef(clazz);
-
-    gBufferingParamsFields.init(env);
-
-    // Modular DRM
-    FIND_CLASS(clazz, "android/media/MediaDrm$MediaDrmStateException");
-    if (clazz) {
-        GET_METHOD_ID(gStateExceptionFields.init, clazz, "<init>", "(ILjava/lang/String;)V");
-        gStateExceptionFields.classId = static_cast<jclass>(env->NewGlobalRef(clazz));
-
-        env->DeleteLocalRef(clazz);
-    } else {
-        ALOGE("JNI android_media_MediaPlayer2_native_init couldn't "
-              "get clazz android/media/MediaDrm$MediaDrmStateException");
-    }
-
-    gPlaybackParamsFields.init(env);
-    gSyncParamsFields.init(env);
-    gVolumeShaperFields.init(env);
-}
-
-static void
-android_media_MediaPlayer2_native_setup(JNIEnv *env, jobject thiz,
-        jint sessionId, jobject weak_this)
-{
-    ALOGV("native_setup");
-    jobject context = env->GetObjectField(thiz, fields.context);
-    sp<MediaPlayer2> mp = MediaPlayer2::Create(sessionId, context);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
-        return;
-    }
-
-    // create new listener and give it to MediaPlayer2
-    sp<JNIMediaPlayer2Listener> listener = new JNIMediaPlayer2Listener(env, thiz, weak_this);
-    mp->setListener(listener);
-
-    // Stow our new C++ MediaPlayer2 in an opaque field in the Java object.
-    setMediaPlayer(env, thiz, mp);
-}
-
-static void
-android_media_MediaPlayer2_release(JNIEnv *env, jobject thiz)
-{
-    ALOGV("release");
-    decVideoSurfaceRef(env, thiz);
-    sp<MediaPlayer2> mp = setMediaPlayer(env, thiz, 0);
-    if (mp != NULL) {
-        // this prevents native callbacks after the object is released
-        mp->setListener(0);
-        mp->disconnect();
-    }
-}
-
-static void
-android_media_MediaPlayer2_native_finalize(JNIEnv *env, jobject thiz)
-{
-    ALOGV("native_finalize");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp != NULL) {
-        ALOGW("MediaPlayer2 finalized without being released");
-    }
-    android_media_MediaPlayer2_release(env, thiz);
-}
-
-static void android_media_MediaPlayer2_setAudioSessionId(JNIEnv *env,  jobject thiz,
-        jint sessionId) {
-    ALOGV("setAudioSessionId(): %d", sessionId);
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->setAudioSessionId((audio_session_t) sessionId), NULL,
-            NULL);
-}
-
-static jint android_media_MediaPlayer2_getAudioSessionId(JNIEnv *env,  jobject thiz) {
-    ALOGV("getAudioSessionId()");
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return 0;
-    }
-
-    return (jint) mp->getAudioSessionId();
-}
-
-static void
-android_media_MediaPlayer2_setAuxEffectSendLevel(JNIEnv *env, jobject thiz, jfloat level)
-{
-    ALOGV("setAuxEffectSendLevel: level %f", level);
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->setAuxEffectSendLevel(level), NULL, NULL );
-}
-
-static void android_media_MediaPlayer2_attachAuxEffect(JNIEnv *env,  jobject thiz, jint effectId) {
-    ALOGV("attachAuxEffect(): %d", effectId);
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-    process_media_player_call( env, thiz, mp->attachAuxEffect(effectId), NULL, NULL );
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-// Modular DRM begin
-
-// TODO: investigate if these can be shared with their MediaDrm counterparts
-static void throwDrmStateException(JNIEnv *env, const char *msg, status_t err)
-{
-    ALOGE("Illegal DRM state exception: %s (%d)", msg, err);
-
-    jobject exception = env->NewObject(gStateExceptionFields.classId,
-            gStateExceptionFields.init, static_cast<int>(err),
-            env->NewStringUTF(msg));
-    env->Throw(static_cast<jthrowable>(exception));
-}
-
-// TODO: investigate if these can be shared with their MediaDrm counterparts
-static bool throwDrmExceptionAsNecessary(JNIEnv *env, status_t err, const char *msg = NULL)
-{
-    const char *drmMessage = "Unknown DRM Msg";
-
-    switch (err) {
-    case ERROR_DRM_UNKNOWN:
-        drmMessage = "General DRM error";
-        break;
-    case ERROR_DRM_NO_LICENSE:
-        drmMessage = "No license";
-        break;
-    case ERROR_DRM_LICENSE_EXPIRED:
-        drmMessage = "License expired";
-        break;
-    case ERROR_DRM_SESSION_NOT_OPENED:
-        drmMessage = "Session not opened";
-        break;
-    case ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED:
-        drmMessage = "Not initialized";
-        break;
-    case ERROR_DRM_DECRYPT:
-        drmMessage = "Decrypt error";
-        break;
-    case ERROR_DRM_CANNOT_HANDLE:
-        drmMessage = "Unsupported scheme or data format";
-        break;
-    case ERROR_DRM_TAMPER_DETECTED:
-        drmMessage = "Invalid state";
-        break;
-    default:
-        break;
-    }
-
-    String8 vendorMessage;
-    if (err >= ERROR_DRM_VENDOR_MIN && err <= ERROR_DRM_VENDOR_MAX) {
-        vendorMessage = String8::format("DRM vendor-defined error: %d", err);
-        drmMessage = vendorMessage.string();
-    }
-
-    if (err == BAD_VALUE) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", msg);
-        return true;
-    } else if (err == ERROR_DRM_NOT_PROVISIONED) {
-        jniThrowException(env, "android/media/NotProvisionedException", msg);
-        return true;
-    } else if (err == ERROR_DRM_RESOURCE_BUSY) {
-        jniThrowException(env, "android/media/ResourceBusyException", msg);
-        return true;
-    } else if (err == ERROR_DRM_DEVICE_REVOKED) {
-        jniThrowException(env, "android/media/DeniedByServerException", msg);
-        return true;
-    } else if (err == DEAD_OBJECT) {
-        jniThrowException(env, "android/media/MediaDrmResetException",
-                          "mediaserver died");
-        return true;
-    } else if (err != OK) {
-        String8 errbuf;
-        if (drmMessage != NULL) {
-            if (msg == NULL) {
-                msg = drmMessage;
-            } else {
-                errbuf = String8::format("%s: %s", msg, drmMessage);
-                msg = errbuf.string();
-            }
-        }
-        throwDrmStateException(env, msg, err);
-        return true;
-    }
-    return false;
-}
-
-static Vector<uint8_t> JByteArrayToVector(JNIEnv *env, jbyteArray const &byteArray)
-{
-    Vector<uint8_t> vector;
-    size_t length = env->GetArrayLength(byteArray);
-    vector.insertAt((size_t)0, length);
-    env->GetByteArrayRegion(byteArray, 0, length, (jbyte *)vector.editArray());
-    return vector;
-}
-
-static void android_media_MediaPlayer2_prepareDrm(JNIEnv *env, jobject thiz,
-                    jlong srcId, jbyteArray uuidObj, jbyteArray drmSessionIdObj)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    if (uuidObj == NULL) {
-        jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
-        return;
-    }
-
-    Vector<uint8_t> uuid = JByteArrayToVector(env, uuidObj);
-
-    if (uuid.size() != 16) {
-        jniThrowException(
-                          env,
-                          "java/lang/IllegalArgumentException",
-                          "invalid UUID size, expected 16 bytes");
-        return;
-    }
-
-    Vector<uint8_t> drmSessionId = JByteArrayToVector(env, drmSessionIdObj);
-
-    if (drmSessionId.size() == 0) {
-        jniThrowException(
-                          env,
-                          "java/lang/IllegalArgumentException",
-                          "empty drmSessionId");
-        return;
-    }
-
-    status_t err = mp->prepareDrm(srcId, uuid.array(), drmSessionId);
-    if (err != OK) {
-        if (err == INVALID_OPERATION) {
-            jniThrowException(
-                              env,
-                              "java/lang/IllegalStateException",
-                              "The player must be in prepared state.");
-        } else if (err == ERROR_DRM_CANNOT_HANDLE) {
-            jniThrowException(
-                              env,
-                              "android/media/UnsupportedSchemeException",
-                              "Failed to instantiate drm object.");
-        } else {
-            throwDrmExceptionAsNecessary(env, err, "Failed to prepare DRM scheme");
-        }
-    }
-}
-
-static void android_media_MediaPlayer2_releaseDrm(JNIEnv *env, jobject thiz, jlong srcId)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL ) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        return;
-    }
-
-    status_t err = mp->releaseDrm(srcId);
-    if (err != OK) {
-        if (err == INVALID_OPERATION) {
-            jniThrowException(
-                              env,
-                              "java/lang/IllegalStateException",
-                              "Can not release DRM in an active player state.");
-        }
-    }
-}
-// Modular DRM end
-// ----------------------------------------------------------------------------
-
-/////////////////////////////////////////////////////////////////////////////////////
-// AudioRouting begin
-static jboolean android_media_MediaPlayer2_setPreferredDevice(JNIEnv *env, jobject thiz, jobject device)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return false;
-    }
-    return mp->setPreferredDevice(device) == NO_ERROR;
-}
-
-static jobject android_media_MediaPlayer2_getRoutedDevice(JNIEnv *env, jobject thiz)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return nullptr;
-    }
-    return mp->getRoutedDevice();
-}
-
-static void android_media_MediaPlayer2_addDeviceCallback(
-        JNIEnv* env, jobject thiz, jobject routingDelegate)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return;
-    }
-
-    status_t status = mp->addAudioDeviceCallback(routingDelegate);
-    if (status != NO_ERROR) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        ALOGE("enable device callback failed: %d", status);
-    }
-}
-
-static void android_media_MediaPlayer2_removeDeviceCallback(
-        JNIEnv* env, jobject thiz, jobject listener)
-{
-    sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
-    if (mp == NULL) {
-        return;
-    }
-
-    status_t status = mp->removeAudioDeviceCallback(listener);
-    if (status != NO_ERROR) {
-        jniThrowException(env, "java/lang/IllegalStateException", NULL);
-        ALOGE("enable device callback failed: %d", status);
-    }
-}
-
-// AudioRouting end
-// ----------------------------------------------------------------------------
-
-/////////////////////////////////////////////////////////////////////////////////////
-// AudioTrack.StreamEventCallback begin
-static void android_media_MediaPlayer2_native_on_tear_down(JNIEnv *env __unused,
-        jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
-{
-    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
-    if (callback != NULL) {
-        callback(JAudioTrack::EVENT_NEW_IAUDIOTRACK, (void *) userDataPtr, NULL);
-    }
-}
-
-static void android_media_MediaPlayer2_native_on_stream_presentation_end(JNIEnv *env __unused,
-        jobject thiz __unused, jlong callbackPtr, jlong userDataPtr)
-{
-    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
-    if (callback != NULL) {
-        callback(JAudioTrack::EVENT_STREAM_END, (void *) userDataPtr, NULL);
-    }
-}
-
-static void android_media_MediaPlayer2_native_on_stream_data_request(JNIEnv *env __unused,
-        jobject thiz __unused, jlong jAudioTrackPtr, jlong callbackPtr, jlong userDataPtr)
-{
-    JAudioTrack::callback_t callback = (JAudioTrack::callback_t) callbackPtr;
-    JAudioTrack* track = (JAudioTrack *) jAudioTrackPtr;
-    if (callback != NULL && track != NULL) {
-        JAudioTrack::Buffer* buffer = new JAudioTrack::Buffer();
-
-        size_t bufferSizeInFrames = track->frameCount();
-        audio_format_t format = track->format();
-
-        size_t bufferSizeInBytes;
-        if (audio_has_proportional_frames(format)) {
-            bufferSizeInBytes =
-                    bufferSizeInFrames * audio_bytes_per_sample(format) * track->channelCount();
-        } else {
-            // See Javadoc of AudioTrack::getBufferSizeInFrames().
-            bufferSizeInBytes = bufferSizeInFrames;
-        }
-
-        uint8_t* byteBuffer = new uint8_t[bufferSizeInBytes];
-        buffer->mSize = bufferSizeInBytes;
-        buffer->mData = (void *) byteBuffer;
-
-        callback(JAudioTrack::EVENT_MORE_DATA, (void *) userDataPtr, buffer);
-
-        if (buffer->mSize > 0 && buffer->mData == byteBuffer) {
-            track->write(buffer->mData, buffer->mSize, true /* Blocking */);
-        }
-
-        delete[] byteBuffer;
-        delete buffer;
-    }
-}
-
-
-// AudioTrack.StreamEventCallback end
-// ----------------------------------------------------------------------------
-
-static const JNINativeMethod gMethods[] = {
-    {
-        "nativeHandleDataSourceUrl",
-        "(ZJLandroid/media/Media2HTTPService;Ljava/lang/String;[Ljava/lang/String;"
-        "[Ljava/lang/String;JJ)V",
-        (void *)android_media_MediaPlayer2_handleDataSourceUrl
-    },
-    {
-        "nativeHandleDataSourceFD",
-        "(ZJLjava/io/FileDescriptor;JJJJ)V",
-        (void *)android_media_MediaPlayer2_handleDataSourceFD
-    },
-    {
-        "nativeHandleDataSourceCallback",
-        "(ZJLandroid/media/DataSourceCallback;JJ)V",
-        (void *)android_media_MediaPlayer2_handleDataSourceCallback
-    },
-    {"nativePlayNextDataSource", "(J)V",                        (void *)android_media_MediaPlayer2_playNextDataSource},
-    {"native_setVideoSurface", "(Landroid/view/Surface;)V",     (void *)android_media_MediaPlayer2_setVideoSurface},
-    {"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer2_getBufferingParams},
-    {"native_setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
-    {"native_prepare",      "()V",                              (void *)android_media_MediaPlayer2_prepare},
-    {"native_start",        "()V",                              (void *)android_media_MediaPlayer2_start},
-    {"native_getState",     "()I",                              (void *)android_media_MediaPlayer2_getState},
-    {"native_getMetrics",   "()Landroid/os/PersistableBundle;", (void *)android_media_MediaPlayer2_native_getMetrics},
-    {"native_setPlaybackParams", "(Landroid/media/PlaybackParams;)V", (void *)android_media_MediaPlayer2_setPlaybackParams},
-    {"getPlaybackParams", "()Landroid/media/PlaybackParams;",   (void *)android_media_MediaPlayer2_getPlaybackParams},
-    {"native_setSyncParams",     "(Landroid/media/SyncParams;)V",     (void *)android_media_MediaPlayer2_setSyncParams},
-    {"getSyncParams",     "()Landroid/media/SyncParams;",       (void *)android_media_MediaPlayer2_getSyncParams},
-    {"native_seekTo",       "(JI)V",                            (void *)android_media_MediaPlayer2_seekTo},
-    {"native_pause",        "()V",                              (void *)android_media_MediaPlayer2_pause},
-    {"getCurrentPosition",  "()J",                              (void *)android_media_MediaPlayer2_getCurrentPosition},
-    {"native_getDuration",  "(J)J",                             (void *)android_media_MediaPlayer2_getDuration},
-    {"native_release",      "()V",                              (void *)android_media_MediaPlayer2_release},
-    {"native_reset",        "()V",                              (void *)android_media_MediaPlayer2_reset},
-    {"native_setAudioAttributes", "(Landroid/media/AudioAttributes;)Z", (void *)android_media_MediaPlayer2_setAudioAttributes},
-    {"native_getAudioAttributes", "()Landroid/media/AudioAttributes;", (void *)android_media_MediaPlayer2_getAudioAttributes},
-    {"setLooping",          "(Z)V",                             (void *)android_media_MediaPlayer2_setLooping},
-    {"isLooping",           "()Z",                              (void *)android_media_MediaPlayer2_isLooping},
-    {"native_setVolume",    "(F)V",                             (void *)android_media_MediaPlayer2_setVolume},
-    {"native_invoke",       "([B)[B",                           (void *)android_media_MediaPlayer2_invoke},
-    {"native_init",         "()V",                              (void *)android_media_MediaPlayer2_native_init},
-    {"native_setup",        "(ILjava/lang/Object;)V",           (void *)android_media_MediaPlayer2_native_setup},
-    {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer2_native_finalize},
-    {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer2_getAudioSessionId},
-    {"native_setAudioSessionId", "(I)V",                        (void *)android_media_MediaPlayer2_setAudioSessionId},
-    {"native_setAuxEffectSendLevel", "(F)V",                    (void *)android_media_MediaPlayer2_setAuxEffectSendLevel},
-    {"native_attachAuxEffect", "(I)V",                          (void *)android_media_MediaPlayer2_attachAuxEffect},
-    // Modular DRM
-    { "native_prepareDrm", "(J[B[B)V",                          (void *)android_media_MediaPlayer2_prepareDrm },
-    { "native_releaseDrm", "(J)V",                              (void *)android_media_MediaPlayer2_releaseDrm },
-
-    // AudioRouting
-    {"native_setPreferredDevice", "(Landroid/media/AudioDeviceInfo;)Z", (void *)android_media_MediaPlayer2_setPreferredDevice},
-    {"getRoutedDevice", "()Landroid/media/AudioDeviceInfo;", (void *)android_media_MediaPlayer2_getRoutedDevice},
-    {"native_addDeviceCallback", "(Landroid/media/RoutingDelegate;)V", (void *)android_media_MediaPlayer2_addDeviceCallback},
-    {"native_removeDeviceCallback", "(Landroid/media/AudioRouting$OnRoutingChangedListener;)V",
-            (void *)android_media_MediaPlayer2_removeDeviceCallback},
-
-    // StreamEventCallback for JAudioTrack
-    {"native_stream_event_onTearDown",                "(JJ)V",  (void *)android_media_MediaPlayer2_native_on_tear_down},
-    {"native_stream_event_onStreamPresentationEnd",   "(JJ)V",  (void *)android_media_MediaPlayer2_native_on_stream_presentation_end},
-    {"native_stream_event_onStreamDataRequest",       "(JJJ)V", (void *)android_media_MediaPlayer2_native_on_stream_data_request},
-};
-
-// This function only registers the native methods
-static int register_android_media_MediaPlayer2(JNIEnv *env)
-{
-    return jniRegisterNativeMethods(env, "android/media/MediaPlayer2", gMethods, NELEM(gMethods));
-}
-
-jint JNI_OnLoad(JavaVM* vm, void* /* reserved */)
-{
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        ALOGE("ERROR: GetEnv failed\n");
-        goto bail;
-    }
-    assert(env != NULL);
-
-    if (register_android_media_MediaPlayer2(env) < 0) {
-        ALOGE("ERROR: MediaPlayer2 native registration failed\n");
-        goto bail;
-    }
-
-    JavaVMHelper::setJavaVM(vm);
-
-    /* success -- return valid version number */
-    result = JNI_VERSION_1_4;
-
-bail:
-    return result;
-}
-
-// KTHXBYE
diff --git a/media/lib/signer/Android.bp b/media/lib/signer/Android.bp
index 2286c53..6b03e4d 100644
--- a/media/lib/signer/Android.bp
+++ b/media/lib/signer/Android.bp
@@ -16,9 +16,8 @@
 
 java_sdk_library {
     name: "com.android.mediadrm.signer",
-    srcs: [
-        "java/**/*.java",
-        ":framework-all-sources",
-    ],
+    srcs: ["java/**/*.java"],
+    api_srcs: [":framework-all-sources"],
+    libs: ["framework-all"],
     api_packages: ["com.android.mediadrm.signer"],
 }
diff --git a/media/proto/Android.bp b/media/proto/Android.bp
deleted file mode 100644
index 2dc0d57..0000000
--- a/media/proto/Android.bp
+++ /dev/null
@@ -1,20 +0,0 @@
-java_library_static {
-    name: "mediaplayer2-protos",
-    host_supported: true,
-    proto: {
-        type: "lite",
-    },
-    srcs: ["mediaplayer2.proto"],
-    jarjar_rules: "jarjar-rules.txt",
-    sdk_version: "28",
-}
-
-cc_library_static {
-    name: "libmediaplayer2-protos",
-    host_supported: true,
-    proto: {
-        export_proto_headers: true,
-        type: "lite",
-    },
-    srcs: ["mediaplayer2.proto"],
-}
diff --git a/media/proto/jarjar-rules.txt b/media/proto/jarjar-rules.txt
deleted file mode 100644
index e73f86d..0000000
--- a/media/proto/jarjar-rules.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-rule com.google.protobuf.** android.media.protobuf.@1
-
diff --git a/media/proto/mediaplayer2.proto b/media/proto/mediaplayer2.proto
deleted file mode 100644
index 6287d6c..0000000
--- a/media/proto/mediaplayer2.proto
+++ /dev/null
@@ -1,53 +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.
- */
-
-syntax = "proto2";
-
-option optimize_for = LITE_RUNTIME;
-
-// C++ namespace: android::media:MediaPlayer2Proto:
-package android.media.MediaPlayer2Proto;
-
-option java_package = "android.media";
-option java_outer_classname = "MediaPlayer2Proto";
-
-message Value {
-    // The kind of value.
-    oneof kind {
-        // Represents a boolean value.
-        bool bool_value = 1;
-        // Represents an int32 value.
-        int32 int32_value = 2;
-        // Represents an uint32 value.
-        uint32 uint32_value = 3;
-        // Represents an int64 value.
-        int64 int64_value = 4;
-        // Represents an uint64 value.
-        uint64 uint64_value = 5;
-        // Represents a float value.
-        double float_value = 6;
-        // Represents a double value.
-        double double_value = 7;
-        // Represents a string value.
-        string string_value = 8;
-        // Represents a bytes value.
-        bytes bytes_value = 9;
-    }
-}
-
-message PlayerMessage {
-    repeated Value values = 1;
-}
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 31a538c..4471818 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -27,4 +27,6 @@
     // Enforce that the library is built against java 7 so that there are
     // no compatibility issues with launcher
     java_version: "1.7",
+
+    min_sdk_version: "26",
 }
diff --git a/services/core/java/com/android/server/DynamicSystemService.java b/services/core/java/com/android/server/DynamicSystemService.java
index f92d0e0..173d5b0 100644
--- a/services/core/java/com/android/server/DynamicSystemService.java
+++ b/services/core/java/com/android/server/DynamicSystemService.java
@@ -21,6 +21,7 @@
 import android.gsi.GsiInstallParams;
 import android.gsi.GsiProgress;
 import android.gsi.IGsiService;
+import android.gsi.IGsid;
 import android.os.Environment;
 import android.os.IBinder;
 import android.os.IBinder.DeathRecipient;
@@ -61,7 +62,9 @@
          * re-initialized in this case.
          */
         binder.linkToDeath(recipient, 0);
-        return IGsiService.Stub.asInterface(binder);
+
+        IGsid gsid = IGsid.Stub.asInterface(binder);
+        return gsid.getClient();
     }
 
     /** implements DeathRecipient */
@@ -159,7 +162,7 @@
             isInUse = getGsiService().isGsiRunning();
         } finally {
             if (!gsidWasRunning && !isInUse) {
-                SystemProperties.set("ctl.stop", "gsid");
+                mGsiService = null;
             }
         }
 
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 8638432..4e8a74c 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -285,11 +285,12 @@
                 }
                 case MSG_UPDATE_DEFAULT_SUB: {
                     int newDefaultPhoneId = msg.arg1;
-                    int newDefaultSubId = (Integer)(msg.obj);
+                    int newDefaultSubId = msg.arg2;
                     if (VDBG) {
                         log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId
-                            + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= "
-                            + newDefaultSubId + " newDefaultPhoneId=" + newDefaultPhoneId);
+                                + " current mDefaultPhoneId=" + mDefaultPhoneId
+                                + " newDefaultSubId=" + newDefaultSubId
+                                + " newDefaultPhoneId=" + newDefaultPhoneId);
                     }
 
                     //Due to possible risk condition,(notify call back using the new
@@ -306,7 +307,7 @@
                     mDefaultSubId = newDefaultSubId;
                     mDefaultPhoneId = newDefaultPhoneId;
                     mLocalLog.log("Default subscription updated: mDefaultPhoneId="
-                            + mDefaultPhoneId + ", mDefaultSubId" + mDefaultSubId);
+                            + mDefaultPhoneId + ", mDefaultSubId=" + mDefaultSubId);
                 }
             }
         }
@@ -336,22 +337,25 @@
                 int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
                 if (DBG) log("onReceive: userHandle=" + userHandle);
                 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0));
-            } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
-                Integer newDefaultSubIdObj = new Integer(intent.getIntExtra(
-                        PhoneConstants.SUBSCRIPTION_KEY,
-                        SubscriptionManager.getDefaultSubscriptionId()));
-                int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.PHONE_KEY,
-                    SubscriptionManager.getPhoneId(mDefaultSubId));
+            } else if (action.equals(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) {
+                int newDefaultSubId = intent.getIntExtra(
+                        SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
+                        SubscriptionManager.getDefaultSubscriptionId());
+                int newDefaultPhoneId = intent.getIntExtra(
+                        PhoneConstants.PHONE_KEY,
+                        SubscriptionManager.getPhoneId(newDefaultSubId));
                 if (DBG) {
                     log("onReceive:current mDefaultSubId=" + mDefaultSubId
-                        + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= "
-                        + newDefaultSubIdObj + " newDefaultPhoneId=" + newDefaultPhoneId);
+                            + " current mDefaultPhoneId=" + mDefaultPhoneId
+                            + " newDefaultSubId=" + newDefaultSubId
+                            + " newDefaultPhoneId=" + newDefaultPhoneId);
                 }
 
-                if(validatePhoneId(newDefaultPhoneId) && (!newDefaultSubIdObj.equals(mDefaultSubId)
-                        || (newDefaultPhoneId != mDefaultPhoneId))) {
+                if (validatePhoneId(newDefaultPhoneId)
+                        && (newDefaultSubId != mDefaultSubId
+                                || newDefaultPhoneId != mDefaultPhoneId)) {
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_DEFAULT_SUB,
-                            newDefaultPhoneId, 0, newDefaultSubIdObj));
+                            newDefaultPhoneId, newDefaultSubId));
                 }
             }
         }
@@ -450,7 +454,7 @@
         final IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_USER_SWITCHED);
         filter.addAction(Intent.ACTION_USER_REMOVED);
-        filter.addAction(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
+        filter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
         log("systemRunning register for intents");
         mContext.registerReceiver(mBroadcastReceiver, filter);
     }
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 7569363..a35d2ee 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -705,7 +705,12 @@
         public void binderDied() {
             synchronized (AppOpsService.this) {
                 for (int i=mStartedOps.size()-1; i>=0; i--) {
-                    finishOperationLocked(mStartedOps.get(i), /*finishNested*/ true);
+                    final Op op = mStartedOps.get(i);
+                    finishOperationLocked(op, /*finishNested*/ true);
+                    if (op.startNesting <= 0) {
+                        scheduleOpActiveChangedIfNeededLocked(op.op, op.uidState.uid,
+                                op.packageName, false);
+                    }
                 }
                 mClients.remove(mAppToken);
             }
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 066e765..77b3fee 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -155,7 +155,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
- * The implementation of the volume manager service.
+ * The implementation of the audio service for volume, audio focus, device management...
  * <p>
  * This implementation focuses on delivering a responsive UI. Most methods are
  * asynchronous to external calls. For example, the task of setting a volume
diff --git a/services/core/java/com/android/server/audio/TEST_MAPPING b/services/core/java/com/android/server/audio/TEST_MAPPING
new file mode 100644
index 0000000..0d34c53
--- /dev/null
+++ b/services/core/java/com/android/server/audio/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+    "presubmit": [
+        {
+            "name": "CtsMediaTestCases",
+            "options": [
+                {
+                    "include-filter": "android.media.cts.AudioManagerTest"
+                },
+                {
+                    "include-filter": "android.media.cts.AudioFocusTest"
+                }
+            ]
+        }
+    ]
+}
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 81e507c..8e09d0e 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.util.Slog;
 import android.util.StatsLog;
 
@@ -40,7 +41,8 @@
 
     public PlatformCompat(Context context) {
         mContext = context;
-        mChangeReporter = new ChangeReporter();
+        mChangeReporter = new ChangeReporter(
+                StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
     }
 
     @Override
@@ -49,6 +51,15 @@
     }
 
     @Override
+    public void reportChangeByPackageName(long changeId, String packageName) {
+        ApplicationInfo appInfo = getApplicationInfo(packageName);
+        if (appInfo == null) {
+            return;
+        }
+        reportChange(changeId, appInfo);
+    }
+
+    @Override
     public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
         if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) {
             reportChange(changeId, appInfo,
@@ -61,17 +72,31 @@
     }
 
     @Override
+    public boolean isChangeEnabledByPackageName(long changeId, String packageName) {
+        ApplicationInfo appInfo = getApplicationInfo(packageName);
+        if (appInfo == null) {
+            return true;
+        }
+        return isChangeEnabled(changeId, appInfo);
+    }
+
+    @Override
     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
         CompatConfig.get().dumpConfig(pw);
     }
 
+    private ApplicationInfo getApplicationInfo(String packageName) {
+        try {
+            return mContext.getPackageManager().getApplicationInfo(packageName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            Slog.e(TAG, "No installed package " + packageName);
+        }
+        return null;
+    }
+
     private void reportChange(long changeId, ApplicationInfo appInfo, int state) {
         int uid = appInfo.uid;
-        //TODO(b/138374585): Implement rate limiting for the logs.
-        Slog.d(TAG, ChangeReporter.createLogString(uid, changeId, state));
-        mChangeReporter.reportChange(uid, changeId,
-                state, /* source */
-                StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__SOURCE__SYSTEM_SERVER);
+        mChangeReporter.reportChange(uid, changeId, state);
     }
 }
diff --git a/services/core/java/com/android/server/integrity/OWNERS b/services/core/java/com/android/server/integrity/OWNERS
new file mode 100644
index 0000000..019aa4f
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/OWNERS
@@ -0,0 +1,6 @@
+omernebil@google.com
+khelmy@google.com
+mdchurchill@google.com
+sturla@google.com
+songpan@google.com
+bjy@google.com
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 248351c..0aee850 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -456,6 +456,7 @@
                 return;
             }
             mDestroyed = true;
+            mPlaybackState = null;
             mHandler.post(MessageHandler.MSG_DESTROYED);
         }
     }
diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java
index b604aa8..1f20968 100644
--- a/services/core/java/com/android/server/om/IdmapManager.java
+++ b/services/core/java/com/android/server/om/IdmapManager.java
@@ -237,14 +237,9 @@
             return fulfilledPolicies | IIdmap2.POLICY_OEM_PARTITION;
         }
 
-        // Check partitions for which there exists no policy so overlays on these partitions will
-        // not fulfill the system policy.
-        if (ai.isProductServices()) {
-            return fulfilledPolicies;
-        }
-
+        // System_ext partition (/system_ext) is considered as system
         // Check this last since every partition except for data is scanned as system in the PMS.
-        if (ai.isSystemApp()) {
+        if (ai.isSystemApp() || ai.isSystemExt()) {
             return fulfilledPolicies | IIdmap2.POLICY_SYSTEM_PARTITION;
         }
 
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 9b6333d..3464cab 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -443,45 +443,39 @@
             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);
+            final PackageParser.Package pkg = pmInt.getPackage(appInfo.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;
+            // If app does not have any default enabled launcher activity or any permissions,
+            // the app can legitimately have no icon so we do not show the synthetic activity.
+            return requestsPermissions(pkg) && hasDefaultEnableLauncherActivity(
+                    appInfo.packageName);
         }
 
-        private boolean hasApplicationDeclaredActivities(@NonNull PackageParser.Package pkg) {
-            if (pkg.activities == null) {
-                return false;
+        private boolean requestsPermissions(@NonNull PackageParser.Package pkg) {
+            return !ArrayUtils.isEmpty(pkg.requestedPermissions);
+        }
+
+        private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) {
+            final PackageManagerInternal pmInt =
+                    LocalServices.getService(PackageManagerInternal.class);
+            final Intent matchIntent = new Intent(Intent.ACTION_MAIN);
+            matchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+            matchIntent.setPackage(packageName);
+            final List<ResolveInfo> infoList = pmInt.queryIntentActivities(matchIntent,
+                    PackageManager.MATCH_DISABLED_COMPONENTS, Binder.getCallingUid(),
+                    getCallingUserId());
+            final int size = infoList.size();
+            for (int i = 0; i < size; i++) {
+                if (infoList.get(i).activityInfo.enabled) {
+                    return true;
+                }
             }
-            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;
+            return false;
         }
 
         private boolean isManagedProfileAdmin(UserHandle user, String packageName) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 9094e1b..e5a2e77 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -376,12 +376,12 @@
                 continue;
             }
 
-            // If the path is in /system, /vendor, /product or /product_services, ignore. It will
+            // If the path is in /system, /vendor, /product or /system_ext, ignore. It will
             // have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
             if (pkg.codePath.startsWith("/system")
                     || pkg.codePath.startsWith("/vendor")
                     || pkg.codePath.startsWith("/product")
-                    || pkg.codePath.startsWith("/product_services")) {
+                    || pkg.codePath.startsWith("/system_ext")) {
                 continue;
             }
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 94d262b..aef7dc7f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -475,7 +475,7 @@
     static final int SCAN_AS_OEM = 1 << 19;
     static final int SCAN_AS_VENDOR = 1 << 20;
     static final int SCAN_AS_PRODUCT = 1 << 21;
-    static final int SCAN_AS_PRODUCT_SERVICES = 1 << 22;
+    static final int SCAN_AS_SYSTEM_EXT = 1 << 22;
     static final int SCAN_AS_ODM = 1 << 23;
 
     @IntDef(flag = true, prefix = { "SCAN_" }, value = {
@@ -593,7 +593,7 @@
 
     private static final String PRODUCT_OVERLAY_DIR = "/product/overlay";
 
-    private static final String PRODUCT_SERVICES_OVERLAY_DIR = "/product_services/overlay";
+    private static final String SYSTEM_EXT_OVERLAY_DIR = "/system_ext/overlay";
 
     private static final String ODM_OVERLAY_DIR = "/odm/overlay";
 
@@ -2604,7 +2604,7 @@
                 scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
             }
 
-            // Collect vendor/product/product_services overlay packages. (Do this before scanning
+            // Collect vendor/product/system_ext overlay packages. (Do this before scanning
             // any apps.)
             // For security and version matching reason, only consider overlay packages if they
             // reside in the right directory.
@@ -2622,12 +2622,12 @@
                     | SCAN_AS_SYSTEM
                     | SCAN_AS_PRODUCT,
                     0);
-            scanDirTracedLI(new File(PRODUCT_SERVICES_OVERLAY_DIR),
+            scanDirTracedLI(new File(SYSTEM_EXT_OVERLAY_DIR),
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
             scanDirTracedLI(new File(ODM_OVERLAY_DIR),
                     mDefParseFlags
@@ -2785,37 +2785,37 @@
                     | SCAN_AS_PRODUCT,
                     0);
 
-            // Collected privileged /product_services packages.
-            File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            // Collected privileged /system_ext packages.
+            File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             try {
-                privilegedProductServicesAppDir =
-                        privilegedProductServicesAppDir.getCanonicalFile();
+                privilegedSystemExtAppDir =
+                        privilegedSystemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(privilegedProductServicesAppDir,
+            scanDirTracedLI(privilegedSystemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES
+                    | SCAN_AS_SYSTEM_EXT
                     | SCAN_AS_PRIVILEGED,
                     0);
 
-            // Collect ordinary /product_services packages.
-            File productServicesAppDir = new File(Environment.getProductServicesDirectory(), "app");
+            // Collect ordinary /system_ext packages.
+            File systemExtAppDir = new File(Environment.getSystemExtDirectory(), "app");
             try {
-                productServicesAppDir = productServicesAppDir.getCanonicalFile();
+                systemExtAppDir = systemExtAppDir.getCanonicalFile();
             } catch (IOException e) {
                 // failed to look up canonical path, continue with original one
             }
-            scanDirTracedLI(productServicesAppDir,
+            scanDirTracedLI(systemExtAppDir,
                     mDefParseFlags
                     | PackageParser.PARSE_IS_SYSTEM_DIR,
                     scanFlags
                     | SCAN_AS_SYSTEM
-                    | SCAN_AS_PRODUCT_SERVICES,
+                    | SCAN_AS_SYSTEM_EXT,
                     0);
 
             // Prune any system packages that no longer exist.
@@ -3045,23 +3045,23 @@
                                     scanFlags
                                     | SCAN_AS_SYSTEM
                                     | SCAN_AS_PRODUCT;
-                        } else if (FileUtils.contains(privilegedProductServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(privilegedSystemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES
+                                    | SCAN_AS_SYSTEM_EXT
                                     | SCAN_AS_PRIVILEGED;
-                        } else if (FileUtils.contains(productServicesAppDir, scanFile)) {
+                        } else if (FileUtils.contains(systemExtAppDir, scanFile)) {
                             reparseFlags =
                                     mDefParseFlags |
                                     PackageParser.PARSE_IS_SYSTEM_DIR;
                             rescanFlags =
                                     scanFlags
                                     | SCAN_AS_SYSTEM
-                                    | SCAN_AS_PRODUCT_SERVICES;
+                                    | SCAN_AS_SYSTEM_EXT;
                         } else {
                             Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                             continue;
@@ -10849,7 +10849,7 @@
      * <li>{@link #SCAN_AS_OEM}</li>
      * <li>{@link #SCAN_AS_VENDOR}</li>
      * <li>{@link #SCAN_AS_PRODUCT}</li>
-     * <li>{@link #SCAN_AS_PRODUCT_SERVICES}</li>
+     * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
      * <li>{@link #SCAN_AS_INSTANT_APP}</li>
      * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
      * <li>{@link #SCAN_AS_ODM}</li>
@@ -10886,8 +10886,8 @@
                 scanFlags |= SCAN_AS_PRODUCT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
-                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0) {
-                scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+                    & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
+                scanFlags |= SCAN_AS_SYSTEM_EXT;
             }
             if ((systemPkgSetting.pkgPrivateFlags
                     & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
@@ -11669,8 +11669,8 @@
             pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         }
 
-        if ((scanFlags & SCAN_AS_PRODUCT_SERVICES) != 0) {
-            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+        if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) {
+            pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         }
 
         if ((scanFlags & SCAN_AS_ODM) != 0) {
@@ -12634,8 +12634,8 @@
             codeRoot = Environment.getOdmDirectory();
         } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
             codeRoot = Environment.getProductDirectory();
-        } else if (FileUtils.contains(Environment.getProductServicesDirectory(), codePath)) {
-            codeRoot = Environment.getProductServicesDirectory();
+        } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+            codeRoot = Environment.getSystemExtDirectory();
         } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
             codeRoot = Environment.getOdmDirectory();
         } else {
@@ -18192,9 +18192,9 @@
         return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    private static boolean isProductServicesApp(PackageParser.Package pkg) {
+    private static boolean isSystemExtApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.privateFlags
-                & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+                & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     private static boolean isOdmApp(PackageParser.Package pkg) {
@@ -18960,13 +18960,13 @@
             final File privilegedVendorAppDir = new File(Environment.getVendorDirectory(), "priv-app");
             final File privilegedOdmAppDir = new File(Environment.getOdmDirectory(), "priv-app");
             final File privilegedProductAppDir = new File(Environment.getProductDirectory(), "priv-app");
-            final File privilegedProductServicesAppDir =
-                    new File(Environment.getProductServicesDirectory(), "priv-app");
+            final File privilegedSystemExtAppDir =
+                    new File(Environment.getSystemExtDirectory(), "priv-app");
             return path.startsWith(privilegedAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedVendorAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedOdmAppDir.getCanonicalPath() + "/")
                     || path.startsWith(privilegedProductAppDir.getCanonicalPath() + "/")
-                    || path.startsWith(privilegedProductServicesAppDir.getCanonicalPath() + "/");
+                    || path.startsWith(privilegedSystemExtAppDir.getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -19001,10 +19001,10 @@
         return false;
     }
 
-    static boolean locationIsProductServices(String path) {
+    static boolean locationIsSystemExt(String path) {
         try {
             return path.startsWith(
-              Environment.getProductServicesDirectory().getCanonicalPath() + "/");
+              Environment.getSystemExtDirectory().getCanonicalPath() + "/");
         } catch (IOException e) {
             Slog.e(TAG, "Unable to access code path " + path);
         }
@@ -19137,8 +19137,8 @@
         if (locationIsProduct(codePathString)) {
             scanFlags |= SCAN_AS_PRODUCT;
         }
-        if (locationIsProductServices(codePathString)) {
-            scanFlags |= SCAN_AS_PRODUCT_SERVICES;
+        if (locationIsSystemExt(codePathString)) {
+            scanFlags |= SCAN_AS_SYSTEM_EXT;
         }
         if (locationIsOdm(codePathString)) {
             scanFlags |= SCAN_AS_ODM;
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 81de8e2..49af15f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1997,10 +1997,10 @@
         }
     }
 
-    private boolean isProductServicesApp(String pkg) {
+    private boolean isSystemExtApp(String pkg) {
         try {
             final PackageInfo info = mInterface.getPackageInfo(pkg, 0, UserHandle.USER_SYSTEM);
-            return info != null && info.applicationInfo.isProductServices();
+            return info != null && info.applicationInfo.isSystemExt();
         } catch (RemoteException e) {
             return false;
         }
@@ -2018,9 +2018,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppPermissions(pkg);
+                    .getSystemExtPrivAppPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg);
         }
@@ -2042,9 +2042,9 @@
             privAppPermissions = SystemConfig.getInstance().getVendorPrivAppDenyPermissions(pkg);
         } else if (isProductApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance().getProductPrivAppDenyPermissions(pkg);
-        } else if (isProductServicesApp(pkg)) {
+        } else if (isSystemExtApp(pkg)) {
             privAppPermissions = SystemConfig.getInstance()
-                    .getProductServicesPrivAppDenyPermissions(pkg);
+                    .getSystemExtPrivAppDenyPermissions(pkg);
         } else {
             privAppPermissions = SystemConfig.getInstance().getPrivAppDenyPermissions(pkg);
         }
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index e859893..4ea8a30 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -148,8 +148,8 @@
         return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
     }
 
-    public boolean isProductServices() {
-        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     public boolean isOdm() {
diff --git a/services/core/java/com/android/server/pm/SettingBase.java b/services/core/java/com/android/server/pm/SettingBase.java
index a24818f..ec9746d 100644
--- a/services/core/java/com/android/server/pm/SettingBase.java
+++ b/services/core/java/com/android/server/pm/SettingBase.java
@@ -63,7 +63,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER
                 | ApplicationInfo.PRIVATE_FLAG_ODM);
     }
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 11a8f4b..3bc2236 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -774,7 +774,7 @@
                 | ApplicationInfo.PRIVATE_FLAG_OEM
                 | ApplicationInfo.PRIVATE_FLAG_VENDOR
                 | ApplicationInfo.PRIVATE_FLAG_PRODUCT
-                | ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES
+                | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
                 | ApplicationInfo.PRIVATE_FLAG_ODM);
         pkgSetting.pkgFlags |= pkgFlags & ApplicationInfo.FLAG_SYSTEM;
         pkgSetting.pkgPrivateFlags |=
@@ -786,7 +786,7 @@
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT;
         pkgSetting.pkgPrivateFlags |=
-                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES;
+                pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
         pkgSetting.pkgPrivateFlags |=
                 pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
         pkgSetting.primaryCpuAbiString = primaryCpuAbi;
@@ -4413,7 +4413,7 @@
             ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY, "STATIC_SHARED_LIBRARY",
             ApplicationInfo.PRIVATE_FLAG_VENDOR, "VENDOR",
             ApplicationInfo.PRIVATE_FLAG_PRODUCT, "PRODUCT",
-            ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES, "PRODUCT_SERVICES",
+            ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT, "SYSTEM_EXT",
             ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD, "VIRTUAL_PRELOAD",
             ApplicationInfo.PRIVATE_FLAG_ODM, "ODM",
     };
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 4550446..f762985 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -1402,8 +1402,7 @@
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
-        dir = new File(Environment.getProductServicesDirectory(),
-                "etc/default-permissions");
+        dir = new File(Environment.getSystemExtDirectory(), "etc/default-permissions");
         if (dir.isDirectory() && dir.canRead()) {
             Collections.addAll(ret, dir.listFiles());
         }
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 8884821..7b25f6d 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -1642,9 +1642,9 @@
         } else if (pkg.isProduct()) {
             wlPermissions =
                     SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
-        } else if (pkg.isProductServices()) {
+        } else if (pkg.isSystemExt()) {
             wlPermissions =
-                    SystemConfig.getInstance().getProductServicesPrivAppPermissions(
+                    SystemConfig.getInstance().getSystemExtPrivAppPermissions(
                             pkg.packageName);
         } else {
             wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
@@ -1678,9 +1678,9 @@
                     } else if (pkg.isProduct()) {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getProductPrivAppDenyPermissions(pkg.packageName);
-                    } else if (pkg.isProductServices()) {
+                    } else if (pkg.isSystemExt()) {
                         deniedPermissions = SystemConfig.getInstance()
-                                .getProductServicesPrivAppDenyPermissions(pkg.packageName);
+                                .getSystemExtPrivAppDenyPermissions(pkg.packageName);
                     } else {
                         deniedPermissions = SystemConfig.getInstance()
                                 .getPrivAppDenyPermissions(pkg.packageName);
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 8f8f9f9..1ca96ed 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -1,87 +1,10 @@
-// AIDL interfaces between the core system and the networking mainline module.
-aidl_interface {
-    name: "ipmemorystore-aidl-interfaces",
-    local_include_dir: "java",
-    srcs: [
-        "java/android/net/IIpMemoryStore.aidl",
-        "java/android/net/IIpMemoryStoreCallbacks.aidl",
-        "java/android/net/ipmemorystore/**/*.aidl",
-    ],
-    backend: {
-        ndk: {
-            enabled: false,
-        },
-        cpp: {
-            enabled: false,
-        },
-    },
-    api_dir: "aidl/ipmemorystore",
-    versions: [
-        "1",
-        "2",
-        "3",
-    ],
-}
-
-aidl_interface {
-    name: "networkstack-aidl-interfaces",
-    local_include_dir: "java",
-    include_dirs: ["frameworks/base/core/java"], // For framework parcelables.
-    srcs: [
-        "java/android/net/DhcpResultsParcelable.aidl",
-        "java/android/net/INetworkMonitor.aidl",
-        "java/android/net/INetworkMonitorCallbacks.aidl",
-        "java/android/net/INetworkStackConnector.aidl",
-        "java/android/net/INetworkStackStatusCallback.aidl",
-        "java/android/net/InitialConfigurationParcelable.aidl",
-        "java/android/net/NattKeepalivePacketDataParcelable.aidl",
-        "java/android/net/PrivateDnsConfigParcel.aidl",
-        "java/android/net/ProvisioningConfigurationParcelable.aidl",
-        "java/android/net/TcpKeepalivePacketDataParcelable.aidl",
-        "java/android/net/dhcp/DhcpServingParamsParcel.aidl",
-        "java/android/net/dhcp/IDhcpServer.aidl",
-        "java/android/net/dhcp/IDhcpServerCallbacks.aidl",
-        "java/android/net/ip/IIpClient.aidl",
-        "java/android/net/ip/IIpClientCallbacks.aidl",
-    ],
-    backend: {
-        ndk: {
-            enabled: false,
-        },
-        cpp: {
-            enabled: false,
-        },
-    },
-    api_dir: "aidl/networkstack",
-    imports: ["ipmemorystore-aidl-interfaces"],
-    versions: [
-        "1",
-        "2",
-        "3",
-    ],
-}
-
 java_library_static {
     name: "services.net",
     srcs: ["java/**/*.java"],
     static_libs: [
         "dnsresolver_aidl_interface-V2-java",
-        "ipmemorystore-client",
         "netd_aidl_interface-java",
-        "networkstack-aidl-interfaces-V3-java",
-    ],
-}
-
-java_library_static {
-    name: "ipmemorystore-client",
-    sdk_version: "system_current",
-    srcs: [
-        ":framework-annotations",
-        "java/android/net/IpMemoryStoreClient.java",
-        "java/android/net/ipmemorystore/**/*.java",
-    ],
-    static_libs: [
-        "ipmemorystore-aidl-interfaces-V3-java",
+        "networkstack-client",
     ],
 }
 
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
deleted file mode 100644
index a8cbab2..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStore.aidl
+++ /dev/null
@@ -1,9 +0,0 @@
-package android.net;
-interface IIpMemoryStore {
-  oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
-  oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
-  oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
-  oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
deleted file mode 100644
index cf02c26..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/IIpMemoryStoreCallbacks.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net;
-interface IIpMemoryStoreCallbacks {
-  oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
deleted file mode 100644
index 291dbef..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/Blob.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-parcelable Blob {
-  byte[] data;
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
deleted file mode 100644
index 52f40d4..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnBlobRetrievedListener {
-  oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
deleted file mode 100644
index 7853514..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnL2KeyResponseListener {
-  oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
deleted file mode 100644
index 3dd2ae6..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnNetworkAttributesRetrievedListener {
-  oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
deleted file mode 100644
index 46d4ecb..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnSameL3NetworkResponseListener {
-  oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
deleted file mode 100644
index 54e654b..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/IOnStatusListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnStatusListener {
-  oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
deleted file mode 100644
index 9531ea3..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net.ipmemorystore;
-parcelable NetworkAttributesParcelable {
-  byte[] assignedV4Address;
-  long assignedV4AddressExpiry;
-  String groupHint;
-  android.net.ipmemorystore.Blob[] dnsAddresses;
-  int mtu;
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
deleted file mode 100644
index 414272b..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ /dev/null
@@ -1,6 +0,0 @@
-package android.net.ipmemorystore;
-parcelable SameL3NetworkResponseParcelable {
-  String l2Key1;
-  String l2Key2;
-  float confidence;
-}
diff --git a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
deleted file mode 100644
index 92c6779..0000000
--- a/services/net/aidl/ipmemorystore/1/android/net/ipmemorystore/StatusParcelable.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-parcelable StatusParcelable {
-  int resultCode;
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl
deleted file mode 100644
index a8cbab2..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStore.aidl
+++ /dev/null
@@ -1,9 +0,0 @@
-package android.net;
-interface IIpMemoryStore {
-  oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
-  oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
-  oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
-  oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl
deleted file mode 100644
index cf02c26..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/IIpMemoryStoreCallbacks.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net;
-interface IIpMemoryStoreCallbacks {
-  oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl
deleted file mode 100644
index 291dbef..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/Blob.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-parcelable Blob {
-  byte[] data;
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
deleted file mode 100644
index 52f40d4..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnBlobRetrievedListener {
-  oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
deleted file mode 100644
index 7853514..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnL2KeyResponseListener {
-  oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
deleted file mode 100644
index 3dd2ae6..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnNetworkAttributesRetrievedListener {
-  oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
deleted file mode 100644
index 46d4ecb..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnSameL3NetworkResponseListener {
-  oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl
deleted file mode 100644
index 54e654b..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/IOnStatusListener.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-interface IOnStatusListener {
-  oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
deleted file mode 100644
index 9531ea3..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net.ipmemorystore;
-parcelable NetworkAttributesParcelable {
-  byte[] assignedV4Address;
-  long assignedV4AddressExpiry;
-  String groupHint;
-  android.net.ipmemorystore.Blob[] dnsAddresses;
-  int mtu;
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
deleted file mode 100644
index 414272b..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ /dev/null
@@ -1,6 +0,0 @@
-package android.net.ipmemorystore;
-parcelable SameL3NetworkResponseParcelable {
-  String l2Key1;
-  String l2Key2;
-  float confidence;
-}
diff --git a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl
deleted file mode 100644
index 92c6779..0000000
--- a/services/net/aidl/ipmemorystore/2/android/net/ipmemorystore/StatusParcelable.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.ipmemorystore;
-parcelable StatusParcelable {
-  int resultCode;
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
deleted file mode 100644
index 30893b2..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStore.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface IIpMemoryStore {
-  oneway void storeNetworkAttributes(String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void storeBlob(String l2Key, String clientId, String name, in android.net.ipmemorystore.Blob data, android.net.ipmemorystore.IOnStatusListener listener);
-  oneway void findL2Key(in android.net.ipmemorystore.NetworkAttributesParcelable attributes, android.net.ipmemorystore.IOnL2KeyResponseListener listener);
-  oneway void isSameNetwork(String l2Key1, String l2Key2, android.net.ipmemorystore.IOnSameL3NetworkResponseListener listener);
-  oneway void retrieveNetworkAttributes(String l2Key, android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener listener);
-  oneway void retrieveBlob(String l2Key, String clientId, String name, android.net.ipmemorystore.IOnBlobRetrievedListener listener);
-  oneway void factoryReset();
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
deleted file mode 100644
index 535ae2c..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/IIpMemoryStoreCallbacks.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface IIpMemoryStoreCallbacks {
-  oneway void onIpMemoryStoreFetched(in android.net.IIpMemoryStore ipMemoryStore);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
deleted file mode 100644
index 6d2dc0c..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/Blob.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-parcelable Blob {
-  byte[] data;
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
deleted file mode 100644
index 48c1fb8..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-interface IOnBlobRetrievedListener {
-  oneway void onBlobRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in String name, in android.net.ipmemorystore.Blob data);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
deleted file mode 100644
index aebc724..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-interface IOnL2KeyResponseListener {
-  oneway void onL2KeyResponse(in android.net.ipmemorystore.StatusParcelable status, in String l2Key);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
deleted file mode 100644
index b66db5a..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-interface IOnNetworkAttributesRetrievedListener {
-  oneway void onNetworkAttributesRetrieved(in android.net.ipmemorystore.StatusParcelable status, in String l2Key, in android.net.ipmemorystore.NetworkAttributesParcelable attributes);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
deleted file mode 100644
index e9f2db4..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-interface IOnSameL3NetworkResponseListener {
-  oneway void onSameL3NetworkResponse(in android.net.ipmemorystore.StatusParcelable status, in android.net.ipmemorystore.SameL3NetworkResponseParcelable response);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
deleted file mode 100644
index 49172ce..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/IOnStatusListener.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-interface IOnStatusListener {
-  oneway void onComplete(in android.net.ipmemorystore.StatusParcelable status);
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
deleted file mode 100644
index 188db20..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-parcelable NetworkAttributesParcelable {
-  byte[] assignedV4Address;
-  long assignedV4AddressExpiry;
-  String groupHint;
-  android.net.ipmemorystore.Blob[] dnsAddresses;
-  int mtu;
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
deleted file mode 100644
index 7a2ed48..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-parcelable SameL3NetworkResponseParcelable {
-  String l2Key1;
-  String l2Key2;
-  float confidence;
-}
diff --git a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
deleted file mode 100644
index d9b0678..0000000
--- a/services/net/aidl/ipmemorystore/3/android/net/ipmemorystore/StatusParcelable.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ipmemorystore;
-parcelable StatusParcelable {
-  int resultCode;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
deleted file mode 100644
index 92b5345..0000000
--- a/services/net/aidl/networkstack/1/android/net/DhcpResultsParcelable.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net;
-parcelable DhcpResultsParcelable {
-  android.net.StaticIpConfiguration baseConfiguration;
-  int leaseDuration;
-  int mtu;
-  String serverAddress;
-  String vendorInfo;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
deleted file mode 100644
index b19f522..0000000
--- a/services/net/aidl/networkstack/1/android/net/INetworkMonitor.aidl
+++ /dev/null
@@ -1,17 +0,0 @@
-package android.net;
-interface INetworkMonitor {
-  oneway void start();
-  oneway void launchCaptivePortalApp();
-  oneway void notifyCaptivePortalAppFinished(int response);
-  oneway void setAcceptPartialConnectivity();
-  oneway void forceReevaluation(int uid);
-  oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
-  oneway void notifyDnsResponse(int returnCode);
-  oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
-  oneway void notifyNetworkDisconnected();
-  oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
-  oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
-  const int NETWORK_TEST_RESULT_VALID = 0;
-  const int NETWORK_TEST_RESULT_INVALID = 1;
-  const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
deleted file mode 100644
index ee9871d..0000000
--- a/services/net/aidl/networkstack/1/android/net/INetworkMonitorCallbacks.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net;
-interface INetworkMonitorCallbacks {
-  oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
-  oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
-  oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
-  oneway void showProvisioningNotification(String action, String packageName);
-  oneway void hideProvisioningNotification();
-}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
deleted file mode 100644
index 7da11e4..0000000
--- a/services/net/aidl/networkstack/1/android/net/INetworkStackConnector.aidl
+++ /dev/null
@@ -1,7 +0,0 @@
-package android.net;
-interface INetworkStackConnector {
-  oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
-  oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
-  oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
-  oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
-}
diff --git a/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
deleted file mode 100644
index f6ca6f7..0000000
--- a/services/net/aidl/networkstack/1/android/net/INetworkStackStatusCallback.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net;
-interface INetworkStackStatusCallback {
-  oneway void onStatusAvailable(int statusCode);
-}
diff --git a/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
deleted file mode 100644
index c80a787..0000000
--- a/services/net/aidl/networkstack/1/android/net/InitialConfigurationParcelable.aidl
+++ /dev/null
@@ -1,7 +0,0 @@
-package android.net;
-parcelable InitialConfigurationParcelable {
-  android.net.LinkAddress[] ipAddresses;
-  android.net.IpPrefix[] directlyConnectedRoutes;
-  String[] dnsServers;
-  String gateway;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
deleted file mode 100644
index 2de790b..0000000
--- a/services/net/aidl/networkstack/1/android/net/PrivateDnsConfigParcel.aidl
+++ /dev/null
@@ -1,5 +0,0 @@
-package android.net;
-parcelable PrivateDnsConfigParcel {
-  String hostname;
-  String[] ips;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
deleted file mode 100644
index 3a6c304..0000000
--- a/services/net/aidl/networkstack/1/android/net/ProvisioningConfigurationParcelable.aidl
+++ /dev/null
@@ -1,15 +0,0 @@
-package android.net;
-parcelable ProvisioningConfigurationParcelable {
-  boolean enableIPv4;
-  boolean enableIPv6;
-  boolean usingMultinetworkPolicyTracker;
-  boolean usingIpReachabilityMonitor;
-  int requestedPreDhcpActionMs;
-  android.net.InitialConfigurationParcelable initialConfig;
-  android.net.StaticIpConfiguration staticIpConfig;
-  android.net.apf.ApfCapabilities apfCapabilities;
-  int provisioningTimeoutMs;
-  int ipv6AddrGenMode;
-  android.net.Network network;
-  String displayName;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index e121c06..0000000
--- a/services/net/aidl/networkstack/1/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,13 +0,0 @@
-package android.net;
-parcelable TcpKeepalivePacketDataParcelable {
-  byte[] srcAddress;
-  int srcPort;
-  byte[] dstAddress;
-  int dstPort;
-  int seq;
-  int ack;
-  int rcvWnd;
-  int rcvWndScale;
-  int tos;
-  int ttl;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
deleted file mode 100644
index 67193ae..0000000
--- a/services/net/aidl/networkstack/1/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ /dev/null
@@ -1,11 +0,0 @@
-package android.net.dhcp;
-parcelable DhcpServingParamsParcel {
-  int serverAddr;
-  int serverAddrPrefixLength;
-  int[] defaultRouters;
-  int[] dnsServers;
-  int[] excludedAddrs;
-  long dhcpLeaseTimeSecs;
-  int linkMtu;
-  boolean metered;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
deleted file mode 100644
index 9143158..0000000
--- a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServer.aidl
+++ /dev/null
@@ -1,10 +0,0 @@
-package android.net.dhcp;
-interface IDhcpServer {
-  oneway void start(in android.net.INetworkStackStatusCallback cb);
-  oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
-  oneway void stop(in android.net.INetworkStackStatusCallback cb);
-  const int STATUS_UNKNOWN = 0;
-  const int STATUS_SUCCESS = 1;
-  const int STATUS_INVALID_ARGUMENT = 2;
-  const int STATUS_UNKNOWN_ERROR = 3;
-}
diff --git a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
deleted file mode 100644
index dcc4489..0000000
--- a/services/net/aidl/networkstack/1/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.dhcp;
-interface IDhcpServerCallbacks {
-  oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
-}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
deleted file mode 100644
index 95a1574..0000000
--- a/services/net/aidl/networkstack/1/android/net/ip/IIpClient.aidl
+++ /dev/null
@@ -1,14 +0,0 @@
-package android.net.ip;
-interface IIpClient {
-  oneway void completedPreDhcpAction();
-  oneway void confirmConfiguration();
-  oneway void readPacketFilterComplete(in byte[] data);
-  oneway void shutdown();
-  oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
-  oneway void stop();
-  oneway void setTcpBufferSizes(in String tcpBufferSizes);
-  oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
-  oneway void setMulticastFilter(boolean enabled);
-  oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
-  oneway void removeKeepalivePacketFilter(int slot);
-}
diff --git a/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
deleted file mode 100644
index d6bc808..0000000
--- a/services/net/aidl/networkstack/1/android/net/ip/IIpClientCallbacks.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package android.net.ip;
-interface IIpClientCallbacks {
-  oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
-  oneway void onPreDhcpAction();
-  oneway void onPostDhcpAction();
-  oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
-  oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
-  oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
-  oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
-  oneway void onReachabilityLost(in String logMsg);
-  oneway void onQuit();
-  oneway void installPacketFilter(in byte[] filter);
-  oneway void startReadPacketFilter();
-  oneway void setFallbackMulticastFilter(boolean enabled);
-  oneway void setNeighborDiscoveryOffload(boolean enable);
-}
diff --git a/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl
deleted file mode 100644
index 31891de..0000000
--- a/services/net/aidl/networkstack/2/android/net/DhcpResultsParcelable.aidl
+++ /dev/null
@@ -1,9 +0,0 @@
-package android.net;
-parcelable DhcpResultsParcelable {
-  android.net.StaticIpConfiguration baseConfiguration;
-  int leaseDuration;
-  int mtu;
-  String serverAddress;
-  String vendorInfo;
-  String serverHostName;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl
deleted file mode 100644
index 029968b..0000000
--- a/services/net/aidl/networkstack/2/android/net/INetworkMonitor.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-package android.net;
-interface INetworkMonitor {
-  oneway void start();
-  oneway void launchCaptivePortalApp();
-  oneway void notifyCaptivePortalAppFinished(int response);
-  oneway void setAcceptPartialConnectivity();
-  oneway void forceReevaluation(int uid);
-  oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
-  oneway void notifyDnsResponse(int returnCode);
-  oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
-  oneway void notifyNetworkDisconnected();
-  oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
-  oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
-  const int NETWORK_TEST_RESULT_VALID = 0;
-  const int NETWORK_TEST_RESULT_INVALID = 1;
-  const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
-  const int NETWORK_VALIDATION_RESULT_VALID = 1;
-  const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
-  const int NETWORK_VALIDATION_PROBE_DNS = 4;
-  const int NETWORK_VALIDATION_PROBE_HTTP = 8;
-  const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
-  const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
-  const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl
deleted file mode 100644
index ee9871d..0000000
--- a/services/net/aidl/networkstack/2/android/net/INetworkMonitorCallbacks.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net;
-interface INetworkMonitorCallbacks {
-  oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
-  oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
-  oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
-  oneway void showProvisioningNotification(String action, String packageName);
-  oneway void hideProvisioningNotification();
-}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl
deleted file mode 100644
index 7da11e4..0000000
--- a/services/net/aidl/networkstack/2/android/net/INetworkStackConnector.aidl
+++ /dev/null
@@ -1,7 +0,0 @@
-package android.net;
-interface INetworkStackConnector {
-  oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
-  oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
-  oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
-  oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
-}
diff --git a/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl
deleted file mode 100644
index f6ca6f7..0000000
--- a/services/net/aidl/networkstack/2/android/net/INetworkStackStatusCallback.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net;
-interface INetworkStackStatusCallback {
-  oneway void onStatusAvailable(int statusCode);
-}
diff --git a/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl
deleted file mode 100644
index c80a787..0000000
--- a/services/net/aidl/networkstack/2/android/net/InitialConfigurationParcelable.aidl
+++ /dev/null
@@ -1,7 +0,0 @@
-package android.net;
-parcelable InitialConfigurationParcelable {
-  android.net.LinkAddress[] ipAddresses;
-  android.net.IpPrefix[] directlyConnectedRoutes;
-  String[] dnsServers;
-  String gateway;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index 65de883..0000000
--- a/services/net/aidl/networkstack/2/android/net/NattKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,7 +0,0 @@
-package android.net;
-parcelable NattKeepalivePacketDataParcelable {
-  byte[] srcAddress;
-  int srcPort;
-  byte[] dstAddress;
-  int dstPort;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl
deleted file mode 100644
index 2de790b..0000000
--- a/services/net/aidl/networkstack/2/android/net/PrivateDnsConfigParcel.aidl
+++ /dev/null
@@ -1,5 +0,0 @@
-package android.net;
-parcelable PrivateDnsConfigParcel {
-  String hostname;
-  String[] ips;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl
deleted file mode 100644
index 3a6c304..0000000
--- a/services/net/aidl/networkstack/2/android/net/ProvisioningConfigurationParcelable.aidl
+++ /dev/null
@@ -1,15 +0,0 @@
-package android.net;
-parcelable ProvisioningConfigurationParcelable {
-  boolean enableIPv4;
-  boolean enableIPv6;
-  boolean usingMultinetworkPolicyTracker;
-  boolean usingIpReachabilityMonitor;
-  int requestedPreDhcpActionMs;
-  android.net.InitialConfigurationParcelable initialConfig;
-  android.net.StaticIpConfiguration staticIpConfig;
-  android.net.apf.ApfCapabilities apfCapabilities;
-  int provisioningTimeoutMs;
-  int ipv6AddrGenMode;
-  android.net.Network network;
-  String displayName;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index e121c06..0000000
--- a/services/net/aidl/networkstack/2/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,13 +0,0 @@
-package android.net;
-parcelable TcpKeepalivePacketDataParcelable {
-  byte[] srcAddress;
-  int srcPort;
-  byte[] dstAddress;
-  int dstPort;
-  int seq;
-  int ack;
-  int rcvWnd;
-  int rcvWndScale;
-  int tos;
-  int ttl;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl
deleted file mode 100644
index 67193ae..0000000
--- a/services/net/aidl/networkstack/2/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ /dev/null
@@ -1,11 +0,0 @@
-package android.net.dhcp;
-parcelable DhcpServingParamsParcel {
-  int serverAddr;
-  int serverAddrPrefixLength;
-  int[] defaultRouters;
-  int[] dnsServers;
-  int[] excludedAddrs;
-  long dhcpLeaseTimeSecs;
-  int linkMtu;
-  boolean metered;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl
deleted file mode 100644
index 9143158..0000000
--- a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServer.aidl
+++ /dev/null
@@ -1,10 +0,0 @@
-package android.net.dhcp;
-interface IDhcpServer {
-  oneway void start(in android.net.INetworkStackStatusCallback cb);
-  oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
-  oneway void stop(in android.net.INetworkStackStatusCallback cb);
-  const int STATUS_UNKNOWN = 0;
-  const int STATUS_SUCCESS = 1;
-  const int STATUS_INVALID_ARGUMENT = 2;
-  const int STATUS_UNKNOWN_ERROR = 3;
-}
diff --git a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl
deleted file mode 100644
index dcc4489..0000000
--- a/services/net/aidl/networkstack/2/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ /dev/null
@@ -1,4 +0,0 @@
-package android.net.dhcp;
-interface IDhcpServerCallbacks {
-  oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
-}
diff --git a/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl
deleted file mode 100644
index 77d5917..0000000
--- a/services/net/aidl/networkstack/2/android/net/ip/IIpClient.aidl
+++ /dev/null
@@ -1,15 +0,0 @@
-package android.net.ip;
-interface IIpClient {
-  oneway void completedPreDhcpAction();
-  oneway void confirmConfiguration();
-  oneway void readPacketFilterComplete(in byte[] data);
-  oneway void shutdown();
-  oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
-  oneway void stop();
-  oneway void setTcpBufferSizes(in String tcpBufferSizes);
-  oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
-  oneway void setMulticastFilter(boolean enabled);
-  oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
-  oneway void removeKeepalivePacketFilter(int slot);
-  oneway void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
-}
diff --git a/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl
deleted file mode 100644
index d6bc808..0000000
--- a/services/net/aidl/networkstack/2/android/net/ip/IIpClientCallbacks.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-package android.net.ip;
-interface IIpClientCallbacks {
-  oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
-  oneway void onPreDhcpAction();
-  oneway void onPostDhcpAction();
-  oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
-  oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
-  oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
-  oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
-  oneway void onReachabilityLost(in String logMsg);
-  oneway void onQuit();
-  oneway void installPacketFilter(in byte[] filter);
-  oneway void startReadPacketFilter();
-  oneway void setFallbackMulticastFilter(boolean enabled);
-  oneway void setNeighborDiscoveryOffload(boolean enable);
-}
diff --git a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl b/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
deleted file mode 100644
index 07ff321..0000000
--- a/services/net/aidl/networkstack/3/android/net/DhcpResultsParcelable.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable DhcpResultsParcelable {
-  android.net.StaticIpConfiguration baseConfiguration;
-  int leaseDuration;
-  int mtu;
-  String serverAddress;
-  String vendorInfo;
-  String serverHostName;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
deleted file mode 100644
index 8aa68bd..0000000
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitor.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetworkMonitor {
-  oneway void start();
-  oneway void launchCaptivePortalApp();
-  oneway void notifyCaptivePortalAppFinished(int response);
-  oneway void setAcceptPartialConnectivity();
-  oneway void forceReevaluation(int uid);
-  oneway void notifyPrivateDnsChanged(in android.net.PrivateDnsConfigParcel config);
-  oneway void notifyDnsResponse(int returnCode);
-  oneway void notifyNetworkConnected(in android.net.LinkProperties lp, in android.net.NetworkCapabilities nc);
-  oneway void notifyNetworkDisconnected();
-  oneway void notifyLinkPropertiesChanged(in android.net.LinkProperties lp);
-  oneway void notifyNetworkCapabilitiesChanged(in android.net.NetworkCapabilities nc);
-  const int NETWORK_TEST_RESULT_VALID = 0;
-  const int NETWORK_TEST_RESULT_INVALID = 1;
-  const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
-  const int NETWORK_VALIDATION_RESULT_VALID = 1;
-  const int NETWORK_VALIDATION_RESULT_PARTIAL = 2;
-  const int NETWORK_VALIDATION_PROBE_DNS = 4;
-  const int NETWORK_VALIDATION_PROBE_HTTP = 8;
-  const int NETWORK_VALIDATION_PROBE_HTTPS = 16;
-  const int NETWORK_VALIDATION_PROBE_FALLBACK = 32;
-  const int NETWORK_VALIDATION_PROBE_PRIVDNS = 64;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
deleted file mode 100644
index ea93729..0000000
--- a/services/net/aidl/networkstack/3/android/net/INetworkMonitorCallbacks.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetworkMonitorCallbacks {
-  oneway void onNetworkMonitorCreated(in android.net.INetworkMonitor networkMonitor);
-  oneway void notifyNetworkTested(int testResult, @nullable String redirectUrl);
-  oneway void notifyPrivateDnsConfigResolved(in android.net.PrivateDnsConfigParcel config);
-  oneway void showProvisioningNotification(String action, String packageName);
-  oneway void hideProvisioningNotification();
-}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
deleted file mode 100644
index e3a83d1..0000000
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackConnector.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetworkStackConnector {
-  oneway void makeDhcpServer(in String ifName, in android.net.dhcp.DhcpServingParamsParcel params, in android.net.dhcp.IDhcpServerCallbacks cb);
-  oneway void makeNetworkMonitor(in android.net.Network network, String name, in android.net.INetworkMonitorCallbacks cb);
-  oneway void makeIpClient(in String ifName, in android.net.ip.IIpClientCallbacks callbacks);
-  oneway void fetchIpMemoryStore(in android.net.IIpMemoryStoreCallbacks cb);
-}
diff --git a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl b/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
deleted file mode 100644
index 3112a08..0000000
--- a/services/net/aidl/networkstack/3/android/net/INetworkStackStatusCallback.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetworkStackStatusCallback {
-  oneway void onStatusAvailable(int statusCode);
-}
diff --git a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
deleted file mode 100644
index f846b26..0000000
--- a/services/net/aidl/networkstack/3/android/net/InitialConfigurationParcelable.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable InitialConfigurationParcelable {
-  android.net.LinkAddress[] ipAddresses;
-  android.net.IpPrefix[] directlyConnectedRoutes;
-  String[] dnsServers;
-  String gateway;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index de75940..0000000
--- a/services/net/aidl/networkstack/3/android/net/NattKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable NattKeepalivePacketDataParcelable {
-  byte[] srcAddress;
-  int srcPort;
-  byte[] dstAddress;
-  int dstPort;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl b/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
deleted file mode 100644
index cf0fbce9..0000000
--- a/services/net/aidl/networkstack/3/android/net/PrivateDnsConfigParcel.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable PrivateDnsConfigParcel {
-  String hostname;
-  String[] ips;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
deleted file mode 100644
index c0f2d4d..0000000
--- a/services/net/aidl/networkstack/3/android/net/ProvisioningConfigurationParcelable.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable ProvisioningConfigurationParcelable {
-  boolean enableIPv4;
-  boolean enableIPv6;
-  boolean usingMultinetworkPolicyTracker;
-  boolean usingIpReachabilityMonitor;
-  int requestedPreDhcpActionMs;
-  android.net.InitialConfigurationParcelable initialConfig;
-  android.net.StaticIpConfiguration staticIpConfig;
-  android.net.apf.ApfCapabilities apfCapabilities;
-  int provisioningTimeoutMs;
-  int ipv6AddrGenMode;
-  android.net.Network network;
-  String displayName;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index 5926794..0000000
--- a/services/net/aidl/networkstack/3/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable TcpKeepalivePacketDataParcelable {
-  byte[] srcAddress;
-  int srcPort;
-  byte[] dstAddress;
-  int dstPort;
-  int seq;
-  int ack;
-  int rcvWnd;
-  int rcvWndScale;
-  int tos;
-  int ttl;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
deleted file mode 100644
index 7ab156f..0000000
--- a/services/net/aidl/networkstack/3/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.dhcp;
-parcelable DhcpServingParamsParcel {
-  int serverAddr;
-  int serverAddrPrefixLength;
-  int[] defaultRouters;
-  int[] dnsServers;
-  int[] excludedAddrs;
-  long dhcpLeaseTimeSecs;
-  int linkMtu;
-  boolean metered;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
deleted file mode 100644
index d281ecf..0000000
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServer.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.dhcp;
-interface IDhcpServer {
-  oneway void start(in android.net.INetworkStackStatusCallback cb);
-  oneway void updateParams(in android.net.dhcp.DhcpServingParamsParcel params, in android.net.INetworkStackStatusCallback cb);
-  oneway void stop(in android.net.INetworkStackStatusCallback cb);
-  const int STATUS_UNKNOWN = 0;
-  const int STATUS_SUCCESS = 1;
-  const int STATUS_INVALID_ARGUMENT = 2;
-  const int STATUS_UNKNOWN_ERROR = 3;
-}
diff --git a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
deleted file mode 100644
index 98be0ab..0000000
--- a/services/net/aidl/networkstack/3/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.dhcp;
-interface IDhcpServerCallbacks {
-  oneway void onDhcpServerCreated(int statusCode, in android.net.dhcp.IDhcpServer server);
-}
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
deleted file mode 100644
index 85c8676..0000000
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClient.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ip;
-interface IIpClient {
-  oneway void completedPreDhcpAction();
-  oneway void confirmConfiguration();
-  oneway void readPacketFilterComplete(in byte[] data);
-  oneway void shutdown();
-  oneway void startProvisioning(in android.net.ProvisioningConfigurationParcelable req);
-  oneway void stop();
-  oneway void setTcpBufferSizes(in String tcpBufferSizes);
-  oneway void setHttpProxy(in android.net.ProxyInfo proxyInfo);
-  oneway void setMulticastFilter(boolean enabled);
-  oneway void addKeepalivePacketFilter(int slot, in android.net.TcpKeepalivePacketDataParcelable pkt);
-  oneway void removeKeepalivePacketFilter(int slot);
-  oneway void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
-  oneway void addNattKeepalivePacketFilter(int slot, in android.net.NattKeepalivePacketDataParcelable pkt);
-}
diff --git a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl b/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
deleted file mode 100644
index 7fe39ed..0000000
--- a/services/net/aidl/networkstack/3/android/net/ip/IIpClientCallbacks.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.ip;
-interface IIpClientCallbacks {
-  oneway void onIpClientCreated(in android.net.ip.IIpClient ipClient);
-  oneway void onPreDhcpAction();
-  oneway void onPostDhcpAction();
-  oneway void onNewDhcpResults(in android.net.DhcpResultsParcelable dhcpResults);
-  oneway void onProvisioningSuccess(in android.net.LinkProperties newLp);
-  oneway void onProvisioningFailure(in android.net.LinkProperties newLp);
-  oneway void onLinkPropertiesChange(in android.net.LinkProperties newLp);
-  oneway void onReachabilityLost(in String logMsg);
-  oneway void onQuit();
-  oneway void installPacketFilter(in byte[] filter);
-  oneway void startReadPacketFilter();
-  oneway void setFallbackMulticastFilter(boolean enabled);
-  oneway void setNeighborDiscoveryOffload(boolean enable);
-}
diff --git a/services/net/java/android/net/DhcpResultsParcelable.aidl b/services/net/java/android/net/DhcpResultsParcelable.aidl
deleted file mode 100644
index c98d9c2..0000000
--- a/services/net/java/android/net/DhcpResultsParcelable.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * 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 perNmissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import android.net.StaticIpConfiguration;
-
-parcelable DhcpResultsParcelable {
-    StaticIpConfiguration baseConfiguration;
-    int leaseDuration;
-    int mtu;
-    String serverAddress;
-    String vendorInfo;
-    String serverHostName;
-}
diff --git a/services/net/java/android/net/IIpMemoryStore.aidl b/services/net/java/android/net/IIpMemoryStore.aidl
deleted file mode 100644
index add221a..0000000
--- a/services/net/java/android/net/IIpMemoryStore.aidl
+++ /dev/null
@@ -1,118 +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 android.net;
-
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.IOnBlobRetrievedListener;
-import android.net.ipmemorystore.IOnL2KeyResponseListener;
-import android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.IOnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.IOnStatusListener;
-
-/** {@hide} */
-oneway interface IIpMemoryStore {
-    /**
-     * Store network attributes for a given L2 key.
-     * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
-     * calling findL2Key with the attributes and storing in the returned value.
-     *
-     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
-     *              key and only care about grouping can pass a unique ID here like the ones
-     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
-     *              relevance of such a network will lead to it being evicted soon if it's not
-     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
-     * @param attributes The attributes for this network.
-     * @param listener A listener that will be invoked to inform of the completion of this call,
-     *                 or null if the client is not interested in learning about success/failure.
-     * @return (through the listener) The L2 key. This is useful if the L2 key was not specified.
-     *         If the call failed, the L2 key will be null.
-     */
-    void storeNetworkAttributes(String l2Key, in NetworkAttributesParcelable attributes,
-            IOnStatusListener listener);
-
-    /**
-     * Store a binary blob associated with an L2 key and a name.
-     *
-     * @param l2Key The L2 key for this network.
-     * @param clientId The ID of the client.
-     * @param name The name of this data.
-     * @param data The data to store.
-     * @param listener A listener to inform of the completion of this call, or null if the client
-     *        is not interested in learning about success/failure.
-     * @return (through the listener) A status to indicate success or failure.
-     */
-    void storeBlob(String l2Key, String clientId, String name, in Blob data,
-            IOnStatusListener listener);
-
-    /**
-     * Returns the best L2 key associated with the attributes.
-     *
-     * This will find a record that would be in the same group as the passed attributes. This is
-     * useful to choose the key for storing a sample or private data when the L2 key is not known.
-     * If multiple records are group-close to these attributes, the closest match is returned.
-     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
-     * order) L2 key is returned.
-     * If no record matches these attributes, null is returned.
-     *
-     * @param attributes The attributes of the network to find.
-     * @param listener The listener that will be invoked to return the answer.
-     * @return (through the listener) The L2 key if one matched, or null.
-     */
-    void findL2Key(in NetworkAttributesParcelable attributes, IOnL2KeyResponseListener listener);
-
-    /**
-     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
-     * to the same L3 network. Group-closeness is used to determine this.
-     *
-     * @param l2Key1 The key for the first network.
-     * @param l2Key2 The key for the second network.
-     * @param listener The listener that will be invoked to return the answer.
-     * @return (through the listener) A SameL3NetworkResponse containing the answer and confidence.
-     */
-    void isSameNetwork(String l2Key1, String l2Key2, IOnSameL3NetworkResponseListener listener);
-
-    /**
-     * Retrieve the network attributes for a key.
-     * If no record is present for this key, this will return null attributes.
-     *
-     * @param l2Key The key of the network to query.
-     * @param listener The listener that will be invoked to return the answer.
-     * @return (through the listener) The network attributes and the L2 key associated with
-     *         the query.
-     */
-    void retrieveNetworkAttributes(String l2Key, IOnNetworkAttributesRetrievedListener listener);
-
-    /**
-     * Retrieve previously stored private data.
-     * If no data was stored for this L2 key and name this will return null.
-     *
-     * @param l2Key The L2 key.
-     * @param clientId The id of the client that stored this data.
-     * @param name The name of the data.
-     * @param listener The listener that will be invoked to return the answer.
-     * @return (through the listener) The private data (or null), with the L2 key
-     *         and the name of the data associated with the query.
-     */
-    void retrieveBlob(String l2Key, String clientId, String name,
-            IOnBlobRetrievedListener listener);
-
-    /**
-     * Delete all data because a factory reset operation is in progress.
-     */
-    void factoryReset();
-}
diff --git a/services/net/java/android/net/IIpMemoryStoreCallbacks.aidl b/services/net/java/android/net/IIpMemoryStoreCallbacks.aidl
deleted file mode 100644
index 53108db..0000000
--- a/services/net/java/android/net/IIpMemoryStoreCallbacks.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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.net;
-
-import android.net.IIpMemoryStore;
-
-/** {@hide} */
-oneway interface IIpMemoryStoreCallbacks {
-    void onIpMemoryStoreFetched(in IIpMemoryStore ipMemoryStore);
-}
diff --git a/services/net/java/android/net/INetworkMonitor.aidl b/services/net/java/android/net/INetworkMonitor.aidl
deleted file mode 100644
index 3fc81a3..0000000
--- a/services/net/java/android/net/INetworkMonitor.aidl
+++ /dev/null
@@ -1,68 +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 perNmissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
-import android.net.PrivateDnsConfigParcel;
-
-/** @hide */
-oneway interface INetworkMonitor {
-    // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED.
-    // The network should be used as a default internet connection.  It was found to be:
-    // 1. a functioning network providing internet access, or
-    // 2. a captive portal and the user decided to use it as is.
-    const int NETWORK_TEST_RESULT_VALID = 0;
-
-    // After a network has been tested this result can be sent with EVENT_NETWORK_TESTED.
-    // The network should not be used as a default internet connection.  It was found to be:
-    // 1. a captive portal and the user is prompted to sign-in, or
-    // 2. a captive portal and the user did not want to use it, or
-    // 3. a broken network (e.g. DNS failed, connect failed, HTTP request failed).
-    const int NETWORK_TEST_RESULT_INVALID = 1;
-
-    // After a network has been tested, this result can be sent with EVENT_NETWORK_TESTED.
-    // The network may be used as a default internet connection, but it was found to be a partial
-    // connectivity network which can get the pass result for http probe but get the failed result
-    // for https probe.
-    const int NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY = 2;
-
-    // Network validation flags indicate probe result and types. If no NETWORK_VALIDATION_RESULT_*
-    // are set, then it's equal to NETWORK_TEST_RESULT_INVALID. If NETWORK_VALIDATION_RESULT_VALID
-    // is set, then the network validates and equal to NETWORK_TEST_RESULT_VALID. If
-    // NETWORK_VALIDATION_RESULT_PARTIAL is set, then the network has partial connectivity which
-    // is equal to NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY. NETWORK_VALIDATION_PROBE_* is set
-    // when the specific probe result of the network is resolved.
-    const int NETWORK_VALIDATION_RESULT_VALID = 0x01;
-    const int NETWORK_VALIDATION_RESULT_PARTIAL = 0x02;
-    const int NETWORK_VALIDATION_PROBE_DNS = 0x04;
-    const int NETWORK_VALIDATION_PROBE_HTTP = 0x08;
-    const int NETWORK_VALIDATION_PROBE_HTTPS = 0x10;
-    const int NETWORK_VALIDATION_PROBE_FALLBACK = 0x20;
-    const int NETWORK_VALIDATION_PROBE_PRIVDNS = 0x40;
-
-    void start();
-    void launchCaptivePortalApp();
-    void notifyCaptivePortalAppFinished(int response);
-    void setAcceptPartialConnectivity();
-    void forceReevaluation(int uid);
-    void notifyPrivateDnsChanged(in PrivateDnsConfigParcel config);
-    void notifyDnsResponse(int returnCode);
-    void notifyNetworkConnected(in LinkProperties lp, in NetworkCapabilities nc);
-    void notifyNetworkDisconnected();
-    void notifyLinkPropertiesChanged(in LinkProperties lp);
-    void notifyNetworkCapabilitiesChanged(in NetworkCapabilities nc);
-}
diff --git a/services/net/java/android/net/INetworkMonitorCallbacks.aidl b/services/net/java/android/net/INetworkMonitorCallbacks.aidl
deleted file mode 100644
index 2c61511..0000000
--- a/services/net/java/android/net/INetworkMonitorCallbacks.aidl
+++ /dev/null
@@ -1,29 +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 android.net;
-
-import android.net.INetworkMonitor;
-import android.net.PrivateDnsConfigParcel;
-
-/** @hide */
-oneway interface INetworkMonitorCallbacks {
-    void onNetworkMonitorCreated(in INetworkMonitor networkMonitor);
-    void notifyNetworkTested(int testResult, @nullable String redirectUrl);
-    void notifyPrivateDnsConfigResolved(in PrivateDnsConfigParcel config);
-    void showProvisioningNotification(String action, String packageName);
-    void hideProvisioningNotification();
-}
\ No newline at end of file
diff --git a/services/net/java/android/net/INetworkStackConnector.aidl b/services/net/java/android/net/INetworkStackConnector.aidl
deleted file mode 100644
index 3751c36..0000000
--- a/services/net/java/android/net/INetworkStackConnector.aidl
+++ /dev/null
@@ -1,32 +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 perNmissions and
- * limitations under the License.
- */
-package android.net;
-
-import android.net.IIpMemoryStoreCallbacks;
-import android.net.INetworkMonitorCallbacks;
-import android.net.Network;
-import android.net.dhcp.DhcpServingParamsParcel;
-import android.net.dhcp.IDhcpServerCallbacks;
-import android.net.ip.IIpClientCallbacks;
-
-/** @hide */
-oneway interface INetworkStackConnector {
-    void makeDhcpServer(in String ifName, in DhcpServingParamsParcel params,
-        in IDhcpServerCallbacks cb);
-    void makeNetworkMonitor(in Network network, String name, in INetworkMonitorCallbacks cb);
-    void makeIpClient(in String ifName, in IIpClientCallbacks callbacks);
-    void fetchIpMemoryStore(in IIpMemoryStoreCallbacks cb);
-}
diff --git a/services/net/java/android/net/INetworkStackStatusCallback.aidl b/services/net/java/android/net/INetworkStackStatusCallback.aidl
deleted file mode 100644
index 51032d8..0000000
--- a/services/net/java/android/net/INetworkStackStatusCallback.aidl
+++ /dev/null
@@ -1,22 +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 android.net;
-
-/** @hide */
-oneway interface INetworkStackStatusCallback {
-    void onStatusAvailable(int statusCode);
-}
\ No newline at end of file
diff --git a/services/net/java/android/net/InitialConfigurationParcelable.aidl b/services/net/java/android/net/InitialConfigurationParcelable.aidl
deleted file mode 100644
index 3fa88c3..0000000
--- a/services/net/java/android/net/InitialConfigurationParcelable.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.net;
-
-import android.net.IpPrefix;
-import android.net.LinkAddress;
-
-parcelable InitialConfigurationParcelable {
-    LinkAddress[] ipAddresses;
-    IpPrefix[] directlyConnectedRoutes;
-    String[] dnsServers;
-    String gateway;
-}
\ No newline at end of file
diff --git a/services/net/java/android/net/IpMemoryStoreClient.java b/services/net/java/android/net/IpMemoryStoreClient.java
deleted file mode 100644
index 014b528..0000000
--- a/services/net/java/android/net/IpMemoryStoreClient.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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.net;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.NetworkAttributes;
-import android.net.ipmemorystore.OnBlobRetrievedListener;
-import android.net.ipmemorystore.OnL2KeyResponseListener;
-import android.net.ipmemorystore.OnNetworkAttributesRetrievedListener;
-import android.net.ipmemorystore.OnSameL3NetworkResponseListener;
-import android.net.ipmemorystore.OnStatusListener;
-import android.net.ipmemorystore.Status;
-import android.os.RemoteException;
-import android.util.Log;
-
-import java.util.concurrent.ExecutionException;
-import java.util.function.Consumer;
-
-/**
- * service used to communicate with the ip memory store service in network stack,
- * which is running in a separate module.
- * @hide
- */
-public abstract class IpMemoryStoreClient {
-    private static final String TAG = IpMemoryStoreClient.class.getSimpleName();
-    private final Context mContext;
-
-    public IpMemoryStoreClient(@NonNull final Context context) {
-        if (context == null) throw new IllegalArgumentException("missing context");
-        mContext = context;
-    }
-
-    protected abstract void runWhenServiceReady(Consumer<IIpMemoryStore> cb)
-            throws ExecutionException;
-
-    @FunctionalInterface
-    private interface ThrowingRunnable {
-        void run() throws RemoteException;
-    }
-
-    private void ignoringRemoteException(ThrowingRunnable r) {
-        ignoringRemoteException("Failed to execute remote procedure call", r);
-    }
-
-    private void ignoringRemoteException(String message, ThrowingRunnable r) {
-        try {
-            r.run();
-        } catch (RemoteException e) {
-            Log.e(TAG, message, e);
-        }
-    }
-
-    /**
-     * Store network attributes for a given L2 key.
-     * If L2Key is null, choose automatically from the attributes ; passing null is equivalent to
-     * calling findL2Key with the attributes and storing in the returned value.
-     *
-     * @param l2Key The L2 key for the L2 network. Clients that don't know or care about the L2
-     *              key and only care about grouping can pass a unique ID here like the ones
-     *              generated by {@code java.util.UUID.randomUUID()}, but keep in mind the low
-     *              relevance of such a network will lead to it being evicted soon if it's not
-     *              refreshed. Use findL2Key to try and find a similar L2Key to these attributes.
-     * @param attributes The attributes for this network.
-     * @param listener A listener that will be invoked to inform of the completion of this call,
-     *                 or null if the client is not interested in learning about success/failure.
-     * Through the listener, returns the L2 key. This is useful if the L2 key was not specified.
-     * If the call failed, the L2 key will be null.
-     */
-    public void storeNetworkAttributes(@NonNull final String l2Key,
-            @NonNull final NetworkAttributes attributes,
-            @Nullable final OnStatusListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.storeNetworkAttributes(l2Key, attributes.toParcelable(),
-                            OnStatusListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error storing network attributes",
-                    () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN)));
-        }
-    }
-
-    /**
-     * Store a binary blob associated with an L2 key and a name.
-     *
-     * @param l2Key The L2 key for this network.
-     * @param clientId The ID of the client.
-     * @param name The name of this data.
-     * @param data The data to store.
-     * @param listener A listener to inform of the completion of this call, or null if the client
-     *        is not interested in learning about success/failure.
-     * Through the listener, returns a status to indicate success or failure.
-     */
-    public void storeBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final Blob data,
-            @Nullable final OnStatusListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.storeBlob(l2Key, clientId, name, data,
-                            OnStatusListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error storing blob",
-                    () -> listener.onComplete(new Status(Status.ERROR_UNKNOWN)));
-        }
-    }
-
-    /**
-     * Returns the best L2 key associated with the attributes.
-     *
-     * This will find a record that would be in the same group as the passed attributes. This is
-     * useful to choose the key for storing a sample or private data when the L2 key is not known.
-     * If multiple records are group-close to these attributes, the closest match is returned.
-     * If multiple records have the same closeness, the one with the smaller (unicode codepoint
-     * order) L2 key is returned.
-     * If no record matches these attributes, null is returned.
-     *
-     * @param attributes The attributes of the network to find.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the L2 key if one matched, or null.
-     */
-    public void findL2Key(@NonNull final NetworkAttributes attributes,
-            @NonNull final OnL2KeyResponseListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.findL2Key(attributes.toParcelable(),
-                            OnL2KeyResponseListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error finding L2 Key",
-                    () -> listener.onL2KeyResponse(new Status(Status.ERROR_UNKNOWN), null));
-        }
-    }
-
-    /**
-     * Returns whether, to the best of the store's ability to tell, the two specified L2 keys point
-     * to the same L3 network. Group-closeness is used to determine this.
-     *
-     * @param l2Key1 The key for the first network.
-     * @param l2Key2 The key for the second network.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, a SameL3NetworkResponse containing the answer and confidence.
-     */
-    public void isSameNetwork(@NonNull final String l2Key1, @NonNull final String l2Key2,
-            @NonNull final OnSameL3NetworkResponseListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.isSameNetwork(l2Key1, l2Key2,
-                            OnSameL3NetworkResponseListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error checking for network sameness",
-                    () -> listener.onSameL3NetworkResponse(new Status(Status.ERROR_UNKNOWN), null));
-        }
-    }
-
-    /**
-     * Retrieve the network attributes for a key.
-     * If no record is present for this key, this will return null attributes.
-     *
-     * @param l2Key The key of the network to query.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the network attributes and the L2 key associated with
-     *         the query.
-     */
-    public void retrieveNetworkAttributes(@NonNull final String l2Key,
-            @NonNull final OnNetworkAttributesRetrievedListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.retrieveNetworkAttributes(l2Key,
-                            OnNetworkAttributesRetrievedListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error retrieving network attributes",
-                    () -> listener.onNetworkAttributesRetrieved(new Status(Status.ERROR_UNKNOWN),
-                            null, null));
-        }
-    }
-
-    /**
-     * Retrieve previously stored private data.
-     * If no data was stored for this L2 key and name this will return null.
-     *
-     * @param l2Key The L2 key.
-     * @param clientId The id of the client that stored this data.
-     * @param name The name of the data.
-     * @param listener The listener that will be invoked to return the answer.
-     * Through the listener, returns the private data (or null), with the L2 key
-     *         and the name of the data associated with the query.
-     */
-    public void retrieveBlob(@NonNull final String l2Key, @NonNull final String clientId,
-            @NonNull final String name, @NonNull final OnBlobRetrievedListener listener) {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.retrieveBlob(l2Key, clientId, name,
-                            OnBlobRetrievedListener.toAIDL(listener))));
-        } catch (ExecutionException m) {
-            ignoringRemoteException("Error retrieving blob",
-                    () -> listener.onBlobRetrieved(new Status(Status.ERROR_UNKNOWN),
-                            null, null, null));
-        }
-    }
-
-    /**
-     * Wipe the data in the database upon network factory reset.
-     */
-    public void factoryReset() {
-        try {
-            runWhenServiceReady(service -> ignoringRemoteException(
-                    () -> service.factoryReset()));
-        } catch (ExecutionException m) {
-            Log.e(TAG, "Error executing factory reset", m);
-        }
-    }
-}
diff --git a/services/net/java/android/net/PrivateDnsConfigParcel.aidl b/services/net/java/android/net/PrivateDnsConfigParcel.aidl
deleted file mode 100644
index b52fce6..0000000
--- a/services/net/java/android/net/PrivateDnsConfigParcel.aidl
+++ /dev/null
@@ -1,22 +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 android.net;
-
-parcelable PrivateDnsConfigParcel {
-    String hostname;
-    String[] ips;
-}
diff --git a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl b/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
deleted file mode 100644
index 99606fb..0000000
--- a/services/net/java/android/net/ProvisioningConfigurationParcelable.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-**
-** 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.net;
-
-import android.net.InitialConfigurationParcelable;
-import android.net.Network;
-import android.net.StaticIpConfiguration;
-import android.net.apf.ApfCapabilities;
-
-parcelable ProvisioningConfigurationParcelable {
-    boolean enableIPv4;
-    boolean enableIPv6;
-    boolean usingMultinetworkPolicyTracker;
-    boolean usingIpReachabilityMonitor;
-    int requestedPreDhcpActionMs;
-    InitialConfigurationParcelable initialConfig;
-    StaticIpConfiguration staticIpConfig;
-    ApfCapabilities apfCapabilities;
-    int provisioningTimeoutMs;
-    int ipv6AddrGenMode;
-    Network network;
-    String displayName;
-}
diff --git a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl b/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
deleted file mode 100644
index e25168d..0000000
--- a/services/net/java/android/net/TcpKeepalivePacketDataParcelable.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.net;
-
-parcelable TcpKeepalivePacketDataParcelable {
-    byte[] srcAddress;
-    int srcPort;
-    byte[] dstAddress;
-    int dstPort;
-    int seq;
-    int ack;
-    int rcvWnd;
-    int rcvWndScale;
-    int tos;
-    int ttl;
-}
diff --git a/services/net/java/android/net/dhcp/DhcpServingParamsParcel.aidl b/services/net/java/android/net/dhcp/DhcpServingParamsParcel.aidl
deleted file mode 100644
index 7b8b9ee..0000000
--- a/services/net/java/android/net/dhcp/DhcpServingParamsParcel.aidl
+++ /dev/null
@@ -1,30 +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 android.net.dhcp;
-
-parcelable DhcpServingParamsParcel {
-    int serverAddr;
-    int serverAddrPrefixLength;
-    int[] defaultRouters;
-    int[] dnsServers;
-    int[] excludedAddrs;
-    long dhcpLeaseTimeSecs;
-    int linkMtu;
-    boolean metered;
-}
-
diff --git a/services/net/java/android/net/dhcp/IDhcpServer.aidl b/services/net/java/android/net/dhcp/IDhcpServer.aidl
deleted file mode 100644
index 559433b..0000000
--- a/services/net/java/android/net/dhcp/IDhcpServer.aidl
+++ /dev/null
@@ -1,32 +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 perNmissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import android.net.INetworkStackStatusCallback;
-import android.net.dhcp.DhcpServingParamsParcel;
-
-/** @hide */
-oneway interface IDhcpServer {
-    const int STATUS_UNKNOWN = 0;
-    const int STATUS_SUCCESS = 1;
-    const int STATUS_INVALID_ARGUMENT = 2;
-    const int STATUS_UNKNOWN_ERROR = 3;
-
-    void start(in INetworkStackStatusCallback cb);
-    void updateParams(in DhcpServingParamsParcel params, in INetworkStackStatusCallback cb);
-    void stop(in INetworkStackStatusCallback cb);
-}
diff --git a/services/net/java/android/net/dhcp/IDhcpServerCallbacks.aidl b/services/net/java/android/net/dhcp/IDhcpServerCallbacks.aidl
deleted file mode 100644
index 7ab4dcd..0000000
--- a/services/net/java/android/net/dhcp/IDhcpServerCallbacks.aidl
+++ /dev/null
@@ -1,24 +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 perNmissions and
- * limitations under the License.
- */
-
-package android.net.dhcp;
-
-import android.net.dhcp.IDhcpServer;
-
-/** @hide */
-oneway interface IDhcpServerCallbacks {
-    void onDhcpServerCreated(int statusCode, in IDhcpServer server);
-}
diff --git a/services/net/java/android/net/ip/IIpClient.aidl b/services/net/java/android/net/ip/IIpClient.aidl
deleted file mode 100644
index 9989c52..0000000
--- a/services/net/java/android/net/ip/IIpClient.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * 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 perNmissions and
- * limitations under the License.
- */
-package android.net.ip;
-
-import android.net.ProxyInfo;
-import android.net.ProvisioningConfigurationParcelable;
-import android.net.NattKeepalivePacketDataParcelable;
-import android.net.TcpKeepalivePacketDataParcelable;
-
-/** @hide */
-oneway interface IIpClient {
-    void completedPreDhcpAction();
-    void confirmConfiguration();
-    void readPacketFilterComplete(in byte[] data);
-    void shutdown();
-    void startProvisioning(in ProvisioningConfigurationParcelable req);
-    void stop();
-    void setTcpBufferSizes(in String tcpBufferSizes);
-    void setHttpProxy(in ProxyInfo proxyInfo);
-    void setMulticastFilter(boolean enabled);
-    void addKeepalivePacketFilter(int slot, in TcpKeepalivePacketDataParcelable pkt);
-    void removeKeepalivePacketFilter(int slot);
-    void setL2KeyAndGroupHint(in String l2Key, in String groupHint);
-    void addNattKeepalivePacketFilter(int slot, in NattKeepalivePacketDataParcelable pkt);
-}
diff --git a/services/net/java/android/net/ip/IIpClientCallbacks.aidl b/services/net/java/android/net/ip/IIpClientCallbacks.aidl
deleted file mode 100644
index 3681416..0000000
--- a/services/net/java/android/net/ip/IIpClientCallbacks.aidl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * 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 perNmissions and
- * limitations under the License.
- */
-package android.net.ip;
-
-import android.net.LinkProperties;
-import android.net.ip.IIpClient;
-import android.net.DhcpResultsParcelable;
-
-/** @hide */
-oneway interface IIpClientCallbacks {
-    void onIpClientCreated(in IIpClient ipClient);
-
-    void onPreDhcpAction();
-    void onPostDhcpAction();
-
-    // This is purely advisory and not an indication of provisioning
-    // success or failure.  This is only here for callers that want to
-    // expose DHCPv4 results to other APIs (e.g., WifiInfo#setInetAddress).
-    // DHCPv4 or static IPv4 configuration failure or success can be
-    // determined by whether or not the passed-in DhcpResults object is
-    // null or not.
-    void onNewDhcpResults(in DhcpResultsParcelable dhcpResults);
-
-    void onProvisioningSuccess(in LinkProperties newLp);
-    void onProvisioningFailure(in LinkProperties newLp);
-
-    // Invoked on LinkProperties changes.
-    void onLinkPropertiesChange(in LinkProperties newLp);
-
-    // Called when the internal IpReachabilityMonitor (if enabled) has
-    // detected the loss of a critical number of required neighbors.
-    void onReachabilityLost(in String logMsg);
-
-    // Called when the IpClient state machine terminates.
-    void onQuit();
-
-    // Install an APF program to filter incoming packets.
-    void installPacketFilter(in byte[] filter);
-
-    // Asynchronously read back the APF program & data buffer from the wifi driver.
-    // Due to Wifi HAL limitations, the current implementation only supports dumping the entire
-    // buffer. In response to this request, the driver returns the data buffer asynchronously
-    // by sending an IpClient#EVENT_READ_PACKET_FILTER_COMPLETE message.
-    void startReadPacketFilter();
-
-    // If multicast filtering cannot be accomplished with APF, this function will be called to
-    // actuate multicast filtering using another means.
-    void setFallbackMulticastFilter(boolean enabled);
-
-    // Enabled/disable Neighbor Discover offload functionality. This is
-    // called, for example, whenever 464xlat is being started or stopped.
-    void setNeighborDiscoveryOffload(boolean enable);
-}
\ No newline at end of file
diff --git a/services/net/java/android/net/ipmemorystore/Blob.aidl b/services/net/java/android/net/ipmemorystore/Blob.aidl
deleted file mode 100644
index 9dbef11..0000000
--- a/services/net/java/android/net/ipmemorystore/Blob.aidl
+++ /dev/null
@@ -1,26 +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 android.net.ipmemorystore;
-
-/**
- * A blob of data opaque to the memory store. The client mutates this at its own risk,
- * and it is strongly suggested to never do it at all and treat this as immutable.
- * {@hide}
- */
-parcelable Blob {
-    byte[] data;
-}
diff --git a/services/net/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl b/services/net/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
deleted file mode 100644
index 4926feb..0000000
--- a/services/net/java/android/net/ipmemorystore/IOnBlobRetrievedListener.aidl
+++ /dev/null
@@ -1,30 +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 android.net.ipmemorystore;
-
-import android.net.ipmemorystore.Blob;
-import android.net.ipmemorystore.StatusParcelable;
-
-/** {@hide} */
-oneway interface IOnBlobRetrievedListener {
-    /**
-     * Private data was retrieved for the L2 key and name specified.
-     * Note this does not return the client ID, as clients are expected to only ever use one ID.
-     */
-     void onBlobRetrieved(in StatusParcelable status, in String l2Key, in String name,
-             in Blob data);
-}
diff --git a/services/net/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
deleted file mode 100644
index dea0cc4..0000000
--- a/services/net/java/android/net/ipmemorystore/IOnL2KeyResponseListener.aidl
+++ /dev/null
@@ -1,27 +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 android.net.ipmemorystore;
-
-import android.net.ipmemorystore.StatusParcelable;
-
-/** {@hide} */
-oneway interface IOnL2KeyResponseListener {
-    /**
-     * The operation completed with the specified L2 key.
-     */
-     void onL2KeyResponse(in StatusParcelable status, in String l2Key);
-}
diff --git a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl b/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
deleted file mode 100644
index 870e217..0000000
--- a/services/net/java/android/net/ipmemorystore/IOnNetworkAttributesRetrievedListener.aidl
+++ /dev/null
@@ -1,30 +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 android.net.ipmemorystore;
-
-import android.net.ipmemorystore.NetworkAttributesParcelable;
-import android.net.ipmemorystore.StatusParcelable;
-
-/** {@hide} */
-oneway interface IOnNetworkAttributesRetrievedListener {
-    /**
-     * Network attributes were fetched for the specified L2 key. While the L2 key will never
-     * be null, the attributes may be if no data is stored about this L2 key.
-     */
-     void onNetworkAttributesRetrieved(in StatusParcelable status, in String l2Key,
-             in NetworkAttributesParcelable attributes);
-}
diff --git a/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl b/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
deleted file mode 100644
index b8ccfb9..0000000
--- a/services/net/java/android/net/ipmemorystore/IOnSameL3NetworkResponseListener.aidl
+++ /dev/null
@@ -1,29 +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 android.net.ipmemorystore;
-
-import android.net.ipmemorystore.SameL3NetworkResponseParcelable;
-import android.net.ipmemorystore.StatusParcelable;
-
-/** {@hide} */
-oneway interface IOnSameL3NetworkResponseListener {
-    /**
-     * The memory store has come up with the answer to a query that was sent.
-     */
-     void onSameL3NetworkResponse(in StatusParcelable status,
-             in SameL3NetworkResponseParcelable response);
-}
diff --git a/services/net/java/android/net/ipmemorystore/IOnStatusListener.aidl b/services/net/java/android/net/ipmemorystore/IOnStatusListener.aidl
deleted file mode 100644
index 5d07504..0000000
--- a/services/net/java/android/net/ipmemorystore/IOnStatusListener.aidl
+++ /dev/null
@@ -1,27 +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 android.net.ipmemorystore;
-
-import android.net.ipmemorystore.StatusParcelable;
-
-/** {@hide} */
-oneway interface IOnStatusListener {
-    /**
-     * The operation has completed with the specified status.
-     */
-     void onComplete(in StatusParcelable status);
-}
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java b/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
deleted file mode 100644
index 818515a..0000000
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributes.java
+++ /dev/null
@@ -1,371 +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 android.net.ipmemorystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-import java.util.StringJoiner;
-
-/**
- * A POD object to represent attributes of a single L2 network entry.
- * @hide
- */
-public class NetworkAttributes {
-    private static final boolean DBG = true;
-
-    // Weight cutoff for grouping. To group, a similarity score is computed with the following
-    // algorithm : if both fields are non-null and equals() then add their assigned weight, else if
-    // both are null then add a portion of their assigned weight (see NULL_MATCH_WEIGHT),
-    // otherwise add nothing.
-    // As a guideline, this should be something like 60~75% of the total weights in this class. The
-    // design states "in essence a reader should imagine that if two important columns don't match,
-    // or one important and several unimportant columns don't match then the two records are
-    // considered a different group".
-    private static final float TOTAL_WEIGHT_CUTOFF = 520.0f;
-    // The portion of the weight that is earned when scoring group-sameness by having both columns
-    // being null. This is because some networks rightfully don't have some attributes (e.g. a
-    // V6-only network won't have an assigned V4 address) and both being null should count for
-    // something, but attributes may also be null just because data is unavailable.
-    private static final float NULL_MATCH_WEIGHT = 0.25f;
-
-    // The v4 address that was assigned to this device the last time it joined this network.
-    // This typically comes from DHCP but could be something else like static configuration.
-    // This does not apply to IPv6.
-    // TODO : add a list of v6 prefixes for the v6 case.
-    @Nullable
-    public final Inet4Address assignedV4Address;
-    private static final float WEIGHT_ASSIGNEDV4ADDR = 300.0f;
-
-    // The lease expiry timestamp of v4 address allocated from DHCP server, in milliseconds.
-    @Nullable
-    public final Long assignedV4AddressExpiry;
-    // lease expiry doesn't imply any correlation between "the same lease expiry value" and "the
-    // same L3 network".
-    private static final float WEIGHT_ASSIGNEDV4ADDREXPIRY = 0.0f;
-
-    // Optionally supplied by the client if it has an opinion on L3 network. For example, this
-    // could be a hash of the SSID + security type on WiFi.
-    @Nullable
-    public final String groupHint;
-    private static final float WEIGHT_GROUPHINT = 300.0f;
-
-    // The list of DNS server addresses.
-    @Nullable
-    public final List<InetAddress> dnsAddresses;
-    private static final float WEIGHT_DNSADDRESSES = 200.0f;
-
-    // The mtu on this network.
-    @Nullable
-    public final Integer mtu;
-    private static final float WEIGHT_MTU = 50.0f;
-
-    // The sum of all weights in this class. Tests ensure that this stays equal to the total of
-    // all weights.
-    /** @hide */
-    @VisibleForTesting
-    public static final float TOTAL_WEIGHT = WEIGHT_ASSIGNEDV4ADDR
-            + WEIGHT_ASSIGNEDV4ADDREXPIRY
-            + WEIGHT_GROUPHINT
-            + WEIGHT_DNSADDRESSES
-            + WEIGHT_MTU;
-
-    /** @hide */
-    @VisibleForTesting
-    public NetworkAttributes(
-            @Nullable final Inet4Address assignedV4Address,
-            @Nullable final Long assignedV4AddressExpiry,
-            @Nullable final String groupHint,
-            @Nullable final List<InetAddress> dnsAddresses,
-            @Nullable final Integer mtu) {
-        if (mtu != null && mtu < 0) throw new IllegalArgumentException("MTU can't be negative");
-        if (assignedV4AddressExpiry != null && assignedV4AddressExpiry <= 0) {
-            throw new IllegalArgumentException("lease expiry can't be negative or zero");
-        }
-        this.assignedV4Address = assignedV4Address;
-        this.assignedV4AddressExpiry = assignedV4AddressExpiry;
-        this.groupHint = groupHint;
-        this.dnsAddresses = null == dnsAddresses ? null :
-                Collections.unmodifiableList(new ArrayList<>(dnsAddresses));
-        this.mtu = mtu;
-    }
-
-    @VisibleForTesting
-    public NetworkAttributes(@NonNull final NetworkAttributesParcelable parcelable) {
-        // The call to the other constructor must be the first statement of this constructor,
-        // so everything has to be inline
-        this((Inet4Address) getByAddressOrNull(parcelable.assignedV4Address),
-                parcelable.assignedV4AddressExpiry > 0
-                        ? parcelable.assignedV4AddressExpiry : null,
-                parcelable.groupHint,
-                blobArrayToInetAddressList(parcelable.dnsAddresses),
-                parcelable.mtu >= 0 ? parcelable.mtu : null);
-    }
-
-    @Nullable
-    private static InetAddress getByAddressOrNull(@Nullable final byte[] address) {
-        if (null == address) return null;
-        try {
-            return InetAddress.getByAddress(address);
-        } catch (UnknownHostException e) {
-            return null;
-        }
-    }
-
-    @Nullable
-    private static List<InetAddress> blobArrayToInetAddressList(@Nullable final Blob[] blobs) {
-        if (null == blobs) return null;
-        final ArrayList<InetAddress> list = new ArrayList<>(blobs.length);
-        for (final Blob b : blobs) {
-            final InetAddress addr = getByAddressOrNull(b.data);
-            if (null != addr) list.add(addr);
-        }
-        return list;
-    }
-
-    @Nullable
-    private static Blob[] inetAddressListToBlobArray(@Nullable final List<InetAddress> addresses) {
-        if (null == addresses) return null;
-        final ArrayList<Blob> blobs = new ArrayList<>();
-        for (int i = 0; i < addresses.size(); ++i) {
-            final InetAddress addr = addresses.get(i);
-            if (null == addr) continue;
-            final Blob b = new Blob();
-            b.data = addr.getAddress();
-            blobs.add(b);
-        }
-        return blobs.toArray(new Blob[0]);
-    }
-
-    /** Converts this NetworkAttributes to a parcelable object */
-    @NonNull
-    public NetworkAttributesParcelable toParcelable() {
-        final NetworkAttributesParcelable parcelable = new NetworkAttributesParcelable();
-        parcelable.assignedV4Address =
-                (null == assignedV4Address) ? null : assignedV4Address.getAddress();
-        parcelable.assignedV4AddressExpiry =
-                (null == assignedV4AddressExpiry) ? 0 : assignedV4AddressExpiry;
-        parcelable.groupHint = groupHint;
-        parcelable.dnsAddresses = inetAddressListToBlobArray(dnsAddresses);
-        parcelable.mtu = (null == mtu) ? -1 : mtu;
-        return parcelable;
-    }
-
-    private float samenessContribution(final float weight,
-            @Nullable final Object o1, @Nullable final Object o2) {
-        if (null == o1) {
-            return (null == o2) ? weight * NULL_MATCH_WEIGHT : 0f;
-        }
-        return Objects.equals(o1, o2) ? weight : 0f;
-    }
-
-    /** @hide */
-    public float getNetworkGroupSamenessConfidence(@NonNull final NetworkAttributes o) {
-        final float samenessScore =
-                samenessContribution(WEIGHT_ASSIGNEDV4ADDR, assignedV4Address, o.assignedV4Address)
-                + samenessContribution(WEIGHT_ASSIGNEDV4ADDREXPIRY, assignedV4AddressExpiry,
-                      o.assignedV4AddressExpiry)
-                + samenessContribution(WEIGHT_GROUPHINT, groupHint, o.groupHint)
-                + samenessContribution(WEIGHT_DNSADDRESSES, dnsAddresses, o.dnsAddresses)
-                + samenessContribution(WEIGHT_MTU, mtu, o.mtu);
-        // The minimum is 0, the max is TOTAL_WEIGHT and should be represented by 1.0, and
-        // TOTAL_WEIGHT_CUTOFF should represent 0.5, but there is no requirement that
-        // TOTAL_WEIGHT_CUTOFF would be half of TOTAL_WEIGHT (indeed, it should not be).
-        // So scale scores under the cutoff between 0 and 0.5, and the scores over the cutoff
-        // between 0.5 and 1.0.
-        if (samenessScore < TOTAL_WEIGHT_CUTOFF) {
-            return samenessScore / (TOTAL_WEIGHT_CUTOFF * 2);
-        } else {
-            return (samenessScore - TOTAL_WEIGHT_CUTOFF) / (TOTAL_WEIGHT - TOTAL_WEIGHT_CUTOFF) / 2
-                    + 0.5f;
-        }
-    }
-
-    /** @hide */
-    public static class Builder {
-        @Nullable
-        private Inet4Address mAssignedAddress;
-        @Nullable
-        private Long mAssignedAddressExpiry;
-        @Nullable
-        private String mGroupHint;
-        @Nullable
-        private List<InetAddress> mDnsAddresses;
-        @Nullable
-        private Integer mMtu;
-
-        /**
-         * Set the assigned address.
-         * @param assignedV4Address The assigned address.
-         * @return This builder.
-         */
-        public Builder setAssignedV4Address(@Nullable final Inet4Address assignedV4Address) {
-            mAssignedAddress = assignedV4Address;
-            return this;
-        }
-
-        /**
-         * Set the lease expiry timestamp of assigned v4 address. Long.MAX_VALUE is used
-         * to represent "infinite lease".
-         *
-         * @param assignedV4AddressExpiry The lease expiry timestamp of assigned v4 address.
-         * @return This builder.
-         */
-        public Builder setAssignedV4AddressExpiry(
-                @Nullable final Long assignedV4AddressExpiry) {
-            if (null != assignedV4AddressExpiry && assignedV4AddressExpiry <= 0) {
-                throw new IllegalArgumentException("lease expiry can't be negative or zero");
-            }
-            mAssignedAddressExpiry = assignedV4AddressExpiry;
-            return this;
-        }
-
-        /**
-         * Set the group hint.
-         * @param groupHint The group hint.
-         * @return This builder.
-         */
-        public Builder setGroupHint(@Nullable final String groupHint) {
-            mGroupHint = groupHint;
-            return this;
-        }
-
-        /**
-         * Set the DNS addresses.
-         * @param dnsAddresses The DNS addresses.
-         * @return This builder.
-         */
-        public Builder setDnsAddresses(@Nullable final List<InetAddress> dnsAddresses) {
-            if (DBG && null != dnsAddresses) {
-                // Parceling code crashes if one of the addresses is null, therefore validate
-                // them when running in debug.
-                for (final InetAddress address : dnsAddresses) {
-                    if (null == address) throw new IllegalArgumentException("Null DNS address");
-                }
-            }
-            this.mDnsAddresses = dnsAddresses;
-            return this;
-        }
-
-        /**
-         * Set the MTU.
-         * @param mtu The MTU.
-         * @return This builder.
-         */
-        public Builder setMtu(@Nullable final Integer mtu) {
-            if (null != mtu && mtu < 0) throw new IllegalArgumentException("MTU can't be negative");
-            mMtu = mtu;
-            return this;
-        }
-
-        /**
-         * Return the built NetworkAttributes object.
-         * @return The built NetworkAttributes object.
-         */
-        public NetworkAttributes build() {
-            return new NetworkAttributes(mAssignedAddress, mAssignedAddressExpiry,
-                  mGroupHint, mDnsAddresses, mMtu);
-        }
-    }
-
-    /** @hide */
-    public boolean isEmpty() {
-        return (null == assignedV4Address) && (null == assignedV4AddressExpiry)
-                && (null == groupHint) && (null == dnsAddresses) && (null == mtu);
-    }
-
-    @Override
-    public boolean equals(@Nullable final Object o) {
-        if (!(o instanceof NetworkAttributes)) return false;
-        final NetworkAttributes other = (NetworkAttributes) o;
-        return Objects.equals(assignedV4Address, other.assignedV4Address)
-                && Objects.equals(assignedV4AddressExpiry, other.assignedV4AddressExpiry)
-                && Objects.equals(groupHint, other.groupHint)
-                && Objects.equals(dnsAddresses, other.dnsAddresses)
-                && Objects.equals(mtu, other.mtu);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(assignedV4Address, assignedV4AddressExpiry,
-                groupHint, dnsAddresses, mtu);
-    }
-
-    /** Pretty print */
-    @Override
-    public String toString() {
-        final StringJoiner resultJoiner = new StringJoiner(" ", "{", "}");
-        final ArrayList<String> nullFields = new ArrayList<>();
-
-        if (null != assignedV4Address) {
-            resultJoiner.add("assignedV4Addr :");
-            resultJoiner.add(assignedV4Address.toString());
-        } else {
-            nullFields.add("assignedV4Addr");
-        }
-
-        if (null != assignedV4AddressExpiry) {
-            resultJoiner.add("assignedV4AddressExpiry :");
-            resultJoiner.add(assignedV4AddressExpiry.toString());
-        } else {
-            nullFields.add("assignedV4AddressExpiry");
-        }
-
-        if (null != groupHint) {
-            resultJoiner.add("groupHint :");
-            resultJoiner.add(groupHint);
-        } else {
-            nullFields.add("groupHint");
-        }
-
-        if (null != dnsAddresses) {
-            resultJoiner.add("dnsAddr : [");
-            for (final InetAddress addr : dnsAddresses) {
-                resultJoiner.add(addr.getHostAddress());
-            }
-            resultJoiner.add("]");
-        } else {
-            nullFields.add("dnsAddr");
-        }
-
-        if (null != mtu) {
-            resultJoiner.add("mtu :");
-            resultJoiner.add(mtu.toString());
-        } else {
-            nullFields.add("mtu");
-        }
-
-        if (!nullFields.isEmpty()) {
-            resultJoiner.add("; Null fields : [");
-            for (final String field : nullFields) {
-                resultJoiner.add(field);
-            }
-            resultJoiner.add("]");
-        }
-
-        return resultJoiner.toString();
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl b/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
deleted file mode 100644
index 997eb2b..0000000
--- a/services/net/java/android/net/ipmemorystore/NetworkAttributesParcelable.aidl
+++ /dev/null
@@ -1,37 +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 android.net.ipmemorystore;
-
-// Blob[] is used to represent an array of byte[], as structured AIDL does not support arrays
-// of arrays.
-import android.net.ipmemorystore.Blob;
-
-/**
- * An object to represent attributes of a single L2 network entry.
- * See NetworkAttributes.java for a description of each field. The types used in this class
- * are structured parcelable types instead of the richer types of the NetworkAttributes object,
- * but they have the same purpose. The NetworkAttributes.java file also contains the code
- * to convert the richer types to the parcelable types and back.
- * @hide
- */
-parcelable NetworkAttributesParcelable {
-    byte[] assignedV4Address;
-    long assignedV4AddressExpiry;
-    String groupHint;
-    Blob[] dnsAddresses;
-    int mtu;
-}
diff --git a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
deleted file mode 100644
index a17483a..0000000
--- a/services/net/java/android/net/ipmemorystore/OnBlobRetrievedListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.net.ipmemorystore;
-
-import android.annotation.NonNull;
-
-/**
- * A listener for the IpMemoryStore to return a blob.
- * @hide
- */
-public interface OnBlobRetrievedListener {
-    /**
-     * The memory store has come up with the answer to a query that was sent.
-     */
-    void onBlobRetrieved(Status status, String l2Key, String name, Blob blob);
-
-    /** Converts this OnBlobRetrievedListener to a parcelable object */
-    @NonNull
-    static IOnBlobRetrievedListener toAIDL(@NonNull final OnBlobRetrievedListener listener) {
-        return new IOnBlobRetrievedListener.Stub() {
-            @Override
-            public void onBlobRetrieved(final StatusParcelable statusParcelable, final String l2Key,
-                    final String name, final Blob blob) {
-                // NonNull, but still don't crash the system server if null
-                if (null != listener) {
-                    listener.onBlobRetrieved(new Status(statusParcelable), l2Key, name, blob);
-                }
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java b/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
deleted file mode 100644
index e608aec..0000000
--- a/services/net/java/android/net/ipmemorystore/OnL2KeyResponseListener.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.net.ipmemorystore;
-
-import android.annotation.NonNull;
-
-/**
- * A listener for the IpMemoryStore to return a L2 key.
- * @hide
- */
-public interface OnL2KeyResponseListener {
-    /**
-     * The operation has completed with the specified status.
-     */
-    void onL2KeyResponse(Status status, String l2Key);
-
-    /** Converts this OnL2KeyResponseListener to a parcelable object */
-    @NonNull
-    static IOnL2KeyResponseListener toAIDL(@NonNull final OnL2KeyResponseListener listener) {
-        return new IOnL2KeyResponseListener.Stub() {
-            @Override
-            public void onL2KeyResponse(final StatusParcelable statusParcelable,
-                    final String l2Key) {
-                // NonNull, but still don't crash the system server if null
-                if (null != listener) {
-                    listener.onL2KeyResponse(new Status(statusParcelable), l2Key);
-                }
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java b/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
deleted file mode 100644
index 395ad98..0000000
--- a/services/net/java/android/net/ipmemorystore/OnNetworkAttributesRetrievedListener.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.net.ipmemorystore;
-
-import android.annotation.NonNull;
-
-/**
- * A listener for the IpMemoryStore to return network attributes.
- * @hide
- */
-public interface OnNetworkAttributesRetrievedListener {
-    /**
-     * The memory store has come up with the answer to a query that was sent.
-     */
-    void onNetworkAttributesRetrieved(Status status, String l2Key, NetworkAttributes attributes);
-
-    /** Converts this OnNetworkAttributesRetrievedListener to a parcelable object */
-    @NonNull
-    static IOnNetworkAttributesRetrievedListener toAIDL(
-            @NonNull final OnNetworkAttributesRetrievedListener listener) {
-        return new IOnNetworkAttributesRetrievedListener.Stub() {
-            @Override
-            public void onNetworkAttributesRetrieved(final StatusParcelable statusParcelable,
-                    final String l2Key,
-                    final NetworkAttributesParcelable networkAttributesParcelable) {
-                // NonNull, but still don't crash the system server if null
-                if (null != listener) {
-                    listener.onNetworkAttributesRetrieved(
-                            new Status(statusParcelable), l2Key, null == networkAttributesParcelable
-                                ? null : new NetworkAttributes(networkAttributesParcelable));
-                }
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java b/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
deleted file mode 100644
index 67f8da8..0000000
--- a/services/net/java/android/net/ipmemorystore/OnSameL3NetworkResponseListener.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.net.ipmemorystore;
-
-import android.annotation.NonNull;
-
-/**
- * A listener for the IpMemoryStore to return a response about network sameness.
- * @hide
- */
-public interface OnSameL3NetworkResponseListener {
-    /**
-     * The memory store has come up with the answer to a query that was sent.
-     */
-    void onSameL3NetworkResponse(Status status, SameL3NetworkResponse response);
-
-    /** Converts this OnSameL3NetworkResponseListener to a parcelable object */
-    @NonNull
-    static IOnSameL3NetworkResponseListener toAIDL(
-            @NonNull final OnSameL3NetworkResponseListener listener) {
-        return new IOnSameL3NetworkResponseListener.Stub() {
-            @Override
-            public void onSameL3NetworkResponse(final StatusParcelable statusParcelable,
-                    final SameL3NetworkResponseParcelable sameL3NetworkResponseParcelable) {
-                // NonNull, but still don't crash the system server if null
-                if (null != listener) {
-                    listener.onSameL3NetworkResponse(
-                            new Status(statusParcelable),
-                            new SameL3NetworkResponse(sameL3NetworkResponseParcelable));
-                }
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/OnStatusListener.java b/services/net/java/android/net/ipmemorystore/OnStatusListener.java
deleted file mode 100644
index 4262efd..0000000
--- a/services/net/java/android/net/ipmemorystore/OnStatusListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.net.ipmemorystore;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * A listener for the IpMemoryStore to return a status to a client.
- * @hide
- */
-public interface OnStatusListener {
-    /**
-     * The operation has completed with the specified status.
-     */
-    void onComplete(Status status);
-
-    /** Converts this OnStatusListener to a parcelable object */
-    @NonNull
-    static IOnStatusListener toAIDL(@Nullable final OnStatusListener listener) {
-        return new IOnStatusListener.Stub() {
-            @Override
-            public void onComplete(final StatusParcelable statusParcelable) {
-                if (null != listener) {
-                    listener.onComplete(new Status(statusParcelable));
-                }
-            }
-
-            @Override
-            public int getInterfaceVersion() {
-                return this.VERSION;
-            }
-        };
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/SameL3NetworkResponse.java b/services/net/java/android/net/ipmemorystore/SameL3NetworkResponse.java
deleted file mode 100644
index 291aca8..0000000
--- a/services/net/java/android/net/ipmemorystore/SameL3NetworkResponse.java
+++ /dev/null
@@ -1,147 +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 android.net.ipmemorystore;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * An object representing the answer to a query whether two given L2 networks represent the
- * same L3 network. Parcels as a SameL3NetworkResponseParceled object.
- * @hide
- */
-public class SameL3NetworkResponse {
-    @IntDef(prefix = "NETWORK_",
-            value = {NETWORK_SAME, NETWORK_DIFFERENT, NETWORK_NEVER_CONNECTED})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NetworkSameness {}
-
-    /**
-     * Both L2 networks represent the same L3 network.
-     */
-    public static final int NETWORK_SAME = 1;
-
-    /**
-     * The two L2 networks represent a different L3 network.
-     */
-    public static final int NETWORK_DIFFERENT = 2;
-
-    /**
-     * The device has never connected to at least one of these two L2 networks, or data
-     * has been wiped. Therefore the device has never seen the L3 network behind at least
-     * one of these two L2 networks, and can't evaluate whether it's the same as the other.
-     */
-    public static final int NETWORK_NEVER_CONNECTED = 3;
-
-    /**
-     * The first L2 key specified in the query.
-     */
-    @NonNull
-    public final String l2Key1;
-
-    /**
-     * The second L2 key specified in the query.
-     */
-    @NonNull
-    public final String l2Key2;
-
-    /**
-     * A confidence value indicating whether the two L2 networks represent the same L3 network.
-     *
-     * If both L2 networks were known, this value will be between 0.0 and 1.0, with 0.0
-     * representing complete confidence that the given L2 networks represent a different
-     * L3 network, and 1.0 representing complete confidence that the given L2 networks
-     * represent the same L3 network.
-     * If at least one of the L2 networks was not known, this value will be outside of the
-     * 0.0~1.0 range.
-     *
-     * Most apps should not be interested in this, and are encouraged to use the collapsing
-     * {@link #getNetworkSameness()} function below.
-     */
-    public final float confidence;
-
-    /**
-     * @return whether the two L2 networks represent the same L3 network. Either
-     *     {@code NETWORK_SAME}, {@code NETWORK_DIFFERENT} or {@code NETWORK_NEVER_CONNECTED}.
-     */
-    @NetworkSameness
-    public final int getNetworkSameness() {
-        if (confidence > 1.0 || confidence < 0.0) return NETWORK_NEVER_CONNECTED;
-        return confidence > 0.5 ? NETWORK_SAME : NETWORK_DIFFERENT;
-    }
-
-    /** @hide */
-    public SameL3NetworkResponse(@NonNull final String l2Key1, @NonNull final String l2Key2,
-            final float confidence) {
-        this.l2Key1 = l2Key1;
-        this.l2Key2 = l2Key2;
-        this.confidence = confidence;
-    }
-
-    /** Builds a SameL3NetworkResponse from a parcelable object */
-    @VisibleForTesting
-    public SameL3NetworkResponse(@NonNull final SameL3NetworkResponseParcelable parceled) {
-        this(parceled.l2Key1, parceled.l2Key2, parceled.confidence);
-    }
-
-    /** Converts this SameL3NetworkResponse to a parcelable object */
-    @NonNull
-    public SameL3NetworkResponseParcelable toParcelable() {
-        final SameL3NetworkResponseParcelable parcelable = new SameL3NetworkResponseParcelable();
-        parcelable.l2Key1 = l2Key1;
-        parcelable.l2Key2 = l2Key2;
-        parcelable.confidence = confidence;
-        return parcelable;
-    }
-
-    // Note key1 and key2 have to match each other for this to return true. If
-    // key1 matches o.key2 and the other way around this returns false.
-    @Override
-    public boolean equals(@Nullable final Object o) {
-        if (!(o instanceof SameL3NetworkResponse)) return false;
-        final SameL3NetworkResponse other = (SameL3NetworkResponse) o;
-        return l2Key1.equals(other.l2Key1) && l2Key2.equals(other.l2Key2)
-                && confidence == other.confidence;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(l2Key1, l2Key2, confidence);
-    }
-
-    @Override
-    /** Pretty print */
-    public String toString() {
-        switch (getNetworkSameness()) {
-            case NETWORK_SAME:
-                return "\"" + l2Key1 + "\" same L3 network as \"" + l2Key2 + "\"";
-            case NETWORK_DIFFERENT:
-                return "\"" + l2Key1 + "\" different L3 network from \"" + l2Key2 + "\"";
-            case NETWORK_NEVER_CONNECTED:
-                return "\"" + l2Key1 + "\" can't be tested against \"" + l2Key2 + "\"";
-            default:
-                return "Buggy sameness value ? \"" + l2Key1 + "\", \"" + l2Key2 + "\"";
-        }
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl b/services/net/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
deleted file mode 100644
index 7196699..0000000
--- a/services/net/java/android/net/ipmemorystore/SameL3NetworkResponseParcelable.aidl
+++ /dev/null
@@ -1,24 +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 android.net.ipmemorystore;
-
-/** {@hide} */
-parcelable SameL3NetworkResponseParcelable {
-    String l2Key1;
-    String l2Key2;
-    float confidence;
-}
diff --git a/services/net/java/android/net/ipmemorystore/Status.java b/services/net/java/android/net/ipmemorystore/Status.java
deleted file mode 100644
index 13242c0..0000000
--- a/services/net/java/android/net/ipmemorystore/Status.java
+++ /dev/null
@@ -1,74 +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 android.net.ipmemorystore;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * A parcelable status representing the result of an operation.
- * Parcels as StatusParceled.
- * @hide
- */
-public class Status {
-    public static final int SUCCESS = 0;
-
-    public static final int ERROR_GENERIC = -1;
-    public static final int ERROR_ILLEGAL_ARGUMENT = -2;
-    public static final int ERROR_DATABASE_CANNOT_BE_OPENED = -3;
-    public static final int ERROR_STORAGE = -4;
-    public static final int ERROR_UNKNOWN = -5;
-
-    public final int resultCode;
-
-    public Status(final int resultCode) {
-        this.resultCode = resultCode;
-    }
-
-    @VisibleForTesting
-    public Status(@NonNull final StatusParcelable parcelable) {
-        this(parcelable.resultCode);
-    }
-
-    /** Converts this Status to a parcelable object */
-    @NonNull
-    public StatusParcelable toParcelable() {
-        final StatusParcelable parcelable = new StatusParcelable();
-        parcelable.resultCode = resultCode;
-        return parcelable;
-    }
-
-    public boolean isSuccess() {
-        return SUCCESS == resultCode;
-    }
-
-    /** Pretty print */
-    @Override
-    public String toString() {
-        switch (resultCode) {
-            case SUCCESS: return "SUCCESS";
-            case ERROR_GENERIC: return "GENERIC ERROR";
-            case ERROR_ILLEGAL_ARGUMENT: return "ILLEGAL ARGUMENT";
-            case ERROR_DATABASE_CANNOT_BE_OPENED: return "DATABASE CANNOT BE OPENED";
-            // "DB storage error" is not very helpful but SQLite does not provide specific error
-            // codes upon store failure. Thus this indicates SQLite returned some error upon store
-            case ERROR_STORAGE: return "DATABASE STORAGE ERROR";
-            default: return "Unknown value ?!";
-        }
-    }
-}
diff --git a/services/net/java/android/net/ipmemorystore/StatusParcelable.aidl b/services/net/java/android/net/ipmemorystore/StatusParcelable.aidl
deleted file mode 100644
index fb36ef4..0000000
--- a/services/net/java/android/net/ipmemorystore/StatusParcelable.aidl
+++ /dev/null
@@ -1,22 +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 android.net.ipmemorystore;
-
-/** {@hide} */
-parcelable StatusParcelable {
-  int resultCode;
-}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 95ec3d9..fc7cfec 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -115,7 +115,7 @@
 
     @Test
     public void testPartitions() throws Exception {
-        String[] partitions = { "system", "vendor", "odm", "oem", "product", "product_services" };
+        String[] partitions = { "system", "vendor", "odm", "oem", "product", "system_ext" };
         String[] appdir = { "app", "priv-app" };
         for (int i = 0; i < partitions.length; i++) {
             for (int j = 0; j < appdir.length; j++) {
@@ -128,7 +128,7 @@
                 Assert.assertEquals(i == 1 || i == 2, PackageManagerService.locationIsVendor(path));
                 Assert.assertEquals(i == 3, PackageManagerService.locationIsOem(path));
                 Assert.assertEquals(i == 4, PackageManagerService.locationIsProduct(path));
-                Assert.assertEquals(i == 5, PackageManagerService.locationIsProductServices(path));
+                Assert.assertEquals(i == 5, PackageManagerService.locationIsSystemExt(path));
             }
         }
     }
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index 4f6524e..c380d29 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -25,6 +25,7 @@
         "slicer",
     ],
     static_libs: [
+        "libcutils",
         "libtinyxml2",
         "liblog",
         "libutils",
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 499c42e..48b44d0 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -161,7 +161,7 @@
 
   MethodBuilder method{cbuilder.CreateMethod("foo", Prototype{TypeDescriptor::Int(), string_type})};
 
-  Value result = method.MakeRegister();
+  LiveRegister result = method.AllocRegister();
 
   MethodDeclData string_length =
       dex_file.GetOrDeclareMethod(string_type, "length", Prototype{TypeDescriptor::Int()});
@@ -314,7 +314,7 @@
   CHECK(decl_->prototype != nullptr);
   size_t const num_args =
       decl_->prototype->param_types != nullptr ? decl_->prototype->param_types->types.size() : 0;
-  code->registers = num_registers_ + num_args + kMaxScratchRegisters;
+  code->registers = NumRegisters() + num_args + kMaxScratchRegisters;
   code->ins_count = num_args;
   EncodeInstructions();
   code->instructions = slicer::ArrayView<const ::dex::u2>(buffer_.data(), buffer_.size());
@@ -327,7 +327,20 @@
   return method;
 }
 
-Value MethodBuilder::MakeRegister() { return Value::Local(num_registers_++); }
+LiveRegister MethodBuilder::AllocRegister() {
+  // Find a free register
+  for (size_t i = 0; i < register_liveness_.size(); ++i) {
+    if (!register_liveness_[i]) {
+      register_liveness_[i] = true;
+      return LiveRegister{&register_liveness_, i};
+    }
+  }
+
+  // If we get here, all the registers are in use, so we have to allocate a new
+  // one.
+  register_liveness_.push_back(true);
+  return LiveRegister{&register_liveness_, register_liveness_.size() - 1};
+}
 
 Value MethodBuilder::MakeLabel() {
   labels_.push_back({});
@@ -600,7 +613,7 @@
   if (value.is_register()) {
     return value.value();
   } else if (value.is_parameter()) {
-    return value.value() + num_registers_ + kMaxScratchRegisters;
+    return value.value() + NumRegisters() + kMaxScratchRegisters;
   }
   CHECK(false && "Must be either a parameter or a register");
   return 0;
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index 292d659..3924e77 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -140,6 +140,29 @@
   constexpr Value(size_t value, Kind kind) : value_{value}, kind_{kind} {}
 };
 
+// Represents an allocated register returned by MethodBuilder::AllocRegister
+class LiveRegister {
+  friend class MethodBuilder;
+
+ public:
+  LiveRegister(LiveRegister&& other) : liveness_{other.liveness_}, index_{other.index_} {
+    other.index_ = {};
+  };
+  ~LiveRegister() {
+    if (index_.has_value()) {
+      (*liveness_)[*index_] = false;
+    }
+  };
+
+  operator const Value() const { return Value::Local(*index_); }
+
+ private:
+  LiveRegister(std::vector<bool>* liveness, size_t index) : liveness_{liveness}, index_{index} {}
+
+  std::vector<bool>* const liveness_;
+  std::optional<size_t> index_;
+};
+
 // A virtual instruction. We convert these to real instructions in MethodBuilder::Encode.
 // Virtual instructions are needed to keep track of information that is not known until all of the
 // code is generated. This information includes things like how many local registers are created and
@@ -178,7 +201,8 @@
   }
   // For most instructions, which take some number of arguments and have an optional return value.
   template <typename... T>
-  static inline Instruction OpWithArgs(Op opcode, std::optional<const Value> dest, T... args) {
+  static inline Instruction OpWithArgs(Op opcode, std::optional<const Value> dest,
+                                       const T&... args) {
     return Instruction{opcode, /*index_argument=*/0, /*result_is_object=*/false, dest, args...};
   }
 
@@ -199,14 +223,14 @@
   template <typename... T>
   static inline Instruction InvokeVirtualObject(size_t index_argument,
                                                 std::optional<const Value> dest, Value this_arg,
-                                                T... args) {
+                                                const T&... args) {
     return Instruction{
         Op::kInvokeVirtual, index_argument, /*result_is_object=*/true, dest, this_arg, args...};
   }
   // For direct calls (basically, constructors).
   template <typename... T>
   static inline Instruction InvokeDirect(size_t index_argument, std::optional<const Value> dest,
-                                         Value this_arg, T... args) {
+                                         Value this_arg, const T&... args) {
     return Instruction{
         Op::kInvokeDirect, index_argument, /*result_is_object=*/false, dest, this_arg, args...};
   }
@@ -234,7 +258,7 @@
   // For static calls.
   template <typename... T>
   static inline Instruction InvokeInterface(size_t index_argument, std::optional<const Value> dest,
-                                            T... args) {
+                                            const T&... args) {
     return Instruction{
         Op::kInvokeInterface, index_argument, /*result_is_object=*/false, dest, args...};
   }
@@ -277,7 +301,7 @@
 
   template <typename... T>
   inline Instruction(Op opcode, size_t index_argument, bool result_is_object,
-                               std::optional<const Value> dest, T... args)
+                     std::optional<const Value> dest, const T&... args)
       : opcode_{opcode},
         index_argument_{index_argument},
         result_is_object_{result_is_object},
@@ -309,10 +333,8 @@
   // Encode the method into DEX format.
   ir::EncodedMethod* Encode();
 
-  // Create a new register to be used to storing values. Note that these are not SSA registers, like
-  // might be expected in similar code generators. This does no liveness tracking or anything, so
-  // it's up to the caller to reuse registers as appropriate.
-  Value MakeRegister();
+  // Create a new register to be used to storing values.
+  LiveRegister AllocRegister();
 
   Value MakeLabel();
 
@@ -329,7 +351,7 @@
   void BuildConst4(Value target, int value);
   void BuildConstString(Value target, const std::string& value);
   template <typename... T>
-  void BuildNew(Value target, TypeDescriptor type, Prototype constructor, T... args);
+  void BuildNew(Value target, TypeDescriptor type, Prototype constructor, const T&... args);
 
   // TODO: add builders for more instructions
 
@@ -427,7 +449,7 @@
     static_assert(num_regs <= kMaxScratchRegisters);
     std::array<Value, num_regs> regs;
     for (size_t i = 0; i < num_regs; ++i) {
-      regs[i] = std::move(Value::Local(num_registers_ + i));
+      regs[i] = std::move(Value::Local(NumRegisters() + i));
     }
     return regs;
   }
@@ -457,8 +479,9 @@
   // around to make legal DEX code.
   static constexpr size_t kMaxScratchRegisters = 5;
 
-  // How many registers we've allocated
-  size_t num_registers_{0};
+  size_t NumRegisters() const {
+    return register_liveness_.size();
+  }
 
   // Stores information needed to back-patch a label once it is bound. We need to know the start of
   // the instruction that refers to the label, and the offset to where the actual label value should
@@ -478,6 +501,8 @@
   // During encoding, keep track of the largest number of arguments needed, so we can use it for our
   // outs count
   size_t max_args_{0};
+
+  std::vector<bool> register_liveness_;
 };
 
 // A helper to build class definitions.
@@ -576,7 +601,8 @@
 };
 
 template <typename... T>
-void MethodBuilder::BuildNew(Value target, TypeDescriptor type, Prototype constructor, T... args) {
+void MethodBuilder::BuildNew(Value target, TypeDescriptor type, Prototype constructor,
+                             const T&... args) {
   MethodDeclData constructor_data{dex_->GetOrDeclareMethod(type, "<init>", constructor)};
   // allocate the object
   ir::Type* type_def = dex_->GetOrAddType(type.descriptor());
diff --git a/startop/view_compiler/dex_layout_compiler.cc b/startop/view_compiler/dex_layout_compiler.cc
index 8febfb7..cb820f8 100644
--- a/startop/view_compiler/dex_layout_compiler.cc
+++ b/startop/view_compiler/dex_layout_compiler.cc
@@ -22,76 +22,94 @@
 namespace startop {
 
 using android::base::StringPrintf;
+using dex::Instruction;
+using dex::LiveRegister;
+using dex::Prototype;
+using dex::TypeDescriptor;
+using dex::Value;
+
+namespace {
+// TODO: these are a bunch of static initializers, which we should avoid. See if
+// we can make them constexpr.
+const TypeDescriptor kAttributeSet = TypeDescriptor::FromClassname("android.util.AttributeSet");
+const TypeDescriptor kContext = TypeDescriptor::FromClassname("android.content.Context");
+const TypeDescriptor kLayoutInflater = TypeDescriptor::FromClassname("android.view.LayoutInflater");
+const TypeDescriptor kResources = TypeDescriptor::FromClassname("android.content.res.Resources");
+const TypeDescriptor kString = TypeDescriptor::FromClassname("java.lang.String");
+const TypeDescriptor kView = TypeDescriptor::FromClassname("android.view.View");
+const TypeDescriptor kViewGroup = TypeDescriptor::FromClassname("android.view.ViewGroup");
+const TypeDescriptor kXmlResourceParser =
+    TypeDescriptor::FromClassname("android.content.res.XmlResourceParser");
+}  // namespace
 
 DexViewBuilder::DexViewBuilder(dex::MethodBuilder* method)
     : method_{method},
-      context_{dex::Value::Parameter(0)},
-      resid_{dex::Value::Parameter(1)},
-      inflater_{method->MakeRegister()},
-      xml_{method->MakeRegister()},
-      attrs_{method->MakeRegister()},
-      classname_tmp_{method->MakeRegister()},
-      xml_next_{method->dex_file()->GetOrDeclareMethod(
-          dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser"), "next",
-          dex::Prototype{dex::TypeDescriptor::Int()})},
+      context_{Value::Parameter(0)},
+      resid_{Value::Parameter(1)},
+      inflater_{method->AllocRegister()},
+      xml_{method->AllocRegister()},
+      attrs_{method->AllocRegister()},
+      classname_tmp_{method->AllocRegister()},
+      xml_next_{method->dex_file()->GetOrDeclareMethod(kXmlResourceParser, "next",
+                                                       Prototype{TypeDescriptor::Int()})},
       try_create_view_{method->dex_file()->GetOrDeclareMethod(
-          dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"), "tryCreateView",
-          dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.View"),
-                         dex::TypeDescriptor::FromClassname("android.view.View"),
-                         dex::TypeDescriptor::FromClassname("java.lang.String"),
-                         dex::TypeDescriptor::FromClassname("android.content.Context"),
-                         dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})},
+          kLayoutInflater, "tryCreateView",
+          Prototype{kView, kView, kString, kContext, kAttributeSet})},
       generate_layout_params_{method->dex_file()->GetOrDeclareMethod(
-          dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "generateLayoutParams",
-          dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams"),
-                         dex::TypeDescriptor::FromClassname("android.util.AttributeSet")})},
+          kViewGroup, "generateLayoutParams",
+          Prototype{TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams"),
+                    kAttributeSet})},
       add_view_{method->dex_file()->GetOrDeclareMethod(
-          dex::TypeDescriptor::FromClassname("android.view.ViewGroup"), "addView",
-          dex::Prototype{
-              dex::TypeDescriptor::Void(),
-              dex::TypeDescriptor::FromClassname("android.view.View"),
-              dex::TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams")})},
-      // The register stack starts with one register, which will be null for the root view.
-      register_stack_{{method->MakeRegister()}} {}
+          kViewGroup, "addView",
+          Prototype{TypeDescriptor::Void(),
+                    kView,
+                    TypeDescriptor::FromClassname("android.view.ViewGroup$LayoutParams")})} {}
+
+void DexViewBuilder::BuildGetLayoutInflater(Value dest) {
+  // dest = LayoutInflater.from(context);
+  auto layout_inflater_from = method_->dex_file()->GetOrDeclareMethod(
+      kLayoutInflater, "from", Prototype{kLayoutInflater, kContext});
+  method_->AddInstruction(Instruction::InvokeStaticObject(layout_inflater_from.id, dest, context_));
+}
+
+void DexViewBuilder::BuildGetResources(Value dest) {
+  // dest = context.getResources();
+  auto get_resources =
+      method_->dex_file()->GetOrDeclareMethod(kContext, "getResources", Prototype{kResources});
+  method_->AddInstruction(Instruction::InvokeVirtualObject(get_resources.id, dest, context_));
+}
+
+void DexViewBuilder::BuildGetLayoutResource(Value dest, Value resources, Value resid) {
+  // dest = resources.getLayout(resid);
+  auto get_layout = method_->dex_file()->GetOrDeclareMethod(
+      kResources, "getLayout", Prototype{kXmlResourceParser, TypeDescriptor::Int()});
+  method_->AddInstruction(Instruction::InvokeVirtualObject(get_layout.id, dest, resources, resid));
+}
+
+void DexViewBuilder::BuildLayoutResourceToAttributeSet(dex::Value dest,
+                                                       dex::Value layout_resource) {
+  // dest = Xml.asAttributeSet(layout_resource);
+  auto as_attribute_set = method_->dex_file()->GetOrDeclareMethod(
+      TypeDescriptor::FromClassname("android.util.Xml"),
+      "asAttributeSet",
+      Prototype{kAttributeSet, TypeDescriptor::FromClassname("org.xmlpull.v1.XmlPullParser")});
+  method_->AddInstruction(
+      Instruction::InvokeStaticObject(as_attribute_set.id, dest, layout_resource));
+}
+
+void DexViewBuilder::BuildXmlNext() {
+  // xml_.next();
+  method_->AddInstruction(Instruction::InvokeInterface(xml_next_.id, {}, xml_));
+}
 
 void DexViewBuilder::Start() {
-  dex::DexBuilder* const dex = method_->dex_file();
+  BuildGetLayoutInflater(/*dest=*/inflater_);
+  BuildGetResources(/*dest=*/xml_);
+  BuildGetLayoutResource(/*dest=*/xml_, /*resources=*/xml_, resid_);
+  BuildLayoutResourceToAttributeSet(/*dest=*/attrs_, /*layout_resource=*/xml_);
 
-  // LayoutInflater inflater = LayoutInflater.from(context);
-  auto layout_inflater_from = dex->GetOrDeclareMethod(
-      dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"),
-      "from",
-      dex::Prototype{dex::TypeDescriptor::FromClassname("android.view.LayoutInflater"),
-                     dex::TypeDescriptor::FromClassname("android.content.Context")});
-  method_->AddInstruction(
-      dex::Instruction::InvokeStaticObject(layout_inflater_from.id, /*dest=*/inflater_, context_));
-
-  // Resources res = context.getResources();
-  auto context_type = dex::TypeDescriptor::FromClassname("android.content.Context");
-  auto resources_type = dex::TypeDescriptor::FromClassname("android.content.res.Resources");
-  auto get_resources =
-      dex->GetOrDeclareMethod(context_type, "getResources", dex::Prototype{resources_type});
-  method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_resources.id, xml_, context_));
-
-  // XmlResourceParser xml = res.getLayout(resid);
-  auto xml_resource_parser_type =
-      dex::TypeDescriptor::FromClassname("android.content.res.XmlResourceParser");
-  auto get_layout =
-      dex->GetOrDeclareMethod(resources_type,
-                              "getLayout",
-                              dex::Prototype{xml_resource_parser_type, dex::TypeDescriptor::Int()});
-  method_->AddInstruction(dex::Instruction::InvokeVirtualObject(get_layout.id, xml_, xml_, resid_));
-
-  // AttributeSet attrs = Xml.asAttributeSet(xml);
-  auto as_attribute_set = dex->GetOrDeclareMethod(
-      dex::TypeDescriptor::FromClassname("android.util.Xml"),
-      "asAttributeSet",
-      dex::Prototype{dex::TypeDescriptor::FromClassname("android.util.AttributeSet"),
-                     dex::TypeDescriptor::FromClassname("org.xmlpull.v1.XmlPullParser")});
-  method_->AddInstruction(dex::Instruction::InvokeStaticObject(as_attribute_set.id, attrs_, xml_));
-
-  // xml.next(); // start document
-  method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_));
+  // Advance past start document tag
+  BuildXmlNext();
 }
 
 void DexViewBuilder::Finish() {}
@@ -107,58 +125,57 @@
 }
 }  // namespace
 
+void DexViewBuilder::BuildTryCreateView(Value dest, Value parent, Value classname) {
+  // dest = inflater_.tryCreateView(parent, classname, context_, attrs_);
+  method_->AddInstruction(Instruction::InvokeVirtualObject(
+      try_create_view_.id, dest, inflater_, parent, classname, context_, attrs_));
+}
+
 void DexViewBuilder::StartView(const std::string& name, bool is_viewgroup) {
   bool const is_root_view = view_stack_.empty();
 
-  // xml.next(); // start tag
-  method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_));
+  // Advance to start tag
+  BuildXmlNext();
 
-  dex::Value view = AcquireRegister();
+  LiveRegister view = AcquireRegister();
   // try to create the view using the factories
   method_->BuildConstString(classname_tmp_,
                             name);  // TODO: the need to fully qualify the classname
   if (is_root_view) {
-    dex::Value null = AcquireRegister();
+    LiveRegister null = AcquireRegister();
     method_->BuildConst4(null, 0);
-    method_->AddInstruction(dex::Instruction::InvokeVirtualObject(
-        try_create_view_.id, view, inflater_, null, classname_tmp_, context_, attrs_));
-    ReleaseRegister();
+    BuildTryCreateView(/*dest=*/view, /*parent=*/null, classname_tmp_);
   } else {
-    method_->AddInstruction(dex::Instruction::InvokeVirtualObject(
-        try_create_view_.id, view, inflater_, GetCurrentView(), classname_tmp_, context_, attrs_));
+    BuildTryCreateView(/*dest=*/view, /*parent=*/GetCurrentView(), classname_tmp_);
   }
   auto label = method_->MakeLabel();
   // branch if not null
   method_->AddInstruction(
-      dex::Instruction::OpWithArgs(dex::Instruction::Op::kBranchNEqz, /*dest=*/{}, view, label));
+      Instruction::OpWithArgs(Instruction::Op::kBranchNEqz, /*dest=*/{}, view, label));
 
   // If null, create the class directly.
   method_->BuildNew(view,
-                    dex::TypeDescriptor::FromClassname(ResolveName(name)),
-                    dex::Prototype{dex::TypeDescriptor::Void(),
-                                   dex::TypeDescriptor::FromClassname("android.content.Context"),
-                                   dex::TypeDescriptor::FromClassname("android.util.AttributeSet")},
+                    TypeDescriptor::FromClassname(ResolveName(name)),
+                    Prototype{TypeDescriptor::Void(), kContext, kAttributeSet},
                     context_,
                     attrs_);
 
-  method_->AddInstruction(
-      dex::Instruction::OpWithArgs(dex::Instruction::Op::kBindLabel, /*dest=*/{}, label));
+  method_->AddInstruction(Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, label));
 
   if (is_viewgroup) {
     // Cast to a ViewGroup so we can add children later.
-    const ir::Type* view_group_def = method_->dex_file()->GetOrAddType(
-        dex::TypeDescriptor::FromClassname("android.view.ViewGroup").descriptor());
-    method_->AddInstruction(dex::Instruction::Cast(view, dex::Value::Type(view_group_def->orig_index)));
+    const ir::Type* view_group_def = method_->dex_file()->GetOrAddType(kViewGroup.descriptor());
+    method_->AddInstruction(Instruction::Cast(view, Value::Type(view_group_def->orig_index)));
   }
 
   if (!is_root_view) {
     // layout_params = parent.generateLayoutParams(attrs);
-    dex::Value layout_params{AcquireRegister()};
-    method_->AddInstruction(dex::Instruction::InvokeVirtualObject(
+    LiveRegister layout_params{AcquireRegister()};
+    method_->AddInstruction(Instruction::InvokeVirtualObject(
         generate_layout_params_.id, layout_params, GetCurrentView(), attrs_));
-    view_stack_.push_back({view, layout_params});
+    view_stack_.push_back({std::move(view), std::move(layout_params)});
   } else {
-    view_stack_.push_back({view, {}});
+    view_stack_.push_back({std::move(view), {}});
   }
 }
 
@@ -167,40 +184,24 @@
     method_->BuildReturn(GetCurrentView(), /*is_object=*/true);
   } else {
     // parent.add(view, layout_params)
-    method_->AddInstruction(dex::Instruction::InvokeVirtual(
+    method_->AddInstruction(Instruction::InvokeVirtual(
         add_view_.id, /*dest=*/{}, GetParentView(), GetCurrentView(), GetCurrentLayoutParams()));
     // xml.next(); // end tag
-    method_->AddInstruction(dex::Instruction::InvokeInterface(xml_next_.id, {}, xml_));
+    method_->AddInstruction(Instruction::InvokeInterface(xml_next_.id, {}, xml_));
   }
   PopViewStack();
 }
 
-dex::Value DexViewBuilder::AcquireRegister() {
-  top_register_++;
-  if (register_stack_.size() == top_register_) {
-    register_stack_.push_back(method_->MakeRegister());
-  }
-  return register_stack_[top_register_];
-}
+LiveRegister DexViewBuilder::AcquireRegister() { return method_->AllocRegister(); }
 
-void DexViewBuilder::ReleaseRegister() { top_register_--; }
-
-dex::Value DexViewBuilder::GetCurrentView() const { return view_stack_.back().view; }
-dex::Value DexViewBuilder::GetCurrentLayoutParams() const {
+Value DexViewBuilder::GetCurrentView() const { return view_stack_.back().view; }
+Value DexViewBuilder::GetCurrentLayoutParams() const {
   return view_stack_.back().layout_params.value();
 }
-dex::Value DexViewBuilder::GetParentView() const {
-  return view_stack_[view_stack_.size() - 2].view;
-}
+Value DexViewBuilder::GetParentView() const { return view_stack_[view_stack_.size() - 2].view; }
 
 void DexViewBuilder::PopViewStack() {
-  const auto& top = view_stack_.back();
-  // release the layout params if we have them
-  if (top.layout_params.has_value()) {
-    ReleaseRegister();
-  }
   // Unconditionally release the view register.
-  ReleaseRegister();
   view_stack_.pop_back();
 }
 
diff --git a/startop/view_compiler/dex_layout_compiler.h b/startop/view_compiler/dex_layout_compiler.h
index 170a1a6..a34ed1f 100644
--- a/startop/view_compiler/dex_layout_compiler.h
+++ b/startop/view_compiler/dex_layout_compiler.h
@@ -79,36 +79,41 @@
 
  private:
   // Accessors for the stack of views that are under construction.
-  dex::Value AcquireRegister();
-  void ReleaseRegister();
+  dex::LiveRegister AcquireRegister();
   dex::Value GetCurrentView() const;
   dex::Value GetCurrentLayoutParams() const;
   dex::Value GetParentView() const;
   void PopViewStack();
 
+  // Methods to simplify building different code fragments.
+  void BuildGetLayoutInflater(dex::Value dest);
+  void BuildGetResources(dex::Value dest);
+  void BuildGetLayoutResource(dex::Value dest, dex::Value resources, dex::Value resid);
+  void BuildLayoutResourceToAttributeSet(dex::Value dest, dex::Value layout_resource);
+  void BuildXmlNext();
+  void BuildTryCreateView(dex::Value dest, dex::Value parent, dex::Value classname);
+
   dex::MethodBuilder* method_;
 
-  // Registers used for code generation
+  // Parameters to the generated method
   dex::Value const context_;
   dex::Value const resid_;
-  const dex::Value inflater_;
-  const dex::Value xml_;
-  const dex::Value attrs_;
-  const dex::Value classname_tmp_;
+
+  // Registers used for code generation
+  const dex::LiveRegister inflater_;
+  const dex::LiveRegister xml_;
+  const dex::LiveRegister attrs_;
+  const dex::LiveRegister classname_tmp_;
 
   const dex::MethodDeclData xml_next_;
   const dex::MethodDeclData try_create_view_;
   const dex::MethodDeclData generate_layout_params_;
   const dex::MethodDeclData add_view_;
 
-  // used for keeping track of which registers are in use
-  size_t top_register_{0};
-  std::vector<dex::Value> register_stack_;
-
   // Keep track of the views currently in progress.
   struct ViewEntry {
-    dex::Value view;
-    std::optional<dex::Value> layout_params;
+    dex::LiveRegister view;
+    std::optional<dex::LiveRegister> layout_params;
   };
   std::vector<ViewEntry> view_stack_;
 };
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
index 6dedf24..5dda59e 100644
--- a/startop/view_compiler/dex_testcase_generator.cc
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -47,7 +47,7 @@
   // int return5() { return 5; }
   auto return5{cbuilder.CreateMethod("return5", Prototype{TypeDescriptor::Int()})};
   {
-    Value r{return5.MakeRegister()};
+    LiveRegister r{return5.AllocRegister()};
     return5.BuildConst4(r, 5);
     return5.BuildReturn(r);
   }
@@ -57,9 +57,9 @@
   auto integer_type{TypeDescriptor::FromClassname("java.lang.Integer")};
   auto returnInteger5{cbuilder.CreateMethod("returnInteger5", Prototype{integer_type})};
   [&](MethodBuilder& method) {
-    Value five{method.MakeRegister()};
+    LiveRegister five{method.AllocRegister()};
     method.BuildConst4(five, 5);
-    Value object{method.MakeRegister()};
+    LiveRegister object{method.AllocRegister()};
     method.BuildNew(
         object, integer_type, Prototype{TypeDescriptor::Void(), TypeDescriptor::Int()}, five);
     method.BuildReturn(object, /*is_object=*/true);
@@ -80,7 +80,7 @@
   auto returnStringLength{
       cbuilder.CreateMethod("returnStringLength", Prototype{TypeDescriptor::Int(), string_type})};
   {
-    Value result = returnStringLength.MakeRegister();
+    LiveRegister result = returnStringLength.AllocRegister();
     returnStringLength.AddInstruction(
         Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0)));
     returnStringLength.BuildReturn(result);
@@ -91,7 +91,7 @@
   MethodBuilder returnIfZero{cbuilder.CreateMethod(
       "returnIfZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
   {
-    Value resultIfZero{returnIfZero.MakeRegister()};
+    LiveRegister resultIfZero{returnIfZero.AllocRegister()};
     Value else_target{returnIfZero.MakeLabel()};
     returnIfZero.AddInstruction(Instruction::OpWithArgs(
         Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target));
@@ -112,7 +112,7 @@
   MethodBuilder returnIfNotZero{cbuilder.CreateMethod(
       "returnIfNotZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
   {
-    Value resultIfNotZero{returnIfNotZero.MakeRegister()};
+    LiveRegister resultIfNotZero{returnIfNotZero.AllocRegister()};
     Value else_target{returnIfNotZero.MakeLabel()};
     returnIfNotZero.AddInstruction(Instruction::OpWithArgs(
         Instruction::Op::kBranchNEqz, /*dest=*/{}, Value::Parameter(0), else_target));
@@ -148,8 +148,8 @@
   MethodBuilder backwardsBranch{
       cbuilder.CreateMethod("backwardsBranch", Prototype{TypeDescriptor::Int()})};
   [](MethodBuilder& method) {
-    Value zero = method.MakeRegister();
-    Value result = method.MakeRegister();
+    LiveRegister zero = method.AllocRegister();
+    LiveRegister result = method.AllocRegister();
     Value labelA = method.MakeLabel();
     Value labelB = method.MakeLabel();
     method.BuildConst4(zero, 0);
@@ -177,7 +177,7 @@
   // public static String returnNull() { return null; }
   MethodBuilder returnNull{cbuilder.CreateMethod("returnNull", Prototype{string_type})};
   [](MethodBuilder& method) {
-    Value zero = method.MakeRegister();
+    LiveRegister zero = method.AllocRegister();
     method.BuildConst4(zero, 0);
     method.BuildReturn(zero, /*is_object=*/true);
   }(returnNull);
@@ -188,7 +188,7 @@
   // public static String makeString() { return "Hello, World!"; }
   MethodBuilder makeString{cbuilder.CreateMethod("makeString", Prototype{string_type})};
   [](MethodBuilder& method) {
-    Value string = method.MakeRegister();
+    LiveRegister string = method.AllocRegister();
     method.BuildConstString(string, "Hello, World!");
     method.BuildReturn(string, /*is_object=*/true);
   }(makeString);
@@ -200,7 +200,7 @@
   MethodBuilder returnStringIfZeroAB{
       cbuilder.CreateMethod("returnStringIfZeroAB", Prototype{string_type, TypeDescriptor::Int()})};
   [&](MethodBuilder& method) {
-    Value resultIfZero{method.MakeRegister()};
+    LiveRegister resultIfZero{method.AllocRegister()};
     Value else_target{method.MakeLabel()};
     method.AddInstruction(Instruction::OpWithArgs(
         Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target));
@@ -220,7 +220,7 @@
   MethodBuilder returnStringIfZeroBA{
       cbuilder.CreateMethod("returnStringIfZeroBA", Prototype{string_type, TypeDescriptor::Int()})};
   [&](MethodBuilder& method) {
-    Value resultIfZero{method.MakeRegister()};
+    LiveRegister resultIfZero{method.AllocRegister()};
     Value else_target{method.MakeLabel()};
     method.AddInstruction(Instruction::OpWithArgs(
         Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target));
@@ -244,7 +244,7 @@
       cbuilder.CreateMethod("invokeStaticReturnObject",
                             Prototype{string_type, TypeDescriptor::Int(), TypeDescriptor::Int()})};
   [&](MethodBuilder& method) {
-    Value result{method.MakeRegister()};
+    LiveRegister result{method.AllocRegister()};
     MethodDeclData to_string{dex_file.GetOrDeclareMethod(
         TypeDescriptor::FromClassname("java.lang.Integer"),
         "toString",
@@ -260,7 +260,7 @@
   MethodBuilder invokeVirtualReturnObject{cbuilder.CreateMethod(
       "invokeVirtualReturnObject", Prototype{string_type, string_type, TypeDescriptor::Int()})};
   [&](MethodBuilder& method) {
-    Value result{method.MakeRegister()};
+    LiveRegister result{method.AllocRegister()};
     MethodDeclData substring{dex_file.GetOrDeclareMethod(
         string_type, "substring", Prototype{string_type, TypeDescriptor::Int()})};
     method.AddInstruction(Instruction::InvokeVirtualObject(
@@ -291,7 +291,7 @@
   [&](MethodBuilder& method) {
     const ir::FieldDecl* field =
         dex_file.GetOrAddField(test_class, "staticInteger", TypeDescriptor::Int());
-    Value result{method.MakeRegister()};
+    LiveRegister result{method.AllocRegister()};
     method.AddInstruction(Instruction::GetStaticField(field->orig_index, result));
     method.BuildReturn(result, /*is_object=*/false);
     method.Encode();
@@ -304,7 +304,7 @@
   [&](MethodBuilder& method) {
     const ir::FieldDecl* field =
         dex_file.GetOrAddField(test_class, "staticInteger", TypeDescriptor::Int());
-    Value number{method.MakeRegister()};
+    LiveRegister number{method.AllocRegister()};
     method.BuildConst4(number, 7);
     method.AddInstruction(Instruction::SetStaticField(field->orig_index, number));
     method.BuildReturn();
@@ -318,7 +318,7 @@
   [&](MethodBuilder& method) {
     const ir::FieldDecl* field =
         dex_file.GetOrAddField(test_class, "instanceField", TypeDescriptor::Int());
-    Value result{method.MakeRegister()};
+    LiveRegister result{method.AllocRegister()};
     method.AddInstruction(Instruction::GetField(field->orig_index, result, Value::Parameter(0)));
     method.BuildReturn(result, /*is_object=*/false);
     method.Encode();
@@ -331,7 +331,7 @@
   [&](MethodBuilder& method) {
     const ir::FieldDecl* field =
         dex_file.GetOrAddField(test_class, "instanceField", TypeDescriptor::Int());
-    Value number{method.MakeRegister()};
+    LiveRegister number{method.AllocRegister()};
     method.BuildConst4(number, 7);
     method.AddInstruction(Instruction::SetField(field->orig_index, Value::Parameter(0), number));
     method.BuildReturn();
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 0e0406d..e4f8d11 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -16,7 +16,6 @@
 
 package android.telecom;
 
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.SdkConstant;
 import android.app.Service;
@@ -33,9 +32,6 @@
 import com.android.internal.telecom.ICallScreeningAdapter;
 import com.android.internal.telecom.ICallScreeningService;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * This service can be implemented by the default dialer (see
  * {@link TelecomManager#getDefaultDialerPackage()}) or a third party app to allow or disallow
@@ -75,7 +71,7 @@
  *
  * public void requestRole() {
  *     RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE);
- *     Intent intent = roleManager.createRequestRoleIntent("android.app.role.CALL_SCREENING");
+ *     Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING);
  *     startActivityForResult(intent, REQUEST_ID);
  * }
  *
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 79b78f2..8bd8625 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -67,6 +67,7 @@
 import android.telephony.data.ApnSetting;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyServiceCategories;
+import android.telephony.ims.ImsMmTelManager;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
 import android.telephony.ims.aidl.IImsRcsFeature;
@@ -8579,7 +8580,12 @@
         return -1;
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use {@link android.telephony.ims.ImsMmTelManager#setVtSettingEnabled(boolean)}
+     * instead.
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
     public void enableVideoCalling(boolean enable) {
@@ -8592,7 +8598,14 @@
         }
     }
 
-    /** @hide */
+    /**
+     * @deprecated Use {@link ImsMmTelManager#isVtSettingEnabled()} instead to check if the user
+     * has enabled the Video Calling setting, {@link ImsMmTelManager#isAvailable(int, int)} to
+     * determine if video calling is available, or {@link ImsMmTelManager#isCapable(int, int)} to
+     * determine if video calling is capable.
+     * @hide
+     */
+    @Deprecated
     @SystemApi
     @RequiresPermission(anyOf = {
             android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
@@ -8712,6 +8725,7 @@
      * @param subId Subscription ID
      * @return true if IMS status is registered, false if the IMS status is not registered or a
      * RemoteException occurred.
+     * Use {@link ImsMmTelManager.RegistrationCallback} instead.
      * @hide
      */
     public boolean isImsRegistered(int subId) {
@@ -8748,6 +8762,8 @@
      * used during creation, the default subscription ID will be used.
      * @return true if Voice over LTE is available or false if it is unavailable or unknown.
      * @see SubscriptionManager#getDefaultSubscriptionId()
+     * <p>
+     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
     @UnsupportedAppUsage
@@ -8767,6 +8783,7 @@
      * used during creation, the default subscription ID will be used. To query the
      * underlying technology that VT is available on, use {@link #getImsRegTechnologyForMmTel}.
      * @return true if VT is available, or false if it is unavailable or unknown.
+     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
     @UnsupportedAppUsage
@@ -8782,6 +8799,7 @@
      * Returns the Status of Wi-Fi calling (Voice over WiFi) for the subscription ID specified.
      * @param subId the subscription ID.
      * @return true if VoWiFi is available, or false if it is unavailable or unknown.
+     * Use {@link ImsMmTelManager#isAvailable(int, int)} instead.
      * @hide
      */
     @UnsupportedAppUsage
@@ -8802,6 +8820,7 @@
      *  - {@link ImsRegistrationImplBase#REGISTRATION_TECH_IWLAN} for IWLAN registration, or
      *  - {@link ImsRegistrationImplBase#REGISTRATION_TECH_NONE} if we are not registered or the
      *  result is unavailable.
+     *  Use {@link ImsMmTelManager.RegistrationCallback} instead.
      *  @hide
      */
     public @ImsRegistrationImplBase.ImsRegistrationTech int getImsRegTechnologyForMmTel() {
diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
index af993be..e9a177d 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java
@@ -115,7 +115,7 @@
             final Context otherContext;
             try {
                 otherContext = context.createPackageContextAsUser(context.getPackageName(),
-                        /* flags =*/ 0, new UserHandle(currentUser));
+                        /* flags =*/ 0, UserHandle.of(currentUser));
                 return otherContext.getContentResolver();
             } catch (NameNotFoundException e) {
                 Rlog.e(LOG_TAG, "Can't find self package", e);
diff --git a/telephony/java/com/android/internal/telephony/SmsApplication.java b/telephony/java/com/android/internal/telephony/SmsApplication.java
index 98f52cb..f17a1a5 100644
--- a/telephony/java/com/android/internal/telephony/SmsApplication.java
+++ b/telephony/java/com/android/internal/telephony/SmsApplication.java
@@ -158,7 +158,7 @@
                 ApplicationInfo appInfo;
                 try {
                     appInfo = pm.getApplicationInfoAsUser(mPackageName, 0,
-                            UserHandle.getUserId(mUid));
+                            UserHandle.getUserHandleForUid(mUid));
                 } catch (NameNotFoundException e) {
                     return null;
                 }
@@ -300,7 +300,7 @@
                 Uri.fromParts(SCHEME_SMSTO, "", null));
         List<ResolveInfo> respondServices = packageManager.queryIntentServicesAsUser(intent,
                 PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
-                userId);
+                UserHandle.getUserHandleForUid(userId));
         for (ResolveInfo resolveInfo : respondServices) {
             final ServiceInfo serviceInfo = resolveInfo.serviceInfo;
             if (serviceInfo == null) {
@@ -806,7 +806,7 @@
             if (userId != UserHandle.USER_SYSTEM) {
                 try {
                     userContext = mContext.createPackageContextAsUser(mContext.getPackageName(), 0,
-                            new UserHandle(userId));
+                        UserHandle.of(userId));
                 } catch (NameNotFoundException nnfe) {
                     if (DEBUG_MULTIUSER) {
                         Log.w(LOG_TAG, "Unable to create package context for user " + userId);
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index 7a0ab9c..2dba70f 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -178,7 +178,7 @@
         // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage)
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage)
                 == AppOpsManager.MODE_ALLOWED;
     }
 
@@ -226,7 +226,7 @@
         // We have READ_PHONE_STATE permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, uid, callingPackage) ==
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_STATE, uid, callingPackage) ==
                 AppOpsManager.MODE_ALLOWED;
     }
 
@@ -367,7 +367,7 @@
         ApplicationInfo callingPackageInfo = null;
         try {
             callingPackageInfo = context.getPackageManager().getApplicationInfoAsUser(
-                    callingPackage, 0, UserHandle.getUserId(uid));
+                    callingPackage, 0, UserHandle.getUserHandleForUid(uid));
             if (callingPackageInfo != null) {
                 if (callingPackageInfo.isSystemApp()) {
                     isPreinstalled = true;
@@ -448,7 +448,7 @@
         // We have READ_CALL_LOG permission, so return true as long as the AppOps bit hasn't been
         // revoked.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        return appOps.noteOp(AppOpsManager.OP_READ_CALL_LOG, uid, callingPackage) ==
+        return appOps.noteOp(AppOpsManager.OPSTR_READ_CALL_LOG, uid, callingPackage) ==
                 AppOpsManager.MODE_ALLOWED;
     }
 
@@ -471,7 +471,7 @@
             String callingPackage, String message) {
         // Default SMS app can always read it.
         AppOpsManager appOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
-        if (appOps.noteOp(AppOpsManager.OP_WRITE_SMS, uid, callingPackage) ==
+        if (appOps.noteOp(AppOpsManager.OPSTR_WRITE_SMS, uid, callingPackage) ==
                 AppOpsManager.MODE_ALLOWED) {
             return true;
         }
@@ -488,25 +488,18 @@
         // Can be read with READ_SMS too.
         try {
             context.enforcePermission(android.Manifest.permission.READ_SMS, pid, uid, message);
-            int opCode = AppOpsManager.permissionToOpCode(android.Manifest.permission.READ_SMS);
-            if (opCode != AppOpsManager.OP_NONE) {
-                return appOps.noteOp(opCode, uid, callingPackage) == AppOpsManager.MODE_ALLOWED;
-            } else {
-                return true;
-            }
+            return appOps.noteOp(AppOpsManager.OPSTR_READ_SMS, uid, callingPackage)
+                == AppOpsManager.MODE_ALLOWED;
+
         } catch (SecurityException readSmsSecurityException) {
         }
         // Can be read with READ_PHONE_NUMBERS too.
         try {
             context.enforcePermission(android.Manifest.permission.READ_PHONE_NUMBERS, pid, uid,
                     message);
-            int opCode = AppOpsManager.permissionToOpCode(
-                    android.Manifest.permission.READ_PHONE_NUMBERS);
-            if (opCode != AppOpsManager.OP_NONE) {
-                return appOps.noteOp(opCode, uid, callingPackage) == AppOpsManager.MODE_ALLOWED;
-            } else {
-                return true;
-            }
+            return appOps.noteOp(AppOpsManager.OPSTR_READ_PHONE_NUMBERS, uid, callingPackage)
+                == AppOpsManager.MODE_ALLOWED;
+
         } catch (SecurityException readPhoneNumberSecurityException) {
         }
 
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index adc9e22..81b1e49 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -19,10 +19,9 @@
 java_sdk_library {
     name: "android.test.mock",
 
-    srcs: [
-        "src/**/*.java",
-        ":framework-all-sources",
-    ],
+    srcs: ["src/**/*.java"],
+    api_srcs: [":framework-all-sources"],
+    libs: ["framework-all"],
 
     api_packages: [
         "android.test.mock",
diff --git a/tests/BootImageProfileTest/Android.bp b/tests/BootImageProfileTest/Android.bp
new file mode 100644
index 0000000..1b097a8
--- /dev/null
+++ b/tests/BootImageProfileTest/Android.bp
@@ -0,0 +1,20 @@
+// 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.
+
+java_test_host {
+    name: "BootImageProfileTest",
+    srcs: ["src/**/*.java"],
+    libs: ["tradefed"],
+    test_suites: ["general-tests"],
+}
diff --git a/tests/BootImageProfileTest/AndroidTest.xml b/tests/BootImageProfileTest/AndroidTest.xml
new file mode 100644
index 0000000..c132007
--- /dev/null
+++ b/tests/BootImageProfileTest/AndroidTest.xml
@@ -0,0 +1,39 @@
+<?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.
+-->
+<configuration description="Config for BootImageProfileTest">
+     <!-- do not use DeviceSetup#set-property because it reboots the device b/136200738.
+         furthermore the changes in /data/local.prop don't actually seem to get picked up.
+    -->
+    <target_preparer
+        class="com.android.tradefed.targetprep.DeviceSetup">
+        <!-- we need this magic flag, otherwise it always reboots and breaks the selinux -->
+        <option name="force-skip-system-props" value="true" />
+
+        <option name="run-command" value="setprop dalvik.vm.profilesystemserver true" />
+        <option name="run-command" value="setprop dalvik.vm.profilebootclasspath true" />
+
+        <!-- Profiling does not pick up the above changes we restart the shell -->
+        <option name="run-command" value="stop" />
+        <option name="run-command" value="start" />
+
+        <!-- give it some time to restart the shell; otherwise the first unit test might fail -->
+        <option name="run-command" value="sleep 2" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.HostTest" >
+        <option name="class" value="com.android.bootimageprofile.BootImageProfileTest" />
+    </test>
+</configuration>
diff --git a/tests/BootImageProfileTest/TEST_MAPPING b/tests/BootImageProfileTest/TEST_MAPPING
new file mode 100644
index 0000000..1b569f9
--- /dev/null
+++ b/tests/BootImageProfileTest/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit": [
+    {
+      "name": "BootImageProfileTest"
+    }
+  ]
+}
diff --git a/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
new file mode 100644
index 0000000..730b210
--- /dev/null
+++ b/tests/BootImageProfileTest/src/com/android/bootimageprofile/BootImageProfileTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.bootimageprofile;
+
+import static org.junit.Assert.assertTrue;
+
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.IDeviceTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class BootImageProfileTest implements IDeviceTest {
+    private ITestDevice mTestDevice;
+    private static final String SYSTEM_SERVER_PROFILE =
+            "/data/misc/profiles/cur/0/android/primary.prof";
+
+    @Override
+    public void setDevice(ITestDevice testDevice) {
+        mTestDevice = testDevice;
+    }
+
+    @Override
+    public ITestDevice getDevice() {
+        return mTestDevice;
+    }
+
+    /**
+     * Test that the boot image profile properties are set.
+     */
+    @Test
+    public void testProperties() throws Exception {
+        String res = mTestDevice.getProperty("dalvik.vm.profilebootclasspath");
+        assertTrue("profile boot class path not enabled", res != null && res.equals("true"));
+        res = mTestDevice.getProperty("dalvik.vm.profilesystemserver");
+        assertTrue("profile system server not enabled", res != null && res.equals("true"));
+    }
+
+    private void forceSaveProfile(String pkg) throws Exception {
+        String pid = mTestDevice.executeShellCommand("pidof " + pkg).trim();
+        assertTrue("Invalid pid " + pid, pid.length() > 0);
+        String res = mTestDevice.executeShellCommand("kill -s SIGUSR1 " + pid).trim();
+        assertTrue("kill SIGUSR1: " + res, res.length() == 0);
+    }
+
+    @Test
+    public void testSystemServerProfile() throws Exception {
+        // Trunacte the profile before force it to be saved to prevent previous profiles
+        // causing the test to pass.
+        String res;
+        res = mTestDevice.executeShellCommand("truncate -s 0 " + SYSTEM_SERVER_PROFILE).trim();
+        assertTrue(res, res.length() == 0);
+        // Wait up to 20 seconds for the profile to be saved.
+        for (int i = 0; i < 20; ++i) {
+            // Force save the profile since we truncated it.
+            forceSaveProfile("system_server");
+            String s = mTestDevice.executeShellCommand("wc -c <" + SYSTEM_SERVER_PROFILE).trim();
+            if (!"0".equals(s)) {
+                break;
+            }
+            Thread.sleep(1000);
+        }
+        // In case the profile is partially saved, wait an extra second.
+        Thread.sleep(1000);
+        // Validate that the profile is non empty.
+        res = mTestDevice.executeShellCommand("profman --dump-only --profile-file="
+                + SYSTEM_SERVER_PROFILE);
+        boolean sawFramework = false;
+        boolean sawServices = false;
+        for (String line : res.split("\n")) {
+            if (line.contains("framework.jar")) {
+                sawFramework = true;
+            } else if (line.contains("services.jar")) {
+                sawServices = true;
+            }
+        }
+        assertTrue("Did not see framework.jar in " + res, sawFramework);
+        assertTrue("Did not see services.jar in " + res, sawServices);
+    }
+}
diff --git a/tests/FlickerTests/AndroidManifest.xml b/tests/FlickerTests/AndroidManifest.xml
index 5b1a36b..91fb7c1 100644
--- a/tests/FlickerTests/AndroidManifest.xml
+++ b/tests/FlickerTests/AndroidManifest.xml
@@ -21,8 +21,12 @@
     <!-- Read and write traces from external storage -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <!-- Write secure settings -->
+    <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
     <!-- Capture screen contents -->
     <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
+    <!-- Enable / Disable tracing !-->
+    <uses-permission android:name="android.permission.DUMP" />
     <!-- Run layers trace -->
     <uses-permission android:name="android.permission.HARDWARE_TEST"/>
     <application>
@@ -33,4 +37,4 @@
                      android:targetPackage="com.android.server.wm.flicker"
                      android:label="WindowManager Flicker Tests">
     </instrumentation>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/tests/FlickerTests/AndroidTest.xml b/tests/FlickerTests/AndroidTest.xml
index e36f976..d433df5 100644
--- a/tests/FlickerTests/AndroidTest.xml
+++ b/tests/FlickerTests/AndroidTest.xml
@@ -25,5 +25,6 @@
     <metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
         <option name="directory-keys" value="/sdcard/flicker" />
         <option name="collect-on-run-ended-only" value="true" />
+        <option name="clean-up" value="false" />
     </metrics_collector>
 </configuration>
diff --git a/tests/FlickerTests/lib/Android.bp b/tests/FlickerTests/lib/Android.bp
deleted file mode 100644
index e0f0188..0000000
--- a/tests/FlickerTests/lib/Android.bp
+++ /dev/null
@@ -1,57 +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.
-//
-
-java_test {
-    name: "flickerlib",
-    platform_apis: true,
-    srcs: ["src/**/*.java"],
-    static_libs: [
-        "androidx.test.janktesthelper",
-        "cts-wm-util",
-        "platformprotosnano",
-        "layersprotosnano",
-        "truth-prebuilt",
-        "sysui-helper",
-        "launcher-helper-lib",
-    ],
-}
-
-java_library {
-    name: "flickerlib_without_helpers",
-    platform_apis: true,
-    srcs: ["src/**/*.java"],
-    exclude_srcs: ["src/**/helpers/*.java"],
-    static_libs: [
-        "cts-wm-util",
-        "platformprotosnano",
-        "layersprotosnano",
-        "truth-prebuilt"
-    ],
-}
-
-java_library {
-    name: "flickerautomationhelperlib",
-    sdk_version: "test_current",
-    srcs: [
-        "src/com/android/server/wm/flicker/helpers/AutomationUtils.java",
-        "src/com/android/server/wm/flicker/WindowUtils.java",
-    ],
-    static_libs: [
-        "sysui-helper",
-        "launcher-helper-lib",
-        "compatibility-device-util-axt",
-    ],
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/Assertions.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/Assertions.java
deleted file mode 100644
index 38255ee..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/Assertions.java
+++ /dev/null
@@ -1,134 +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.server.wm.flicker;
-
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-
-/**
- * Collection of functional interfaces and classes representing assertions and their associated
- * results. Assertions are functions that are applied over a single trace entry and returns a
- * result which includes a detailed reason if the assertion fails.
- */
-public class Assertions {
-    /**
-     * Checks assertion on a single trace entry.
-     *
-     * @param <T> trace entry type to perform the assertion on.
-     */
-    @FunctionalInterface
-    public interface TraceAssertion<T> extends Function<T, Result> {
-        /**
-         * Returns an assertion that represents the logical negation of this assertion.
-         *
-         * @return a assertion that represents the logical negation of this assertion
-         */
-        default TraceAssertion<T> negate() {
-            return (T t) -> apply(t).negate();
-        }
-    }
-
-    /**
-     * Checks assertion on a single layers trace entry.
-     */
-    @FunctionalInterface
-    public interface LayersTraceAssertion extends TraceAssertion<LayersTrace.Entry> {
-
-    }
-
-    /**
-     * Utility class to store assertions with an identifier to help generate more useful debug
-     * data when dealing with multiple assertions.
-     */
-    public static class NamedAssertion<T> {
-        public final TraceAssertion<T> assertion;
-        public final String name;
-
-        public NamedAssertion(TraceAssertion<T> assertion, String name) {
-            this.assertion = assertion;
-            this.name = name;
-        }
-    }
-
-    /**
-     * Contains the result of an assertion including the reason for failed assertions.
-     */
-    public static class Result {
-        public static final String NEGATION_PREFIX = "!";
-        public final boolean success;
-        public final long timestamp;
-        public final String assertionName;
-        public final String reason;
-
-        public Result(boolean success, long timestamp, String assertionName, String reason) {
-            this.success = success;
-            this.timestamp = timestamp;
-            this.assertionName = assertionName;
-            this.reason = reason;
-        }
-
-        public Result(boolean success, String reason) {
-            this.success = success;
-            this.reason = reason;
-            this.assertionName = "";
-            this.timestamp = 0;
-        }
-
-        /**
-         * Returns the negated {@code Result} and adds a negation prefix to the assertion name.
-         */
-        public Result negate() {
-            String negatedAssertionName;
-            if (this.assertionName.startsWith(NEGATION_PREFIX)) {
-                negatedAssertionName = this.assertionName.substring(NEGATION_PREFIX.length() + 1);
-            } else {
-                negatedAssertionName = NEGATION_PREFIX + this.assertionName;
-            }
-            return new Result(!this.success, this.timestamp, negatedAssertionName, this.reason);
-        }
-
-        public boolean passed() {
-            return this.success;
-        }
-
-        public boolean failed() {
-            return !this.success;
-        }
-
-        @Override
-        public String toString() {
-            return "Timestamp: " + prettyTimestamp(timestamp)
-                    + "\nAssertion: " + assertionName
-                    + "\nReason:   " + reason;
-        }
-
-        private String prettyTimestamp(long timestamp_ns) {
-            StringBuilder prettyTimestamp = new StringBuilder();
-            TimeUnit[] timeUnits = {TimeUnit.HOURS, TimeUnit.MINUTES, TimeUnit.SECONDS, TimeUnit
-                    .MILLISECONDS};
-            String[] unitSuffixes = {"h", "m", "s", "ms"};
-
-            for (int i = 0; i < timeUnits.length; i++) {
-                long convertedTime = timeUnits[i].convert(timestamp_ns, TimeUnit.NANOSECONDS);
-                timestamp_ns -= TimeUnit.NANOSECONDS.convert(convertedTime, timeUnits[i]);
-                prettyTimestamp.append(convertedTime).append(unitSuffixes[i]);
-            }
-
-            return prettyTimestamp.toString();
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AssertionsChecker.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AssertionsChecker.java
deleted file mode 100644
index 5c4df81..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/AssertionsChecker.java
+++ /dev/null
@@ -1,183 +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.server.wm.flicker;
-
-import com.android.server.wm.flicker.Assertions.NamedAssertion;
-import com.android.server.wm.flicker.Assertions.Result;
-import com.android.server.wm.flicker.Assertions.TraceAssertion;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Captures some of the common logic in {@link LayersTraceSubject} and {@link WmTraceSubject}
- * used to filter trace entries and combine multiple assertions.
- *
- * @param <T> trace entry type
- */
-public class AssertionsChecker<T extends ITraceEntry> {
-    private boolean mFilterEntriesByRange = false;
-    private long mFilterStartTime = 0;
-    private long mFilterEndTime = 0;
-    private AssertionOption mOption = AssertionOption.NONE;
-    private List<NamedAssertion<T>> mAssertions = new LinkedList<>();
-
-    public void add(Assertions.TraceAssertion<T> assertion, String name) {
-        mAssertions.add(new NamedAssertion<>(assertion, name));
-    }
-
-    public void filterByRange(long startTime, long endTime) {
-        mFilterEntriesByRange = true;
-        mFilterStartTime = startTime;
-        mFilterEndTime = endTime;
-    }
-
-    private void setOption(AssertionOption option) {
-        if (mOption != AssertionOption.NONE && option != mOption) {
-            throw new IllegalArgumentException("Cannot use " + mOption + " option with "
-                    + option + " option.");
-        }
-        mOption = option;
-    }
-
-    public void checkFirstEntry() {
-        setOption(AssertionOption.CHECK_FIRST_ENTRY);
-    }
-
-    public void checkLastEntry() {
-        setOption(AssertionOption.CHECK_LAST_ENTRY);
-    }
-
-    public void checkChangingAssertions() {
-        setOption(AssertionOption.CHECK_CHANGING_ASSERTIONS);
-    }
-
-
-    /**
-     * Filters trace entries then runs assertions returning a list of failures.
-     *
-     * @param entries list of entries to perform assertions on
-     * @return list of failed assertion results
-     */
-    public List<Result> test(List<T> entries) {
-        List<T> filteredEntries;
-        List<Result> failures;
-
-        if (mFilterEntriesByRange) {
-            filteredEntries = entries.stream()
-                    .filter(e -> ((e.getTimestamp() >= mFilterStartTime)
-                            && (e.getTimestamp() <= mFilterEndTime)))
-                    .collect(Collectors.toList());
-        } else {
-            filteredEntries = entries;
-        }
-
-        switch (mOption) {
-            case CHECK_CHANGING_ASSERTIONS:
-                return assertChanges(filteredEntries);
-            case CHECK_FIRST_ENTRY:
-                return assertEntry(filteredEntries.get(0));
-            case CHECK_LAST_ENTRY:
-                return assertEntry(filteredEntries.get(filteredEntries.size() - 1));
-        }
-        return assertAll(filteredEntries);
-    }
-
-    /**
-     * Steps through each trace entry checking if provided assertions are true in the order they
-     * are added. Each assertion must be true for at least a single trace entry.
-     *
-     * This can be used to check for asserting a change in property over a trace. Such as visibility
-     * for a window changes from true to false or top-most window changes from A to Bb and back to A
-     * again.
-     */
-    private List<Result> assertChanges(List<T> entries) {
-        List<Result> failures = new ArrayList<>();
-        int entryIndex = 0;
-        int assertionIndex = 0;
-        int lastPassedAssertionIndex = -1;
-
-        if (mAssertions.size() == 0) {
-            return failures;
-        }
-
-        while (assertionIndex < mAssertions.size() && entryIndex < entries.size()) {
-            TraceAssertion<T> currentAssertion = mAssertions.get(assertionIndex).assertion;
-            Result result = currentAssertion.apply(entries.get(entryIndex));
-            if (result.passed()) {
-                lastPassedAssertionIndex = assertionIndex;
-                entryIndex++;
-                continue;
-            }
-
-            if (lastPassedAssertionIndex != assertionIndex) {
-                failures.add(result);
-                break;
-            }
-            assertionIndex++;
-
-            if (assertionIndex == mAssertions.size()) {
-                failures.add(result);
-                break;
-            }
-        }
-
-        if (failures.isEmpty()) {
-            if (assertionIndex != mAssertions.size() - 1) {
-                String reason = "\nAssertion " + mAssertions.get(assertionIndex).name
-                        + " never became false";
-                reason += "\nPassed assertions: " + mAssertions.stream().limit(assertionIndex)
-                        .map(assertion -> assertion.name).collect(Collectors.joining(","));
-                reason += "\nUntested assertions: " + mAssertions.stream().skip(assertionIndex + 1)
-                        .map(assertion -> assertion.name).collect(Collectors.joining(","));
-
-                Result result = new Result(false /* success */, 0 /* timestamp */,
-                        "assertChanges", "Not all assertions passed." + reason);
-                failures.add(result);
-            }
-        }
-        return failures;
-    }
-
-    private List<Result> assertEntry(T entry) {
-        List<Result> failures = new ArrayList<>();
-        for (NamedAssertion<T> assertion : mAssertions) {
-            Result result = assertion.assertion.apply(entry);
-            if (result.failed()) {
-                failures.add(result);
-            }
-        }
-        return failures;
-    }
-
-    private List<Result> assertAll(List<T> entries) {
-        return mAssertions.stream().flatMap(
-                assertion -> entries.stream()
-                        .map(assertion.assertion)
-                        .filter(Result::failed))
-                .collect(Collectors.toList());
-    }
-
-    private enum AssertionOption {
-        NONE,
-        CHECK_CHANGING_ASSERTIONS,
-        CHECK_FIRST_ENTRY,
-        CHECK_LAST_ENTRY,
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/ITraceEntry.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/ITraceEntry.java
deleted file mode 100644
index c47f7f4..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/ITraceEntry.java
+++ /dev/null
@@ -1,27 +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.server.wm.flicker;
-
-/**
- * Common interface for Layer and WindowManager trace entries.
- */
-public interface ITraceEntry {
-    /**
-     * @return timestamp of current entry
-     */
-    long getTimestamp();
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTrace.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTrace.java
deleted file mode 100644
index 68986d4..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTrace.java
+++ /dev/null
@@ -1,420 +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.server.wm.flicker;
-
-import android.graphics.Rect;
-import android.surfaceflinger.nano.Layers.LayerProto;
-import android.surfaceflinger.nano.Layers.RectProto;
-import android.surfaceflinger.nano.Layers.RegionProto;
-import android.surfaceflinger.nano.Layerstrace.LayersTraceFileProto;
-import android.surfaceflinger.nano.Layerstrace.LayersTraceProto;
-import android.util.SparseArray;
-
-import androidx.annotation.Nullable;
-
-import com.android.server.wm.flicker.Assertions.Result;
-
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-/**
- * Contains a collection of parsed Layers trace entries and assertions to apply over
- * a single entry.
- *
- * Each entry is parsed into a list of {@link LayersTrace.Entry} objects.
- */
-public class LayersTrace {
-    final private List<Entry> mEntries;
-    @Nullable
-    final private Path mSource;
-
-    private LayersTrace(List<Entry> entries, Path source) {
-        this.mEntries = entries;
-        this.mSource = source;
-    }
-
-    /**
-     * Parses {@code LayersTraceFileProto} from {@code data} and uses the proto to generates a list
-     * of trace entries, storing the flattened layers into its hierarchical structure.
-     *
-     * @param data   binary proto data
-     * @param source Path to source of data for additional debug information
-     */
-    public static LayersTrace parseFrom(byte[] data, Path source) {
-        List<Entry> entries = new ArrayList<>();
-        LayersTraceFileProto fileProto;
-        try {
-            fileProto = LayersTraceFileProto.parseFrom(data);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        for (LayersTraceProto traceProto : fileProto.entry) {
-            Entry entry = Entry.fromFlattenedLayers(traceProto.elapsedRealtimeNanos,
-                    traceProto.layers.layers);
-            entries.add(entry);
-        }
-        return new LayersTrace(entries, source);
-    }
-
-    /**
-     * Parses {@code LayersTraceFileProto} from {@code data} and uses the proto to generates a list
-     * of trace entries, storing the flattened layers into its hierarchical structure.
-     *
-     * @param data binary proto data
-     */
-    public static LayersTrace parseFrom(byte[] data) {
-        return parseFrom(data, null);
-    }
-
-    public List<Entry> getEntries() {
-        return mEntries;
-    }
-
-    public Entry getEntry(long timestamp) {
-        Optional<Entry> entry = mEntries.stream()
-                .filter(e -> e.getTimestamp() == timestamp)
-                .findFirst();
-        if (!entry.isPresent()) {
-            throw new RuntimeException("Entry does not exist for timestamp " + timestamp);
-        }
-        return entry.get();
-    }
-
-    public Optional<Path> getSource() {
-        return Optional.ofNullable(mSource);
-    }
-
-    /**
-     * Represents a single Layer trace entry.
-     */
-    public static class Entry implements ITraceEntry {
-        private long mTimestamp;
-        private List<Layer> mRootLayers; // hierarchical representation of layers
-        private List<Layer> mFlattenedLayers = null;
-
-        private Entry(long timestamp, List<Layer> rootLayers) {
-            this.mTimestamp = timestamp;
-            this.mRootLayers = rootLayers;
-        }
-
-        /**
-         * Constructs the layer hierarchy from a flattened list of layers.
-         */
-        public static Entry fromFlattenedLayers(long timestamp, LayerProto[] protos) {
-            SparseArray<Layer> layerMap = new SparseArray<>();
-            ArrayList<Layer> orphans = new ArrayList<>();
-            for (LayerProto proto : protos) {
-                int id = proto.id;
-                int parentId = proto.parent;
-
-                Layer newLayer = layerMap.get(id);
-                if (newLayer == null) {
-                    newLayer = new Layer(proto);
-                    layerMap.append(id, newLayer);
-                } else if (newLayer.mProto != null) {
-                    throw new RuntimeException("Duplicate layer id found:" + id);
-                } else {
-                    newLayer.mProto = proto;
-                    orphans.remove(newLayer);
-                }
-
-                // add parent placeholder
-                if (layerMap.get(parentId) == null) {
-                    Layer orphanLayer = new Layer(null);
-                    layerMap.append(parentId, orphanLayer);
-                    orphans.add(orphanLayer);
-                }
-                layerMap.get(parentId).addChild(newLayer);
-                newLayer.addParent(layerMap.get(parentId));
-            }
-
-            // Fail if we find orphan layers.
-            orphans.remove(layerMap.get(-1));
-            orphans.forEach(orphan -> {
-                String childNodes = orphan.mChildren.stream().map(node ->
-                        Integer.toString(node.getId())).collect(Collectors.joining(", "));
-                int orphanId = orphan.mChildren.get(0).mProto.parent;
-                throw new RuntimeException(
-                        "Failed to parse layers trace. Found orphan layers with parent "
-                                + "layer id:" + orphanId + " : " + childNodes);
-            });
-
-            return new Entry(timestamp, layerMap.get(-1).mChildren);
-        }
-
-        /**
-         * Extracts {@link Rect} from {@link RectProto}.
-         */
-        private static Rect extract(RectProto proto) {
-            return new Rect(proto.left, proto.top, proto.right, proto.bottom);
-        }
-
-        /**
-         * Extracts {@link Rect} from {@link RegionProto} by returning a rect that encompasses all
-         * the rects making up the region.
-         */
-        private static Rect extract(RegionProto regionProto) {
-            Rect region = new Rect();
-            for (RectProto proto : regionProto.rect) {
-                region.union(proto.left, proto.top, proto.right, proto.bottom);
-            }
-            return region;
-        }
-
-        /**
-         * Checks if a region specified by {@code testRect} is covered by all visible layers.
-         */
-        public Result coversRegion(Rect testRect) {
-            String assertionName = "coversRegion";
-            Collection<Layer> layers = asFlattenedLayers();
-
-            for (int x = testRect.left; x < testRect.right; x++) {
-                for (int y = testRect.top; y < testRect.bottom; y++) {
-                    boolean emptyRegionFound = true;
-                    for (Layer layer : layers) {
-                        if (layer.isInvisible() || layer.isHiddenByParent()) {
-                            continue;
-                        }
-                        for (RectProto rectProto : layer.mProto.visibleRegion.rect) {
-                            Rect r = extract(rectProto);
-                            if (r.contains(x, y)) {
-                                y = r.bottom;
-                                emptyRegionFound = false;
-                            }
-                        }
-                    }
-                    if (emptyRegionFound) {
-                        String reason = "Region to test: " + testRect
-                                + "\nfirst empty point: " + x + ", " + y;
-                        reason += "\nvisible regions:";
-                        for (Layer layer : layers) {
-                            if (layer.isInvisible() || layer.isHiddenByParent()) {
-                                continue;
-                            }
-                            Rect r = extract(layer.mProto.visibleRegion);
-                            reason += "\n" + layer.mProto.name + r.toString();
-                        }
-                        return new Result(false /* success */, this.mTimestamp, assertionName,
-                                reason);
-                    }
-                }
-            }
-            String info = "Region covered: " + testRect;
-            return new Result(true /* success */, this.mTimestamp, assertionName, info);
-        }
-
-        /**
-         * Checks if a layer with name {@code layerName} has a visible region
-         * {@code expectedVisibleRegion}.
-         */
-        public Result hasVisibleRegion(String layerName, Rect expectedVisibleRegion) {
-            String assertionName = "hasVisibleRegion";
-            String reason = "Could not find " + layerName;
-            for (Layer layer : asFlattenedLayers()) {
-                if (layer.mProto.name.contains(layerName)) {
-                    if (layer.isHiddenByParent()) {
-                        reason = layer.getHiddenByParentReason();
-                        continue;
-                    }
-                    if (layer.isInvisible()) {
-                        reason = layer.getVisibilityReason();
-                        continue;
-                    }
-                    Rect visibleRegion = extract(layer.mProto.visibleRegion);
-                    if (visibleRegion.equals(expectedVisibleRegion)) {
-                        return new Result(true /* success */, this.mTimestamp, assertionName,
-                                layer.mProto.name + "has visible region " + expectedVisibleRegion);
-                    }
-                    reason = layer.mProto.name + " has visible region:" + visibleRegion + " "
-                            + "expected:" + expectedVisibleRegion;
-                }
-            }
-            return new Result(false /* success */, this.mTimestamp, assertionName, reason);
-        }
-
-        /**
-         * Checks if a layer with name {@code layerName} is visible.
-         */
-        public Result isVisible(String layerName) {
-            String assertionName = "isVisible";
-            String reason = "Could not find " + layerName;
-            for (Layer layer : asFlattenedLayers()) {
-                if (layer.mProto.name.contains(layerName)) {
-                    if (layer.isHiddenByParent()) {
-                        reason = layer.getHiddenByParentReason();
-                        continue;
-                    }
-                    if (layer.isInvisible()) {
-                        reason = layer.getVisibilityReason();
-                        continue;
-                    }
-                    return new Result(true /* success */, this.mTimestamp, assertionName,
-                            layer.mProto.name + " is visible");
-                }
-            }
-            return new Result(false /* success */, this.mTimestamp, assertionName, reason);
-        }
-
-        @Override
-        public long getTimestamp() {
-            return mTimestamp;
-        }
-
-        public List<Layer> getRootLayers() {
-            return mRootLayers;
-        }
-
-        /**
-         * Returns all layers as a flattened list using a depth first traversal.
-         */
-        public List<Layer> asFlattenedLayers() {
-            if (mFlattenedLayers == null) {
-                mFlattenedLayers = new LinkedList<>();
-                ArrayList<Layer> pendingLayers = new ArrayList<>(this.mRootLayers);
-                while (!pendingLayers.isEmpty()) {
-                    Layer layer = pendingLayers.remove(0);
-                    mFlattenedLayers.add(layer);
-                    pendingLayers.addAll(0, layer.mChildren);
-                }
-            }
-            return mFlattenedLayers;
-        }
-
-        public Rect getVisibleBounds(String layerName) {
-            List<Layer> layers = asFlattenedLayers();
-            for (Layer layer : layers) {
-                if (layer.mProto.name.contains(layerName) && layer.isVisible()) {
-                    return extract(layer.mProto.visibleRegion);
-                }
-            }
-            return new Rect(0, 0, 0, 0);
-        }
-    }
-
-    /**
-     * Represents a single layer with links to its parent and child layers.
-     */
-    public static class Layer {
-        @Nullable
-        public LayerProto mProto;
-        public List<Layer> mChildren;
-        @Nullable
-        public Layer mParent = null;
-
-        private Layer(LayerProto proto) {
-            this.mProto = proto;
-            this.mChildren = new ArrayList<>();
-        }
-
-        private void addChild(Layer childLayer) {
-            this.mChildren.add(childLayer);
-        }
-
-        private void addParent(Layer parentLayer) {
-            this.mParent = parentLayer;
-        }
-
-        public int getId() {
-            return mProto.id;
-        }
-
-        public boolean isActiveBufferEmpty() {
-            return this.mProto.activeBuffer == null || this.mProto.activeBuffer.height == 0
-                    || this.mProto.activeBuffer.width == 0;
-        }
-
-        public boolean isVisibleRegionEmpty() {
-            if (this.mProto.visibleRegion == null) {
-                return true;
-            }
-            Rect visibleRect = Entry.extract(this.mProto.visibleRegion);
-            return visibleRect.height() == 0 || visibleRect.width() == 0;
-        }
-
-        public boolean isHidden() {
-            return (this.mProto.flags & /* FLAG_HIDDEN */ 0x1) != 0x0;
-        }
-
-        public boolean isVisible() {
-            return (!isActiveBufferEmpty() || isColorLayer())
-                    && !isHidden()
-                    && this.mProto.color != null
-                    && this.mProto.color.a > 0
-                    && !isVisibleRegionEmpty();
-        }
-
-        public boolean isColorLayer() {
-            return this.mProto.type.equals("ColorLayer");
-        }
-
-        public boolean isRootLayer() {
-            return mParent == null || mParent.mProto == null;
-        }
-
-        public boolean isInvisible() {
-            return !isVisible();
-        }
-
-        public boolean isHiddenByParent() {
-            return !isRootLayer() && (mParent.isHidden() || mParent.isHiddenByParent());
-        }
-
-        public String getHiddenByParentReason() {
-            String reason = "Layer " + mProto.name;
-            if (isHiddenByParent()) {
-                reason += " is hidden by parent: " + mParent.mProto.name;
-            } else {
-                reason += " is not hidden by parent: " + mParent.mProto.name;
-            }
-            return reason;
-        }
-
-        public String getVisibilityReason() {
-            String reason = "Layer " + mProto.name;
-            if (isVisible()) {
-                reason += " is visible:";
-            } else {
-                reason += " is invisible:";
-                if (this.mProto.activeBuffer == null) {
-                    reason += " activeBuffer=null";
-                } else if (this.mProto.activeBuffer.height == 0) {
-                    reason += " activeBuffer.height=0";
-                } else if (this.mProto.activeBuffer.width == 0) {
-                    reason += " activeBuffer.width=0";
-                }
-                if (!isColorLayer()) {
-                    reason += " type != ColorLayer";
-                }
-                if (isHidden()) {
-                    reason += " flags=" + this.mProto.flags + " (FLAG_HIDDEN set)";
-                }
-                if (this.mProto.color == null || this.mProto.color.a == 0) {
-                    reason += " color.a=0";
-                }
-                if (isVisibleRegionEmpty()) {
-                    reason += " visible region is empty";
-                }
-            }
-            return reason;
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTraceSubject.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTraceSubject.java
deleted file mode 100644
index 4a5129e..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/LayersTraceSubject.java
+++ /dev/null
@@ -1,140 +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.server.wm.flicker;
-
-import static com.google.common.truth.Truth.assertAbout;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import android.graphics.Rect;
-
-import androidx.annotation.Nullable;
-
-import com.android.server.wm.flicker.Assertions.Result;
-import com.android.server.wm.flicker.LayersTrace.Entry;
-import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
-
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Truth subject for {@link LayersTrace} objects.
- */
-public class LayersTraceSubject extends Subject<LayersTraceSubject, LayersTrace> {
-    // Boiler-plate Subject.Factory for LayersTraceSubject
-    private static final Subject.Factory<LayersTraceSubject, LayersTrace> FACTORY =
-            new Subject.Factory<LayersTraceSubject, LayersTrace>() {
-                @Override
-                public LayersTraceSubject createSubject(
-                        FailureMetadata fm, @Nullable LayersTrace target) {
-                    return new LayersTraceSubject(fm, target);
-                }
-            };
-
-    private AssertionsChecker<Entry> mChecker = new AssertionsChecker<>();
-
-    private LayersTraceSubject(FailureMetadata fm, @Nullable LayersTrace subject) {
-        super(fm, subject);
-    }
-
-    // User-defined entry point
-    public static LayersTraceSubject assertThat(@Nullable LayersTrace entry) {
-        return assertAbout(FACTORY).that(entry);
-    }
-
-    // User-defined entry point
-    public static LayersTraceSubject assertThat(@Nullable TransitionResult result) {
-        LayersTrace entries = LayersTrace.parseFrom(result.getLayersTrace(),
-                result.getLayersTracePath());
-        return assertWithMessage(result.toString()).about(FACTORY).that(entries);
-    }
-
-    // Static method for getting the subject factory (for use with assertAbout())
-    public static Subject.Factory<LayersTraceSubject, LayersTrace> entries() {
-        return FACTORY;
-    }
-
-    public void forAllEntries() {
-        test();
-    }
-
-    public void forRange(long startTime, long endTime) {
-        mChecker.filterByRange(startTime, endTime);
-        test();
-    }
-
-    public LayersTraceSubject then() {
-        mChecker.checkChangingAssertions();
-        return this;
-    }
-
-    public void inTheBeginning() {
-        if (getSubject().getEntries().isEmpty()) {
-            fail("No entries found.");
-        }
-        mChecker.checkFirstEntry();
-        test();
-    }
-
-    public void atTheEnd() {
-        if (getSubject().getEntries().isEmpty()) {
-            fail("No entries found.");
-        }
-        mChecker.checkLastEntry();
-        test();
-    }
-
-    private void test() {
-        List<Result> failures = mChecker.test(getSubject().getEntries());
-        if (!failures.isEmpty()) {
-            String failureLogs = failures.stream().map(Result::toString)
-                    .collect(Collectors.joining("\n"));
-            String tracePath = "";
-            if (getSubject().getSource().isPresent()) {
-                tracePath = "\nLayers Trace can be found in: "
-                        + getSubject().getSource().get().toAbsolutePath() + "\n";
-            }
-            fail(tracePath + failureLogs);
-        }
-    }
-
-    public LayersTraceSubject coversRegion(Rect rect) {
-        mChecker.add(entry -> entry.coversRegion(rect),
-                "coversRegion(" + rect + ")");
-        return this;
-    }
-
-    public LayersTraceSubject hasVisibleRegion(String layerName, Rect size) {
-        mChecker.add(entry -> entry.hasVisibleRegion(layerName, size),
-                "hasVisibleRegion(" + layerName + size + ")");
-        return this;
-    }
-
-    public LayersTraceSubject showsLayer(String layerName) {
-        mChecker.add(entry -> entry.isVisible(layerName),
-                "showsLayer(" + layerName + ")");
-        return this;
-    }
-
-    public LayersTraceSubject hidesLayer(String layerName) {
-        mChecker.add(entry -> entry.isVisible(layerName).negate(),
-                "hidesLayer(" + layerName + ")");
-        return this;
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java
deleted file mode 100644
index 241a1c0..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/TransitionRunner.java
+++ /dev/null
@@ -1,433 +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.server.wm.flicker;
-
-import static com.android.server.wm.flicker.monitor.ITransitionMonitor.OUTPUT_DIR;
-
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
-import androidx.test.InstrumentationRegistry;
-
-import com.android.server.wm.flicker.monitor.ITransitionMonitor;
-import com.android.server.wm.flicker.monitor.LayersTraceMonitor;
-import com.android.server.wm.flicker.monitor.ScreenRecorder;
-import com.android.server.wm.flicker.monitor.WindowAnimationFrameStatsMonitor;
-import com.android.server.wm.flicker.monitor.WindowManagerTraceMonitor;
-
-import com.google.common.io.Files;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * Builds and runs UI transitions capturing test artifacts.
- *
- * User can compose a transition from simpler steps, specifying setup and teardown steps. During
- * a transition, Layers trace, WindowManager trace, screen recordings and window animation frame
- * stats can be captured.
- *
- * <pre>
- * Transition builder options:
- *  {@link TransitionBuilder#run(Runnable)} run transition under test. Monitors will be started
- *  before the transition and stopped after the transition is completed.
- *  {@link TransitionBuilder#repeat(int)} repeat transitions under test multiple times recording
- *  result for each run.
- *  {@link TransitionBuilder#withTag(String)} specify a string identifier used to prefix logs and
- *  artifacts generated.
- *  {@link TransitionBuilder#runBeforeAll(Runnable)} run setup transitions once before all other
- *  transition are run to set up an initial state on device.
- *  {@link TransitionBuilder#runBefore(Runnable)} run setup transitions before each test transition
- *  run.
- *  {@link TransitionBuilder#runAfter(Runnable)} run teardown transitions after each test
- *  transition.
- *  {@link TransitionBuilder#runAfter(Runnable)} run teardown transitions once after all
- *  other transition  are run.
- *  {@link TransitionBuilder#includeJankyRuns()} disables {@link WindowAnimationFrameStatsMonitor}
- *  to monitor janky frames. If janky frames are detected, then the test run is skipped. This
- *  monitor is enabled by default.
- *  {@link TransitionBuilder#skipLayersTrace()} disables {@link LayersTraceMonitor} used to
- *  capture Layers trace during a transition. This monitor is enabled by default.
- *  {@link TransitionBuilder#skipWindowManagerTrace()} disables {@link WindowManagerTraceMonitor}
- *  used to capture WindowManager trace during a transition. This monitor is enabled by
- *  default.
- *  {@link TransitionBuilder#recordAllRuns()} records the screen contents and saves it to a file.
- *  All the runs including setup and teardown transitions are included in the recording. This
- *  monitor is used for debugging purposes.
- *  {@link TransitionBuilder#recordEachRun()} records the screen contents during test transitions
- *  and saves it to a file for each run. This monitor is used for debugging purposes.
- *
- * Example transition to capture WindowManager and Layers trace when opening a test app:
- * {@code
- * TransitionRunner.newBuilder()
- *      .withTag("OpenTestAppFast")
- *      .runBeforeAll(UiAutomationLib::wakeUp)
- *      .runBeforeAll(UiAutomationLib::UnlockDevice)
- *      .runBeforeAll(UiAutomationLib::openTestApp)
- *      .runBefore(UiAutomationLib::closeTestApp)
- *      .run(UiAutomationLib::openTestApp)
- *      .runAfterAll(UiAutomationLib::closeTestApp)
- *      .repeat(5)
- *      .build()
- *      .run();
- * }
- * </pre>
- */
-public class TransitionRunner {
-    private static final String TAG = "FLICKER";
-    private final ScreenRecorder mScreenRecorder;
-    private final WindowManagerTraceMonitor mWmTraceMonitor;
-    private final LayersTraceMonitor mLayersTraceMonitor;
-    private final WindowAnimationFrameStatsMonitor mFrameStatsMonitor;
-
-    private final List<ITransitionMonitor> mAllRunsMonitors;
-    private final List<ITransitionMonitor> mPerRunMonitors;
-    private final List<Runnable> mBeforeAlls;
-    private final List<Runnable> mBefores;
-    private final List<Runnable> mTransitions;
-    private final List<Runnable> mAfters;
-    private final List<Runnable> mAfterAlls;
-
-    private final int mIterations;
-    private final String mTestTag;
-
-    @Nullable
-    private List<TransitionResult> mResults = null;
-
-    private TransitionRunner(TransitionBuilder builder) {
-        mScreenRecorder = builder.mScreenRecorder;
-        mWmTraceMonitor = builder.mWmTraceMonitor;
-        mLayersTraceMonitor = builder.mLayersTraceMonitor;
-        mFrameStatsMonitor = builder.mFrameStatsMonitor;
-
-        mAllRunsMonitors = builder.mAllRunsMonitors;
-        mPerRunMonitors = builder.mPerRunMonitors;
-        mBeforeAlls = builder.mBeforeAlls;
-        mBefores = builder.mBefores;
-        mTransitions = builder.mTransitions;
-        mAfters = builder.mAfters;
-        mAfterAlls = builder.mAfterAlls;
-
-        mIterations = builder.mIterations;
-        mTestTag = builder.mTestTag;
-    }
-
-    public static TransitionBuilder newBuilder() {
-        return newBuilder(OUTPUT_DIR.toString());
-    }
-
-    public static TransitionBuilder newBuilder(String outputDir) {
-        return new TransitionBuilder(outputDir);
-    }
-
-    /**
-     * Runs the composed transition and calls monitors at the appropriate stages. If jank monitor
-     * is enabled, transitions with jank are skipped.
-     *
-     * @return itself
-     */
-    public TransitionRunner run() {
-        mResults = new ArrayList<>();
-        mAllRunsMonitors.forEach(ITransitionMonitor::start);
-        mBeforeAlls.forEach(Runnable::run);
-        for (int iteration = 0; iteration < mIterations; iteration++) {
-            mBefores.forEach(Runnable::run);
-            mPerRunMonitors.forEach(ITransitionMonitor::start);
-            mTransitions.forEach(Runnable::run);
-            mPerRunMonitors.forEach(ITransitionMonitor::stop);
-            mAfters.forEach(Runnable::run);
-            if (runJankFree() && mFrameStatsMonitor.jankyFramesDetected()) {
-                String msg = String.format("Skipping iteration %d/%d for test %s due to jank. %s",
-                        iteration, mIterations - 1, mTestTag, mFrameStatsMonitor.toString());
-                Log.e(TAG, msg);
-                continue;
-            }
-            mResults.add(saveResult(iteration));
-        }
-        mAfterAlls.forEach(Runnable::run);
-        mAllRunsMonitors.forEach(monitor -> {
-            monitor.stop();
-            monitor.save(mTestTag);
-        });
-        return this;
-    }
-
-    /**
-     * Returns a list of transition results.
-     *
-     * @return list of transition results.
-     */
-    public List<TransitionResult> getResults() {
-        if (mResults == null) {
-            throw new IllegalStateException("Results do not exist!");
-        }
-        return mResults;
-    }
-
-    /**
-     * Deletes all transition results that are not marked for saving.
-     *
-     * @return list of transition results.
-     */
-    public void deleteResults() {
-        if (mResults == null) {
-            return;
-        }
-        mResults.stream()
-                .filter(TransitionResult::canDelete)
-                .forEach(TransitionResult::delete);
-        mResults = null;
-    }
-
-    /**
-     * Saves monitor results to file.
-     *
-     * @return object containing paths to test artifacts
-     */
-    private TransitionResult saveResult(int iteration) {
-        Path windowTrace = null;
-        Path layerTrace = null;
-        Path screenCaptureVideo = null;
-
-        if (mPerRunMonitors.contains(mWmTraceMonitor)) {
-            windowTrace = mWmTraceMonitor.save(mTestTag, iteration);
-        }
-        if (mPerRunMonitors.contains(mLayersTraceMonitor)) {
-            layerTrace = mLayersTraceMonitor.save(mTestTag, iteration);
-        }
-        if (mPerRunMonitors.contains(mScreenRecorder)) {
-            screenCaptureVideo = mScreenRecorder.save(mTestTag, iteration);
-        }
-        return new TransitionResult(layerTrace, windowTrace, screenCaptureVideo);
-    }
-
-    private boolean runJankFree() {
-        return mPerRunMonitors.contains(mFrameStatsMonitor);
-    }
-
-    public String getTestTag() {
-        return mTestTag;
-    }
-
-    /**
-     * Stores paths to all test artifacts.
-     */
-    @VisibleForTesting
-    public static class TransitionResult {
-        @Nullable
-        public final Path layersTrace;
-        @Nullable
-        public final Path windowManagerTrace;
-        @Nullable
-        public final Path screenCaptureVideo;
-        private boolean flaggedForSaving;
-
-        public TransitionResult(@Nullable Path layersTrace, @Nullable Path windowManagerTrace,
-                @Nullable Path screenCaptureVideo) {
-            this.layersTrace = layersTrace;
-            this.windowManagerTrace = windowManagerTrace;
-            this.screenCaptureVideo = screenCaptureVideo;
-        }
-
-        public void flagForSaving() {
-            flaggedForSaving = true;
-        }
-
-        public boolean canDelete() {
-            return !flaggedForSaving;
-        }
-
-        public boolean layersTraceExists() {
-            return layersTrace != null && layersTrace.toFile().exists();
-        }
-
-        public byte[] getLayersTrace() {
-            try {
-                return Files.toByteArray(this.layersTrace.toFile());
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        public Path getLayersTracePath() {
-            return layersTrace;
-        }
-
-        public boolean windowManagerTraceExists() {
-            return windowManagerTrace != null && windowManagerTrace.toFile().exists();
-        }
-
-        public byte[] getWindowManagerTrace() {
-            try {
-                return Files.toByteArray(this.windowManagerTrace.toFile());
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-        }
-
-        public Path getWindowManagerTracePath() {
-            return windowManagerTrace;
-        }
-
-        public boolean screenCaptureVideoExists() {
-            return screenCaptureVideo != null && screenCaptureVideo.toFile().exists();
-        }
-
-        public Path screenCaptureVideoPath() {
-            return screenCaptureVideo;
-        }
-
-        public void delete() {
-            if (layersTraceExists()) layersTrace.toFile().delete();
-            if (windowManagerTraceExists()) windowManagerTrace.toFile().delete();
-            if (screenCaptureVideoExists()) screenCaptureVideo.toFile().delete();
-        }
-    }
-
-    /**
-     * Builds a {@link TransitionRunner} instance.
-     */
-    public static class TransitionBuilder {
-        private ScreenRecorder mScreenRecorder;
-        private WindowManagerTraceMonitor mWmTraceMonitor;
-        private LayersTraceMonitor mLayersTraceMonitor;
-        private WindowAnimationFrameStatsMonitor mFrameStatsMonitor;
-
-        private List<ITransitionMonitor> mAllRunsMonitors = new LinkedList<>();
-        private List<ITransitionMonitor> mPerRunMonitors = new LinkedList<>();
-        private List<Runnable> mBeforeAlls = new LinkedList<>();
-        private List<Runnable> mBefores = new LinkedList<>();
-        private List<Runnable> mTransitions = new LinkedList<>();
-        private List<Runnable> mAfters = new LinkedList<>();
-        private List<Runnable> mAfterAlls = new LinkedList<>();
-
-        private boolean mRunJankFree = true;
-        private boolean mCaptureWindowManagerTrace = true;
-        private boolean mCaptureLayersTrace = true;
-        private boolean mRecordEachRun = false;
-        private int mIterations = 1;
-        private String mTestTag = "";
-
-        private boolean mRecordAllRuns = false;
-
-        public TransitionBuilder(String outputDir) {
-            mScreenRecorder = new ScreenRecorder();
-            mWmTraceMonitor = new WindowManagerTraceMonitor(outputDir);
-            mLayersTraceMonitor = new LayersTraceMonitor(outputDir);
-            mFrameStatsMonitor = new
-                    WindowAnimationFrameStatsMonitor(InstrumentationRegistry.getInstrumentation());
-        }
-
-        public TransitionRunner build() {
-            if (mCaptureWindowManagerTrace) {
-                mPerRunMonitors.add(mWmTraceMonitor);
-            }
-
-            if (mCaptureLayersTrace) {
-                mPerRunMonitors.add(mLayersTraceMonitor);
-            }
-
-            if (mRunJankFree) {
-                mPerRunMonitors.add(mFrameStatsMonitor);
-            }
-
-            if (mRecordAllRuns) {
-                mAllRunsMonitors.add(mScreenRecorder);
-            }
-
-            if (mRecordEachRun) {
-                mPerRunMonitors.add(mScreenRecorder);
-            }
-
-            return new TransitionRunner(this);
-        }
-
-        public TransitionBuilder runBeforeAll(Runnable runnable) {
-            mBeforeAlls.add(runnable);
-            return this;
-        }
-
-        public TransitionBuilder runBefore(Runnable runnable) {
-            mBefores.add(runnable);
-            return this;
-        }
-
-        public TransitionBuilder run(Runnable runnable) {
-            mTransitions.add(runnable);
-            return this;
-        }
-
-        public TransitionBuilder runAfter(Runnable runnable) {
-            mAfters.add(runnable);
-            return this;
-        }
-
-        public TransitionBuilder runAfterAll(Runnable runnable) {
-            mAfterAlls.add(runnable);
-            return this;
-        }
-
-        public TransitionBuilder repeat(int iterations) {
-            mIterations = iterations;
-            return this;
-        }
-
-        public TransitionBuilder skipWindowManagerTrace() {
-            mCaptureWindowManagerTrace = false;
-            return this;
-        }
-
-        public TransitionBuilder skipLayersTrace() {
-            mCaptureLayersTrace = false;
-            return this;
-        }
-
-        public TransitionBuilder includeJankyRuns() {
-            mRunJankFree = false;
-            return this;
-        }
-
-        public TransitionBuilder recordEachRun() {
-            if (mRecordAllRuns) {
-                throw new IllegalArgumentException("Invalid option with recordAllRuns");
-            }
-            mRecordEachRun = true;
-            return this;
-        }
-
-        public TransitionBuilder recordAllRuns() {
-            if (mRecordEachRun) {
-                throw new IllegalArgumentException("Invalid option with recordEachRun");
-            }
-            mRecordAllRuns = true;
-            return this;
-        }
-
-        public TransitionBuilder withTag(String testTag) {
-            if (testTag.contains(" ")) {
-                throw new IllegalArgumentException("The test tag can not contain spaces since it "
-                        + "is a part of the file name");
-            }
-            mTestTag = testTag;
-            return this;
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowManagerTrace.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowManagerTrace.java
deleted file mode 100644
index 412e72d8..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowManagerTrace.java
+++ /dev/null
@@ -1,240 +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.server.wm.flicker;
-
-import androidx.annotation.Nullable;
-
-import com.android.server.wm.flicker.Assertions.Result;
-import com.android.server.wm.nano.AppWindowTokenProto;
-import com.android.server.wm.nano.StackProto;
-import com.android.server.wm.nano.TaskProto;
-import com.android.server.wm.nano.WindowManagerTraceFileProto;
-import com.android.server.wm.nano.WindowManagerTraceProto;
-import com.android.server.wm.nano.WindowStateProto;
-import com.android.server.wm.nano.WindowTokenProto;
-
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-
-/**
- * Contains a collection of parsed WindowManager trace entries and assertions to apply over
- * a single entry.
- *
- * Each entry is parsed into a list of {@link WindowManagerTrace.Entry} objects.
- */
-public class WindowManagerTrace {
-    private static final int DEFAULT_DISPLAY = 0;
-    private final List<Entry> mEntries;
-    @Nullable
-    final private Path mSource;
-
-    private WindowManagerTrace(List<Entry> entries, Path source) {
-        this.mEntries = entries;
-        this.mSource = source;
-    }
-
-    /**
-     * Parses {@code WindowManagerTraceFileProto} from {@code data} and uses the proto to
-     * generates a list of trace entries.
-     *
-     * @param data   binary proto data
-     * @param source Path to source of data for additional debug information
-     */
-    public static WindowManagerTrace parseFrom(byte[] data, Path source) {
-        List<Entry> entries = new ArrayList<>();
-
-        WindowManagerTraceFileProto fileProto;
-        try {
-            fileProto = WindowManagerTraceFileProto.parseFrom(data);
-        } catch (InvalidProtocolBufferNanoException e) {
-            throw new RuntimeException(e);
-        }
-        for (WindowManagerTraceProto entryProto : fileProto.entry) {
-            entries.add(new Entry(entryProto));
-        }
-        return new WindowManagerTrace(entries, source);
-    }
-
-    public static WindowManagerTrace parseFrom(byte[] data) {
-        return parseFrom(data, null);
-    }
-
-    public List<Entry> getEntries() {
-        return mEntries;
-    }
-
-    public Entry getEntry(long timestamp) {
-        Optional<Entry> entry = mEntries.stream()
-                .filter(e -> e.getTimestamp() == timestamp)
-                .findFirst();
-        if (!entry.isPresent()) {
-            throw new RuntimeException("Entry does not exist for timestamp " + timestamp);
-        }
-        return entry.get();
-    }
-
-    public Optional<Path> getSource() {
-        return Optional.ofNullable(mSource);
-    }
-
-    /**
-     * Represents a single WindowManager trace entry.
-     */
-    public static class Entry implements ITraceEntry {
-        private final WindowManagerTraceProto mProto;
-
-        public Entry(WindowManagerTraceProto proto) {
-            mProto = proto;
-        }
-
-        private static Result isWindowVisible(String windowTitle,
-                WindowTokenProto[] windowTokenProtos) {
-            boolean titleFound = false;
-            for (WindowTokenProto windowToken : windowTokenProtos) {
-                for (WindowStateProto windowState : windowToken.windows) {
-                    if (windowState.identifier.title.contains(windowTitle)) {
-                        titleFound = true;
-                        if (isVisible(windowState)) {
-                            return new Result(true /* success */,
-                                    windowState.identifier.title + " is visible");
-                        }
-                    }
-                }
-            }
-
-            String reason;
-            if (!titleFound) {
-                reason = windowTitle + " cannot be found";
-            } else {
-                reason = windowTitle + " is invisible";
-            }
-            return new Result(false /* success */, reason);
-        }
-
-        private static boolean isVisible(WindowStateProto windowState) {
-            return windowState.windowContainer.visible;
-        }
-
-        @Override
-        public long getTimestamp() {
-            return mProto.elapsedRealtimeNanos;
-        }
-
-        /**
-         * Returns window title of the top most visible app window.
-         */
-        private String getTopVisibleAppWindow() {
-            StackProto[] stacks = mProto.windowManagerService.rootWindowContainer
-                    .displays[DEFAULT_DISPLAY].stacks;
-            for (StackProto stack : stacks) {
-                for (TaskProto task : stack.tasks) {
-                    for (AppWindowTokenProto token : task.appWindowTokens) {
-                        for (WindowStateProto windowState : token.windowToken.windows) {
-                            if (windowState.windowContainer.visible) {
-                                return task.appWindowTokens[0].name;
-                            }
-                        }
-                    }
-                }
-            }
-
-            return "";
-        }
-
-        /**
-         * Checks if aboveAppWindow with {@code windowTitle} is visible.
-         */
-        public Result isAboveAppWindowVisible(String windowTitle) {
-            WindowTokenProto[] windowTokenProtos = mProto.windowManagerService
-                    .rootWindowContainer
-                    .displays[DEFAULT_DISPLAY].aboveAppWindows;
-            Result result = isWindowVisible(windowTitle, windowTokenProtos);
-            return new Result(result.success, getTimestamp(), "showsAboveAppWindow", result.reason);
-        }
-
-        /**
-         * Checks if belowAppWindow with {@code windowTitle} is visible.
-         */
-        public Result isBelowAppWindowVisible(String windowTitle) {
-            WindowTokenProto[] windowTokenProtos = mProto.windowManagerService
-                    .rootWindowContainer
-                    .displays[DEFAULT_DISPLAY].belowAppWindows;
-            Result result = isWindowVisible(windowTitle, windowTokenProtos);
-            return new Result(result.success, getTimestamp(), "isBelowAppWindowVisible",
-                    result.reason);
-        }
-
-        /**
-         * Checks if imeWindow with {@code windowTitle} is visible.
-         */
-        public Result isImeWindowVisible(String windowTitle) {
-            WindowTokenProto[] windowTokenProtos = mProto.windowManagerService
-                    .rootWindowContainer
-                    .displays[DEFAULT_DISPLAY].imeWindows;
-            Result result = isWindowVisible(windowTitle, windowTokenProtos);
-            return new Result(result.success, getTimestamp(), "isImeWindowVisible",
-                    result.reason);
-        }
-
-        /**
-         * Checks if app window with {@code windowTitle} is on top.
-         */
-        public Result isVisibleAppWindowOnTop(String windowTitle) {
-            String topAppWindow = getTopVisibleAppWindow();
-            boolean success = topAppWindow.contains(windowTitle);
-            String reason = "wanted=" + windowTitle + " found=" + topAppWindow;
-            return new Result(success, getTimestamp(), "isAppWindowOnTop", reason);
-        }
-
-        /**
-         * Checks if app window with {@code windowTitle} is visible.
-         */
-        public Result isAppWindowVisible(String windowTitle) {
-            final String assertionName = "isAppWindowVisible";
-            boolean titleFound = false;
-            StackProto[] stacks = mProto.windowManagerService.rootWindowContainer
-                    .displays[DEFAULT_DISPLAY].stacks;
-            for (StackProto stack : stacks) {
-                for (TaskProto task : stack.tasks) {
-                    for (AppWindowTokenProto token : task.appWindowTokens) {
-                        if (token.name.contains(windowTitle)) {
-                            titleFound = true;
-                            for (WindowStateProto windowState : token.windowToken.windows) {
-                                if (windowState.windowContainer.visible) {
-                                    return new Result(true /* success */, getTimestamp(),
-                                            assertionName, "Window " + token.name +
-                                            "is visible");
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-            String reason;
-            if (!titleFound) {
-                reason = "Window " + windowTitle + " cannot be found";
-            } else {
-                reason = "Window " + windowTitle + " is invisible";
-            }
-            return new Result(false /* success */, getTimestamp(), assertionName, reason);
-        }
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java
deleted file mode 100644
index 3d25fbe..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WindowUtils.java
+++ /dev/null
@@ -1,144 +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.server.wm.flicker;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import androidx.test.InstrumentationRegistry;
-
-/**
- * Helper functions to retrieve system window sizes and positions.
- */
-public class WindowUtils {
-
-    public static Rect getDisplayBounds() {
-        Point display = new Point();
-        WindowManager wm =
-                (WindowManager) InstrumentationRegistry.getContext().getSystemService(
-                        Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getRealSize(display);
-        return new Rect(0, 0, display.x, display.y);
-    }
-
-    private static int getCurrentRotation() {
-        WindowManager wm =
-                (WindowManager) InstrumentationRegistry.getContext().getSystemService(
-                        Context.WINDOW_SERVICE);
-        return wm.getDefaultDisplay().getRotation();
-    }
-
-    public static Rect getDisplayBounds(int requestedRotation) {
-        Rect displayBounds = getDisplayBounds();
-        int currentDisplayRotation = getCurrentRotation();
-
-        boolean displayIsRotated = (currentDisplayRotation == Surface.ROTATION_90 ||
-                currentDisplayRotation == Surface.ROTATION_270);
-
-        boolean requestedDisplayIsRotated = requestedRotation == Surface.ROTATION_90 ||
-                requestedRotation == Surface.ROTATION_270;
-
-        // if the current orientation changes with the requested rotation,
-        // flip height and width of display bounds.
-        if (displayIsRotated != requestedDisplayIsRotated) {
-            return new Rect(0, 0, displayBounds.height(), displayBounds.width());
-        }
-
-        return new Rect(0, 0, displayBounds.width(), displayBounds.height());
-    }
-
-
-    public static Rect getAppPosition(int requestedRotation) {
-        Rect displayBounds = getDisplayBounds();
-        int currentDisplayRotation = getCurrentRotation();
-
-        boolean displayIsRotated = currentDisplayRotation == Surface.ROTATION_90 ||
-                currentDisplayRotation == Surface.ROTATION_270;
-
-        boolean requestedAppIsRotated = requestedRotation == Surface.ROTATION_90 ||
-                requestedRotation == Surface.ROTATION_270;
-
-        // display size will change if the display is reflected. Flip height and width of app if the
-        // requested rotation is different from the current rotation.
-        if (displayIsRotated != requestedAppIsRotated) {
-            return new Rect(0, 0, displayBounds.height(), displayBounds.width());
-        }
-
-        return new Rect(0, 0, displayBounds.width(), displayBounds.height());
-    }
-
-    public static Rect getStatusBarPosition(int requestedRotation) {
-        Resources resources = InstrumentationRegistry.getContext().getResources();
-        String resourceName;
-        Rect displayBounds = getDisplayBounds();
-        int width;
-        if (requestedRotation == Surface.ROTATION_0 || requestedRotation == Surface.ROTATION_180) {
-            resourceName = "status_bar_height_portrait";
-            width = Math.min(displayBounds.width(), displayBounds.height());
-        } else {
-            resourceName = "status_bar_height_landscape";
-            width = Math.max(displayBounds.width(), displayBounds.height());
-        }
-
-        int resourceId = resources.getIdentifier(resourceName, "dimen", "android");
-        int height = resources.getDimensionPixelSize(resourceId);
-
-        return new Rect(0, 0, width, height);
-    }
-
-    public static Rect getNavigationBarPosition(int requestedRotation) {
-        Resources resources = InstrumentationRegistry.getContext().getResources();
-        Rect displayBounds = getDisplayBounds();
-        int displayWidth = Math.min(displayBounds.width(), displayBounds.height());
-        int displayHeight = Math.max(displayBounds.width(), displayBounds.height());
-        int resourceId;
-        if (requestedRotation == Surface.ROTATION_0 || requestedRotation == Surface.ROTATION_180) {
-            resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
-            int height = resources.getDimensionPixelSize(resourceId);
-            return new Rect(0, displayHeight - height, displayWidth, displayHeight);
-        } else {
-            resourceId = resources.getIdentifier("navigation_bar_width", "dimen", "android");
-            int width = resources.getDimensionPixelSize(resourceId);
-            // swap display dimensions in landscape or seascape mode
-            int temp = displayHeight;
-            displayHeight = displayWidth;
-            displayWidth = temp;
-            if (requestedRotation == Surface.ROTATION_90) {
-                return new Rect(0, 0, width, displayHeight);
-            } else {
-                return new Rect(displayWidth - width, 0, displayWidth, displayHeight);
-            }
-        }
-    }
-
-    public static int getNavigationBarHeight() {
-        Resources resources = InstrumentationRegistry.getContext().getResources();
-        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
-        return resources.getDimensionPixelSize(resourceId);
-    }
-
-    public static int getDockedStackDividerInset() {
-        Resources resources = InstrumentationRegistry.getContext().getResources();
-        int resourceId = resources.getIdentifier("docked_stack_divider_insets", "dimen",
-                "android");
-        return resources.getDimensionPixelSize(resourceId);
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WmTraceSubject.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WmTraceSubject.java
deleted file mode 100644
index 064cc27..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/WmTraceSubject.java
+++ /dev/null
@@ -1,192 +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.server.wm.flicker;
-
-import static com.google.common.truth.Truth.assertAbout;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import androidx.annotation.Nullable;
-
-import com.android.server.wm.flicker.Assertions.Result;
-import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
-
-import com.google.common.truth.FailureMetadata;
-import com.google.common.truth.Subject;
-
-import java.nio.file.Path;
-import java.util.List;
-import java.util.Optional;
-import java.util.stream.Collectors;
-
-/**
- * Truth subject for {@link WindowManagerTrace} objects.
- */
-public class WmTraceSubject extends Subject<WmTraceSubject, WindowManagerTrace> {
-    // Boiler-plate Subject.Factory for WmTraceSubject
-    private static final Subject.Factory<WmTraceSubject, WindowManagerTrace> FACTORY =
-            new Subject.Factory<WmTraceSubject, WindowManagerTrace>() {
-                @Override
-                public WmTraceSubject createSubject(
-                        FailureMetadata fm, @Nullable WindowManagerTrace target) {
-                    return new WmTraceSubject(fm, target);
-                }
-            };
-
-    private AssertionsChecker<WindowManagerTrace.Entry> mChecker = new AssertionsChecker<>();
-
-    private WmTraceSubject(FailureMetadata fm, @Nullable WindowManagerTrace subject) {
-        super(fm, subject);
-    }
-
-    // User-defined entry point
-    public static WmTraceSubject assertThat(@Nullable WindowManagerTrace entry) {
-        return assertAbout(FACTORY).that(entry);
-    }
-
-    // User-defined entry point
-    public static WmTraceSubject assertThat(@Nullable TransitionResult result) {
-        WindowManagerTrace entries = WindowManagerTrace.parseFrom(result.getWindowManagerTrace(),
-                result.getWindowManagerTracePath());
-        return assertWithMessage(result.toString()).about(FACTORY).that(entries);
-    }
-
-    // Static method for getting the subject factory (for use with assertAbout())
-    public static Subject.Factory<WmTraceSubject, WindowManagerTrace> entries() {
-        return FACTORY;
-    }
-
-    public void forAllEntries() {
-        test();
-    }
-
-    public void forRange(long startTime, long endTime) {
-        mChecker.filterByRange(startTime, endTime);
-        test();
-    }
-
-    public WmTraceSubject then() {
-        mChecker.checkChangingAssertions();
-        return this;
-    }
-
-    public void inTheBeginning() {
-        if (getSubject().getEntries().isEmpty()) {
-            fail("No entries found.");
-        }
-        mChecker.checkFirstEntry();
-        test();
-    }
-
-    public void atTheEnd() {
-        if (getSubject().getEntries().isEmpty()) {
-            fail("No entries found.");
-        }
-        mChecker.checkLastEntry();
-        test();
-    }
-
-    private void test() {
-        List<Result> failures = mChecker.test(getSubject().getEntries());
-        if (!failures.isEmpty()) {
-            Optional<Path> failureTracePath = getSubject().getSource();
-            String failureLogs = failures.stream().map(Result::toString)
-                    .collect(Collectors.joining("\n"));
-            String tracePath = "";
-            if (failureTracePath.isPresent()) {
-                tracePath = "\nWindowManager Trace can be found in: "
-                        + failureTracePath.get().toAbsolutePath() + "\n";
-            }
-            fail(tracePath + failureLogs);
-        }
-    }
-
-    public WmTraceSubject showsAboveAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isAboveAppWindowVisible(partialWindowTitle),
-                "showsAboveAppWindow(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject hidesAboveAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isAboveAppWindowVisible(partialWindowTitle).negate(),
-                "hidesAboveAppWindow" + "(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject showsBelowAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isBelowAppWindowVisible(partialWindowTitle),
-                "showsBelowAppWindow(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject hidesBelowAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isBelowAppWindowVisible(partialWindowTitle).negate(),
-                "hidesBelowAppWindow" + "(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject showsImeWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isImeWindowVisible(partialWindowTitle),
-                "showsBelowAppWindow(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject hidesImeWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isImeWindowVisible(partialWindowTitle).negate(),
-                "hidesImeWindow" + "(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject showsAppWindowOnTop(String partialWindowTitle) {
-        mChecker.add(
-                entry -> {
-                    Result result = entry.isAppWindowVisible(partialWindowTitle);
-                    if (result.passed()) {
-                        result = entry.isVisibleAppWindowOnTop(partialWindowTitle);
-                    }
-                    return result;
-                },
-                "showsAppWindowOnTop(" + partialWindowTitle + ")"
-        );
-        return this;
-    }
-
-    public WmTraceSubject hidesAppWindowOnTop(String partialWindowTitle) {
-        mChecker.add(
-                entry -> {
-                    Result result = entry.isAppWindowVisible(partialWindowTitle).negate();
-                    if (result.failed()) {
-                        result = entry.isVisibleAppWindowOnTop(partialWindowTitle).negate();
-                    }
-                    return result;
-                },
-                "hidesAppWindowOnTop(" + partialWindowTitle + ")"
-        );
-        return this;
-    }
-
-    public WmTraceSubject showsAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isAppWindowVisible(partialWindowTitle),
-                "showsAppWindow(" + partialWindowTitle + ")");
-        return this;
-    }
-
-    public WmTraceSubject hidesAppWindow(String partialWindowTitle) {
-        mChecker.add(entry -> entry.isAppWindowVisible(partialWindowTitle).negate(),
-                "hidesAppWindow(" + partialWindowTitle + ")");
-        return this;
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/helpers/AutomationUtils.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/helpers/AutomationUtils.java
deleted file mode 100644
index 6821ff0..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/helpers/AutomationUtils.java
+++ /dev/null
@@ -1,263 +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.server.wm.flicker.helpers;
-
-import static android.os.SystemClock.sleep;
-import static android.system.helpers.OverviewHelper.isRecentsInLauncher;
-import static android.view.Surface.ROTATION_0;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.os.RemoteException;
-import android.support.test.launcherhelper.LauncherStrategyFactory;
-import android.support.test.uiautomator.By;
-import android.support.test.uiautomator.BySelector;
-import android.support.test.uiautomator.Configurator;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject2;
-import android.support.test.uiautomator.Until;
-import android.util.Log;
-import android.util.Rational;
-import android.view.View;
-import android.view.ViewConfiguration;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.server.wm.flicker.WindowUtils;
-
-/**
- * Collection of UI Automation helper functions.
- */
-public class AutomationUtils {
-    private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
-    private static final long FIND_TIMEOUT = 10000;
-    private static final long LONG_PRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout() * 2L;
-    private static final String TAG = "FLICKER";
-
-    public static void wakeUpAndGoToHomeScreen() {
-        UiDevice device = UiDevice.getInstance(InstrumentationRegistry
-                .getInstrumentation());
-        try {
-            device.wakeUp();
-        } catch (RemoteException e) {
-            throw new RuntimeException(e);
-        }
-        device.pressHome();
-    }
-
-    /**
-     * Sets {@link android.app.UiAutomation#waitForIdle(long, long)} global timeout to 0 causing
-     * the {@link android.app.UiAutomation#waitForIdle(long, long)} function to timeout instantly.
-     * This removes some delays when using the UIAutomator library required to create fast UI
-     * transitions.
-     */
-    public static void setFastWait() {
-        Configurator.getInstance().setWaitForIdleTimeout(0);
-    }
-
-    /**
-     * Reverts {@link android.app.UiAutomation#waitForIdle(long, long)} to default behavior.
-     */
-    public static void setDefaultWait() {
-        Configurator.getInstance().setWaitForIdleTimeout(10000);
-    }
-
-    public static boolean isQuickstepEnabled(UiDevice device) {
-        return device.findObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")) == null;
-    }
-
-    public static void openQuickstep(UiDevice device) {
-        if (isQuickstepEnabled(device)) {
-            int height = device.getDisplayHeight();
-            UiObject2 navBar = device.findObject(By.res(SYSTEMUI_PACKAGE, "navigation_bar_frame"));
-
-            Rect navBarVisibleBounds;
-
-            // TODO(vishnun) investigate why this object cannot be found.
-            if (navBar != null) {
-                navBarVisibleBounds = navBar.getVisibleBounds();
-            } else {
-                Log.e(TAG, "Could not find nav bar, infer location");
-                navBarVisibleBounds = WindowUtils.getNavigationBarPosition(ROTATION_0);
-            }
-
-            // Swipe from nav bar to 2/3rd down the screen.
-            device.swipe(
-                    navBarVisibleBounds.centerX(), navBarVisibleBounds.centerY(),
-                    navBarVisibleBounds.centerX(), height * 2 / 3,
-                    (navBarVisibleBounds.centerY() - height * 2 / 3) / 100); // 100 px/step
-        } else {
-            try {
-                device.pressRecentApps();
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
-        }
-        BySelector RECENTS = By.res(SYSTEMUI_PACKAGE, "recents_view");
-
-        // use a long timeout to wait until recents populated
-        if (device.wait(
-                Until.findObject(isRecentsInLauncher()
-                        ? getLauncherOverviewSelector(device) : RECENTS),
-                10000) == null) {
-            fail("Recents didn't appear");
-        }
-        device.waitForIdle();
-    }
-
-    public static void clearRecents(UiDevice device) {
-        if (isQuickstepEnabled(device)) {
-            openQuickstep(device);
-
-            for (int i = 0; i < 5; i++) {
-                device.swipe(device.getDisplayWidth() / 2,
-                        device.getDisplayHeight() / 2, device.getDisplayWidth(),
-                        device.getDisplayHeight() / 2,
-                        5);
-
-                BySelector clearAllSelector = By.res("com.google.android.apps.nexuslauncher",
-                        "clear_all_button");
-                UiObject2 clearAllButton = device.wait(Until.findObject(clearAllSelector), 100);
-                if (clearAllButton != null) {
-                    clearAllButton.click();
-                    return;
-                }
-            }
-        }
-    }
-
-    private static BySelector getLauncherOverviewSelector(UiDevice device) {
-        return By.res(device.getLauncherPackageName(), "overview_panel");
-    }
-
-    private static void longPressRecents(UiDevice device) {
-        BySelector recentsSelector = By.res(SYSTEMUI_PACKAGE, "recent_apps");
-        UiObject2 recentsButton = device.wait(Until.findObject(recentsSelector), FIND_TIMEOUT);
-        assertNotNull("Unable to find recents button", recentsButton);
-        recentsButton.click(LONG_PRESS_TIMEOUT);
-    }
-
-    public static void launchSplitScreen(UiDevice device) {
-        String mLauncherPackage = LauncherStrategyFactory.getInstance(device)
-                .getLauncherStrategy().getSupportedLauncherPackage();
-
-        if (isQuickstepEnabled(device)) {
-            // Quickstep enabled
-            openQuickstep(device);
-
-            BySelector overviewIconSelector = By.res(mLauncherPackage, "icon")
-                    .clazz(View.class);
-            UiObject2 overviewIcon = device.wait(Until.findObject(overviewIconSelector),
-                    FIND_TIMEOUT);
-            assertNotNull("Unable to find app icon in Overview", overviewIcon);
-            overviewIcon.click();
-
-            BySelector splitscreenButtonSelector = By.text("Split screen");
-            UiObject2 splitscreenButton = device.wait(Until.findObject(splitscreenButtonSelector),
-                    FIND_TIMEOUT);
-            assertNotNull("Unable to find Split screen button in Overview", splitscreenButton);
-            splitscreenButton.click();
-        } else {
-            // Classic long press recents
-            longPressRecents(device);
-        }
-        // Wait for animation to complete.
-        sleep(2000);
-    }
-
-    public static void exitSplitScreen(UiDevice device) {
-        if (isQuickstepEnabled(device)) {
-            // Quickstep enabled
-            BySelector dividerSelector = By.res(SYSTEMUI_PACKAGE, "docked_divider_handle");
-            UiObject2 divider = device.wait(Until.findObject(dividerSelector), FIND_TIMEOUT);
-            assertNotNull("Unable to find Split screen divider", divider);
-
-            // Drag the split screen divider to the top of the screen
-            divider.drag(new Point(device.getDisplayWidth() / 2, 0), 400);
-        } else {
-            // Classic long press recents
-            longPressRecents(device);
-        }
-        // Wait for animation to complete.
-        sleep(2000);
-    }
-
-    public static void resizeSplitScreen(UiDevice device, Rational windowHeightRatio) {
-        BySelector dividerSelector = By.res(SYSTEMUI_PACKAGE, "docked_divider_handle");
-        UiObject2 divider = device.wait(Until.findObject(dividerSelector), FIND_TIMEOUT);
-        assertNotNull("Unable to find Split screen divider", divider);
-        int destHeight =
-                (int) (WindowUtils.getDisplayBounds().height() * windowHeightRatio.floatValue());
-        // Drag the split screen divider to so that the ratio of top window height and bottom
-        // window height is windowHeightRatio
-        device.drag(divider.getVisibleBounds().centerX(), divider.getVisibleBounds().centerY(),
-                device.getDisplayWidth() / 2, destHeight, 10);
-        //divider.drag(new Point(device.getDisplayWidth() / 2, destHeight), 400)
-        divider = device.wait(Until.findObject(dividerSelector), FIND_TIMEOUT);
-
-        // Wait for animation to complete.
-        sleep(2000);
-    }
-
-    public static void closePipWindow(UiDevice device) {
-        UiObject2 pipWindow = device.findObject(
-                By.res(SYSTEMUI_PACKAGE, "background"));
-        pipWindow.click();
-        UiObject2 exitPipObject = device.findObject(
-                By.res(SYSTEMUI_PACKAGE, "dismiss"));
-        exitPipObject.click();
-        // Wait for animation to complete.
-        sleep(2000);
-    }
-
-    public static void expandPipWindow(UiDevice device) {
-        UiObject2 pipWindow = device.findObject(
-                By.res(SYSTEMUI_PACKAGE, "background"));
-        pipWindow.click();
-        pipWindow.click();
-    }
-
-    public static void stopPackage(Context context, String packageName) {
-        runShellCommand("am force-stop " + packageName);
-        int packageUid;
-        try {
-            packageUid = context.getPackageManager().getPackageUid(packageName, /* flags= */0);
-        } catch (PackageManager.NameNotFoundException e) {
-            return;
-        }
-        while (targetPackageIsRunning(packageUid)) {
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                //ignore
-            }
-        }
-    }
-
-    private static boolean targetPackageIsRunning(int uid) {
-        final String result = runShellCommand(
-                String.format("cmd activity get-uid-state %d", uid));
-        return !result.contains("(NONEXISTENT)");
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ITransitionMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ITransitionMonitor.java
deleted file mode 100644
index 67e0ecc..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ITransitionMonitor.java
+++ /dev/null
@@ -1,63 +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.server.wm.flicker.monitor;
-
-import android.os.Environment;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-/**
- * Collects test artifacts during a UI transition.
- */
-public interface ITransitionMonitor {
-    Path OUTPUT_DIR = Paths.get(Environment.getExternalStorageDirectory().toString(), "flicker");
-
-    /**
-     * Starts monitor.
-     */
-    void start();
-
-    /**
-     * Stops monitor.
-     */
-    void stop();
-
-    /**
-     * Saves any monitor artifacts to file adding {@code testTag} and {@code iteration}
-     * to the file name.
-     *
-     * @param testTag   suffix added to artifact name
-     * @param iteration suffix added to artifact name
-     *
-     * @return Path to saved artifact
-     */
-    default Path save(String testTag, int iteration) {
-        return save(testTag + "_" + iteration);
-    }
-
-    /**
-     * Saves any monitor artifacts to file adding {@code testTag} to the file name.
-     *
-     * @param testTag suffix added to artifact name
-     *
-     * @return Path to saved artifact
-     */
-    default Path save(String testTag) {
-        throw new UnsupportedOperationException("Save not implemented for this monitor");
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/LayersTraceMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/LayersTraceMonitor.java
deleted file mode 100644
index da75b3e..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/LayersTraceMonitor.java
+++ /dev/null
@@ -1,64 +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.server.wm.flicker.monitor;
-
-import android.os.RemoteException;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
-
-/**
- * Captures Layers trace from SurfaceFlinger.
- */
-public class LayersTraceMonitor extends TraceMonitor {
-    private IWindowManager mWm = WindowManagerGlobal.getWindowManagerService();
-
-    public LayersTraceMonitor() {
-        this(OUTPUT_DIR.toString());
-    }
-
-    public LayersTraceMonitor(String outputDir) {
-        super(outputDir, "layers_trace.pb");
-    }
-
-    @Override
-    public void start() {
-        setEnabled(true);
-    }
-
-    @Override
-    public void stop() {
-        setEnabled(false);
-    }
-
-    @Override
-    public boolean isEnabled() throws RemoteException {
-        try {
-            return mWm.isLayerTracing();
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-        return false;
-    }
-
-    private void setEnabled(boolean isEnabled) {
-        try {
-            mWm.setLayerTracing(isEnabled);
-        } catch (RemoteException e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ScreenRecorder.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ScreenRecorder.java
deleted file mode 100644
index dce1c27..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/ScreenRecorder.java
+++ /dev/null
@@ -1,80 +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.server.wm.flicker.monitor;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-
-import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-/**
- * Captures screen contents and saves it as a mp4 video file.
- */
-public class ScreenRecorder implements ITransitionMonitor {
-    @VisibleForTesting
-    public static final Path DEFAULT_OUTPUT_PATH = OUTPUT_DIR.resolve("transition.mp4");
-    private static final String TAG = "FLICKER";
-    private Thread recorderThread;
-
-    @VisibleForTesting
-    public static Path getPath(String testTag) {
-        return OUTPUT_DIR.resolve(testTag + ".mp4");
-    }
-
-    @Override
-    public void start() {
-        OUTPUT_DIR.toFile().mkdirs();
-        String command = "screenrecord " + DEFAULT_OUTPUT_PATH;
-        recorderThread = new Thread(() -> {
-            try {
-                Runtime.getRuntime().exec(command);
-            } catch (IOException e) {
-                Log.e(TAG, "Error executing " + command, e);
-            }
-        });
-        recorderThread.start();
-    }
-
-    @Override
-    public void stop() {
-        runShellCommand("killall -s 2 screenrecord");
-        try {
-            recorderThread.join();
-        } catch (InterruptedException e) {
-            // ignore
-        }
-    }
-
-    @Override
-    public Path save(String testTag) {
-        try {
-            Path targetPath = Files.move(DEFAULT_OUTPUT_PATH, getPath(testTag),
-                    REPLACE_EXISTING);
-            Log.i(TAG, "Video saved to " + targetPath.toString());
-            return targetPath;
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/TraceMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/TraceMonitor.java
deleted file mode 100644
index 1ba36bb..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/TraceMonitor.java
+++ /dev/null
@@ -1,74 +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.server.wm.flicker.monitor;
-
-import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
-
-import android.os.RemoteException;
-
-import androidx.annotation.VisibleForTesting;
-
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Locale;
-
-/**
- * Base class for monitors containing common logic to read the trace
- * as a byte array and save the trace to another location.
- */
-public abstract class TraceMonitor implements ITransitionMonitor {
-    public static final String TAG = "FLICKER";
-    private static final String TRACE_DIR = "/data/misc/wmtrace/";
-
-    private Path mOutputDir;
-    public String mTraceFileName;
-
-    public abstract boolean isEnabled() throws RemoteException;
-
-    public TraceMonitor(String outputDir, String traceFileName) {
-        mOutputDir = Paths.get(outputDir);
-        mTraceFileName = traceFileName;
-    }
-
-    /**
-     * Saves trace file to the external storage directory suffixing the name with the testtag
-     * and iteration.
-     *
-     * Moves the trace file from the default location via a shell command since the test app
-     * does not have security privileges to access /data/misc/wmtrace.
-     *
-     * @param testTag suffix added to trace name used to identify trace
-     *
-     * @return Path to saved trace file
-     */
-    @Override
-    public Path save(String testTag) {
-        OUTPUT_DIR.toFile().mkdirs();
-        Path traceFileCopy = getOutputTraceFilePath(testTag);
-
-        // Read the input stream fully.
-        String copyCommand = String.format(Locale.getDefault(), "mv %s%s %s", TRACE_DIR,
-                mTraceFileName, traceFileCopy.toString());
-        runShellCommand(copyCommand);
-        return traceFileCopy;
-    }
-
-    @VisibleForTesting
-    public Path getOutputTraceFilePath(String testTag) {
-        return mOutputDir.resolve(mTraceFileName + "_" + testTag);
-    }
-}
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java
deleted file mode 100644
index 3f86f0d..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitor.java
+++ /dev/null
@@ -1,100 +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.server.wm.flicker.monitor;
-
-import static android.view.FrameStats.UNDEFINED_TIME_NANO;
-
-import android.app.Instrumentation;
-import android.util.Log;
-import android.view.FrameStats;
-
-/**
- * Monitors {@link android.view.WindowAnimationFrameStats} to detect janky frames.
- *
- * Adapted from {@link androidx.test.jank.internal.WindowAnimationFrameStatsMonitorImpl}
- * using the same threshold to determine jank.
- */
-public class WindowAnimationFrameStatsMonitor implements ITransitionMonitor {
-
-    private static final String TAG = "FLICKER";
-    // Maximum normalized error in frame duration before the frame is considered janky
-    private static final double MAX_ERROR = 0.5f;
-    // Maximum normalized frame duration before the frame is considered a pause
-    private static final double PAUSE_THRESHOLD = 15.0f;
-    private Instrumentation mInstrumentation;
-    private FrameStats stats;
-    private int numJankyFrames;
-    private long mLongestFrameNano = 0L;
-
-
-    /**
-     * Constructs a WindowAnimationFrameStatsMonitor instance.
-     */
-    public WindowAnimationFrameStatsMonitor(Instrumentation instrumentation) {
-        mInstrumentation = instrumentation;
-    }
-
-    private void analyze() {
-        int frameCount = stats.getFrameCount();
-        long refreshPeriodNano = stats.getRefreshPeriodNano();
-
-        // Skip first frame
-        for (int i = 2; i < frameCount; i++) {
-            // Handle frames that have not been presented.
-            if (stats.getFramePresentedTimeNano(i) == UNDEFINED_TIME_NANO) {
-                // The animation must not have completed. Warn and break out of the loop.
-                Log.w(TAG, "Skipping fenced frame.");
-                break;
-            }
-            long frameDurationNano = stats.getFramePresentedTimeNano(i) -
-                    stats.getFramePresentedTimeNano(i - 1);
-            double normalized = (double) frameDurationNano / refreshPeriodNano;
-            if (normalized < PAUSE_THRESHOLD) {
-                if (normalized > 1.0f + MAX_ERROR) {
-                    numJankyFrames++;
-                }
-                mLongestFrameNano = Math.max(mLongestFrameNano, frameDurationNano);
-            }
-        }
-    }
-
-    @Override
-    public void start() {
-        // Clear out any previous data
-        numJankyFrames = 0;
-        mLongestFrameNano = 0;
-        mInstrumentation.getUiAutomation().clearWindowAnimationFrameStats();
-    }
-
-    @Override
-    public void stop() {
-        stats = mInstrumentation.getUiAutomation().getWindowAnimationFrameStats();
-        analyze();
-    }
-
-    public boolean jankyFramesDetected() {
-        return stats.getFrameCount() > 0 && numJankyFrames > 0;
-    }
-
-    @Override
-    public String toString() {
-        return stats.toString() +
-                " RefreshPeriodNano:" + stats.getRefreshPeriodNano() +
-                " NumJankyFrames:" + numJankyFrames +
-                " LongestFrameNano:" + mLongestFrameNano;
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitor.java b/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitor.java
deleted file mode 100644
index 11de4aa..0000000
--- a/tests/FlickerTests/lib/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitor.java
+++ /dev/null
@@ -1,59 +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.server.wm.flicker.monitor;
-
-import android.os.RemoteException;
-import android.view.IWindowManager;
-import android.view.WindowManagerGlobal;
-
-/**
- * Captures WindowManager trace from WindowManager.
- */
-public class WindowManagerTraceMonitor extends TraceMonitor {
-    private IWindowManager mWm = WindowManagerGlobal.getWindowManagerService();
-
-    public WindowManagerTraceMonitor() {
-        this(OUTPUT_DIR.toString());
-    }
-
-    public WindowManagerTraceMonitor(String outputDir) {
-        super(outputDir, "wm_trace.pb");
-    }
-
-    @Override
-    public void start() {
-        try {
-            mWm.startWindowTrace();
-        } catch (RemoteException e) {
-            throw new RuntimeException("Could not start trace", e);
-        }
-    }
-
-    @Override
-    public void stop() {
-        try {
-            mWm.stopWindowTrace();
-        } catch (RemoteException e) {
-            throw new RuntimeException("Could not stop trace", e);
-        }
-    }
-
-    @Override
-    public boolean isEnabled() throws RemoteException{
-        return mWm.isWindowTraceEnabled();
-    }
-}
diff --git a/tests/FlickerTests/lib/test/Android.bp b/tests/FlickerTests/lib/test/Android.bp
deleted file mode 100644
index bfeb75b2..0000000
--- a/tests/FlickerTests/lib/test/Android.bp
+++ /dev/null
@@ -1,33 +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.
-//
-
-android_test {
-    name: "FlickerLibTest",
-    // sign this with platform cert, so this test is allowed to call private platform apis
-    certificate: "platform",
-    platform_apis: true,
-    test_suites: ["tests"],
-    srcs: ["src/**/*.java"],
-    libs: ["android.test.runner"],
-    static_libs: [
-        "androidx.test.rules",
-        "platform-test-annotations",
-        "truth-prebuilt",
-        "platformprotosnano",
-        "layersprotosnano",
-        "flickerlib",
-    ],
-}
diff --git a/tests/FlickerTests/lib/test/AndroidManifest.xml b/tests/FlickerTests/lib/test/AndroidManifest.xml
deleted file mode 100644
index 6451a57..0000000
--- a/tests/FlickerTests/lib/test/AndroidManifest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright 2018 Google Inc. All Rights Reserved.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.server.wm.flicker">
-
-    <uses-sdk android:minSdkVersion="27" android:targetSdkVersion="27"/>
-    <!-- Read and write traces from external storage -->
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <!-- Capture screen contents -->
-    <uses-permission android:name="android.permission.ACCESS_SURFACE_FLINGER" />
-    <!-- Run layers trace -->
-    <uses-permission android:name="android.permission.HARDWARE_TEST"/>
-    <application android:label="FlickerLibTest">
-        <uses-library android:name="android.test.runner"/>
-    </application>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.server.wm.flicker"
-                     android:label="WindowManager Flicker Lib Test">
-    </instrumentation>
-
-</manifest>
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/test/AndroidTest.xml b/tests/FlickerTests/lib/test/AndroidTest.xml
deleted file mode 100644
index e4cc298..0000000
--- a/tests/FlickerTests/lib/test/AndroidTest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright 2018 Google Inc. All Rights Reserved.
- -->
-<configuration description="Config for WindowManager Flicker Tests">
-    <target_preparer class="com.google.android.tradefed.targetprep.GoogleDeviceSetup">
-        <!-- keeps the screen on during tests -->
-        <option name="screen-always-on" value="on" />
-        <!-- prevents the phone from restarting -->
-        <option name="force-skip-system-props" value="true" />
-    </target_preparer>
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true"/>
-        <option name="test-file-name" value="FlickerLibTest.apk"/>
-    </target_preparer>
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest">
-        <option name="package" value="com.android.server.wm.flicker"/>
-        <option name="hidden-api-checks" value="false" />
-    </test>
-</configuration>
diff --git a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_emptyregion.pb b/tests/FlickerTests/lib/test/assets/testdata/layers_trace_emptyregion.pb
deleted file mode 100644
index 98ee6f3..0000000
--- a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_emptyregion.pb
+++ /dev/null
Binary files differ
diff --git a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_invalid_layer_visibility.pb b/tests/FlickerTests/lib/test/assets/testdata/layers_trace_invalid_layer_visibility.pb
deleted file mode 100644
index 20572d7..0000000
--- a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_invalid_layer_visibility.pb
+++ /dev/null
Binary files differ
diff --git a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_orphanlayers.pb b/tests/FlickerTests/lib/test/assets/testdata/layers_trace_orphanlayers.pb
deleted file mode 100644
index af40797..0000000
--- a/tests/FlickerTests/lib/test/assets/testdata/layers_trace_orphanlayers.pb
+++ /dev/null
Binary files differ
diff --git a/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome.pb b/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome.pb
deleted file mode 100644
index b3f3170..0000000
--- a/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome.pb
+++ /dev/null
Binary files differ
diff --git a/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome2.pb b/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome2.pb
deleted file mode 100644
index b3b73ce..0000000
--- a/tests/FlickerTests/lib/test/assets/testdata/wm_trace_openchrome2.pb
+++ /dev/null
Binary files differ
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsCheckerTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsCheckerTest.java
deleted file mode 100644
index 8e7fe1b..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsCheckerTest.java
+++ /dev/null
@@ -1,181 +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.server.wm.flicker;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.wm.flicker.Assertions.Result;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Contains {@link AssertionsChecker} tests.
- * To run this test: {@code atest FlickerLibTest:AssertionsCheckerTest}
- */
-public class AssertionsCheckerTest {
-
-    /**
-     * Returns a list of SimpleEntry objects with {@code data} and incremental timestamps starting
-     * at 0.
-     */
-    private static List<SimpleEntry> getTestEntries(int... data) {
-        List<SimpleEntry> entries = new ArrayList<>();
-        for (int i = 0; i < data.length; i++) {
-            entries.add(new SimpleEntry(i, data[i]));
-        }
-        return entries;
-    }
-
-    @Test
-    public void canCheckAllEntries() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.add(SimpleEntry::isData42, "isData42");
-
-        List<Result> failures = checker.test(getTestEntries(1, 1, 1, 1, 1));
-
-        assertThat(failures).hasSize(5);
-    }
-
-    @Test
-    public void canCheckFirstEntry() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.checkFirstEntry();
-        checker.add(SimpleEntry::isData42, "isData42");
-
-        List<Result> failures = checker.test(getTestEntries(1, 1, 1, 1, 1));
-
-        assertThat(failures).hasSize(1);
-        assertThat(failures.get(0).timestamp).isEqualTo(0);
-    }
-
-    @Test
-    public void canCheckLastEntry() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.checkLastEntry();
-        checker.add(SimpleEntry::isData42, "isData42");
-
-        List<Result> failures = checker.test(getTestEntries(1, 1, 1, 1, 1));
-
-        assertThat(failures).hasSize(1);
-        assertThat(failures.get(0).timestamp).isEqualTo(4);
-    }
-
-    @Test
-    public void canCheckRangeOfEntries() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.filterByRange(1, 2);
-        checker.add(SimpleEntry::isData42, "isData42");
-
-        List<Result> failures = checker.test(getTestEntries(1, 42, 42, 1, 1));
-
-        assertThat(failures).hasSize(0);
-    }
-
-    @Test
-    public void emptyRangePasses() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.filterByRange(9, 10);
-        checker.add(SimpleEntry::isData42, "isData42");
-
-        List<Result> failures = checker.test(getTestEntries(1, 1, 1, 1, 1));
-
-        assertThat(failures).isEmpty();
-    }
-
-    @Test
-    public void canCheckChangingAssertions() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.add(SimpleEntry::isData42, "isData42");
-        checker.add(SimpleEntry::isData0, "isData0");
-        checker.checkChangingAssertions();
-
-        List<Result> failures = checker.test(getTestEntries(42, 0, 0, 0, 0));
-
-        assertThat(failures).isEmpty();
-    }
-
-    @Test
-    public void canCheckChangingAssertions_withNoAssertions() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.checkChangingAssertions();
-
-        List<Result> failures = checker.test(getTestEntries(42, 0, 0, 0, 0));
-
-        assertThat(failures).isEmpty();
-    }
-
-    @Test
-    public void canCheckChangingAssertions_withSingleAssertion() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.add(SimpleEntry::isData42, "isData42");
-        checker.checkChangingAssertions();
-
-        List<Result> failures = checker.test(getTestEntries(42, 42, 42, 42, 42));
-
-        assertThat(failures).isEmpty();
-    }
-
-    @Test
-    public void canFailCheckChangingAssertions_ifStartingAssertionFails() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.add(SimpleEntry::isData42, "isData42");
-        checker.add(SimpleEntry::isData0, "isData0");
-        checker.checkChangingAssertions();
-
-        List<Result> failures = checker.test(getTestEntries(0, 0, 0, 0, 0));
-
-        assertThat(failures).hasSize(1);
-    }
-
-    @Test
-    public void canFailCheckChangingAssertions_ifStartingAssertionAlwaysPasses() {
-        AssertionsChecker<SimpleEntry> checker = new AssertionsChecker<>();
-        checker.add(SimpleEntry::isData42, "isData42");
-        checker.add(SimpleEntry::isData0, "isData0");
-        checker.checkChangingAssertions();
-
-        List<Result> failures = checker.test(getTestEntries(0, 0, 0, 0, 0));
-
-        assertThat(failures).hasSize(1);
-    }
-
-    static class SimpleEntry implements ITraceEntry {
-        long timestamp;
-        int data;
-
-        SimpleEntry(long timestamp, int data) {
-            this.timestamp = timestamp;
-            this.data = data;
-        }
-
-        @Override
-        public long getTimestamp() {
-            return timestamp;
-        }
-
-        Result isData42() {
-            return new Result(this.data == 42, this.timestamp, "is42", "");
-        }
-
-        Result isData0() {
-            return new Result(this.data == 0, this.timestamp, "is42", "");
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsTest.java
deleted file mode 100644
index 7fd178c..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/AssertionsTest.java
+++ /dev/null
@@ -1,60 +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.server.wm.flicker;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.wm.flicker.Assertions.Result;
-
-import org.junit.Test;
-
-/**
- * Contains {@link Assertions} tests.
- * To run this test: {@code atest FlickerLibTest:AssertionsTest}
- */
-public class AssertionsTest {
-    @Test
-    public void traceEntryAssertionCanNegateResult() {
-        Assertions.TraceAssertion<Integer> assertNumEquals42 =
-                getIntegerTraceEntryAssertion();
-
-        assertThat(assertNumEquals42.apply(1).success).isFalse();
-        assertThat(assertNumEquals42.negate().apply(1).success).isTrue();
-
-        assertThat(assertNumEquals42.apply(42).success).isTrue();
-        assertThat(assertNumEquals42.negate().apply(42).success).isFalse();
-    }
-
-    @Test
-    public void resultCanBeNegated() {
-        String reason = "Everything is fine!";
-        Result result = new Result(true, 0, "TestAssert", reason);
-        Result negatedResult = result.negate();
-        assertThat(negatedResult.success).isFalse();
-        assertThat(negatedResult.reason).isEqualTo(reason);
-        assertThat(negatedResult.assertionName).isEqualTo("!TestAssert");
-    }
-
-    private Assertions.TraceAssertion<Integer> getIntegerTraceEntryAssertion() {
-        return (num) -> {
-            if (num == 42) {
-                return new Result(true, "Num equals 42");
-            }
-            return new Result(false, "Num doesn't equal 42, actual:" + num);
-        };
-    }
-}
\ No newline at end of file
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceSubjectTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceSubjectTest.java
deleted file mode 100644
index d06c5d7..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceSubjectTest.java
+++ /dev/null
@@ -1,88 +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.server.wm.flicker;
-
-import static com.android.server.wm.flicker.LayersTraceSubject.assertThat;
-import static com.android.server.wm.flicker.TestFileUtils.readTestFile;
-
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.fail;
-
-import android.graphics.Rect;
-
-import org.junit.Test;
-
-import java.nio.file.Paths;
-
-/**
- * Contains {@link LayersTraceSubject} tests.
- * To run this test: {@code atest FlickerLibTest:LayersTraceSubjectTest}
- */
-public class LayersTraceSubjectTest {
-    private static final Rect displayRect = new Rect(0, 0, 1440, 2880);
-
-    private static LayersTrace readLayerTraceFromFile(String relativePath) {
-        try {
-            return LayersTrace.parseFrom(readTestFile(relativePath), Paths.get(relativePath));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Test
-    public void testCanDetectEmptyRegionFromLayerTrace() {
-        LayersTrace layersTraceEntries = readLayerTraceFromFile("layers_trace_emptyregion.pb");
-        try {
-            assertThat(layersTraceEntries).coversRegion(displayRect).forAllEntries();
-            fail("Assertion passed");
-        } catch (AssertionError e) {
-            assertWithMessage("Contains path to trace")
-                    .that(e.getMessage()).contains("layers_trace_emptyregion.pb");
-            assertWithMessage("Contains timestamp")
-                    .that(e.getMessage()).contains("0h38m28s8ms");
-            assertWithMessage("Contains assertion function")
-                    .that(e.getMessage()).contains("coversRegion");
-            assertWithMessage("Contains debug info")
-                    .that(e.getMessage()).contains("Region to test: " + displayRect);
-            assertWithMessage("Contains debug info")
-                    .that(e.getMessage()).contains("first empty point: 0, 99");
-        }
-    }
-
-    @Test
-    public void testCanDetectIncorrectVisibilityFromLayerTrace() {
-        LayersTrace layersTraceEntries = readLayerTraceFromFile(
-                "layers_trace_invalid_layer_visibility.pb");
-        try {
-            assertThat(layersTraceEntries).showsLayer("com.android.server.wm.flicker.testapp")
-                    .then().hidesLayer("com.android.server.wm.flicker.testapp").forAllEntries();
-            fail("Assertion passed");
-        } catch (AssertionError e) {
-            assertWithMessage("Contains path to trace")
-                    .that(e.getMessage()).contains("layers_trace_invalid_layer_visibility.pb");
-            assertWithMessage("Contains timestamp")
-                    .that(e.getMessage()).contains("70h13m14s303ms");
-            assertWithMessage("Contains assertion function")
-                    .that(e.getMessage()).contains("!isVisible");
-            assertWithMessage("Contains debug info")
-                    .that(e.getMessage()).contains(
-                    "com.android.server.wm.flicker.testapp/com.android.server.wm.flicker.testapp"
-                            + ".SimpleActivity#0 is visible");
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java
deleted file mode 100644
index 7d77126..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/LayersTraceTest.java
+++ /dev/null
@@ -1,230 +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.server.wm.flicker;
-
-import static com.android.server.wm.flicker.TestFileUtils.readTestFile;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.fail;
-
-import android.content.Context;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.WindowManager;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.Test;
-
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * Contains {@link LayersTrace} tests.
- * To run this test: {@code atest FlickerLibTest:LayersTraceTest}
- */
-public class LayersTraceTest {
-    private static LayersTrace readLayerTraceFromFile(String relativePath) {
-        try {
-            return LayersTrace.parseFrom(readTestFile(relativePath));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static Rect getDisplayBounds() {
-        Point display = new Point();
-        WindowManager wm =
-                (WindowManager) InstrumentationRegistry.getContext().getSystemService(
-                        Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getRealSize(display);
-        return new Rect(0, 0, display.x, display.y);
-    }
-
-    @Test
-    public void canParseAllLayers() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        assertThat(trace.getEntries()).isNotEmpty();
-        assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
-        assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
-                .isEqualTo(2308521813510L);
-        List<LayersTrace.Layer> flattenedLayers = trace.getEntries().get(0).asFlattenedLayers();
-        String msg = "Layers:\n" + flattenedLayers.stream().map(layer -> layer.mProto.name)
-                .collect(Collectors.joining("\n\t"));
-        assertWithMessage(msg).that(flattenedLayers).hasSize(47);
-    }
-
-    @Test
-    public void canParseVisibleLayers() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        assertThat(trace.getEntries()).isNotEmpty();
-        assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
-        assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
-                .isEqualTo(2308521813510L);
-        List<LayersTrace.Layer> flattenedLayers = trace.getEntries().get(0).asFlattenedLayers();
-        List<LayersTrace.Layer> visibleLayers = flattenedLayers.stream()
-                .filter(layer -> layer.isVisible() && !layer.isHiddenByParent())
-                .collect(Collectors.toList());
-
-        String msg = "Visible Layers:\n" + visibleLayers.stream()
-                .map(layer -> layer.mProto.name)
-                .collect(Collectors.joining("\n\t"));
-
-        assertWithMessage(msg).that(visibleLayers).hasSize(9);
-    }
-
-    @Test
-    public void canParseLayerHierarchy() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        assertThat(trace.getEntries()).isNotEmpty();
-        assertThat(trace.getEntries().get(0).getTimestamp()).isEqualTo(2307984557311L);
-        assertThat(trace.getEntries().get(trace.getEntries().size() - 1).getTimestamp())
-                .isEqualTo(2308521813510L);
-        List<LayersTrace.Layer> layers = trace.getEntries().get(0).getRootLayers();
-        assertThat(layers).hasSize(2);
-        assertThat(layers.get(0).mChildren).hasSize(layers.get(0).mProto.children.length);
-        assertThat(layers.get(1).mChildren).hasSize(layers.get(1).mProto.children.length);
-    }
-
-    // b/76099859
-    @Test
-    public void canDetectOrphanLayers() {
-        try {
-            readLayerTraceFromFile(
-                    "layers_trace_orphanlayers.pb");
-            fail("Failed to detect orphaned layers.");
-        } catch (RuntimeException exception) {
-            assertThat(exception.getMessage()).contains(
-                    "Failed to parse layers trace. Found orphan layers "
-                            + "with parent layer id:1006 : 49");
-        }
-    }
-
-    // b/75276931
-    @Test
-    public void canDetectUncoveredRegion() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2308008331271L);
-
-        Assertions.Result result = entry.coversRegion(getDisplayBounds());
-
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("Region to test: Rect(0, 0 - 1440, 2880)");
-        assertThat(result.reason).contains("first empty point: 0, 99");
-        assertThat(result.reason).contains("visible regions:");
-        assertWithMessage("Reason contains list of visible regions")
-                .that(result.reason).contains("StatusBar#0Rect(0, 0 - 1440, 98");
-    }
-
-    // Visible region tests
-    @Test
-    public void canTestLayerVisibleRegion_layerDoesNotExist() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2308008331271L);
-
-        final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
-        Assertions.Result result = entry.hasVisibleRegion("ImaginaryLayer",
-                expectedVisibleRegion);
-
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("Could not find ImaginaryLayer");
-    }
-
-    @Test
-    public void canTestLayerVisibleRegion_layerDoesNotHaveExpectedVisibleRegion() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2307993020072L);
-
-        final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
-        Assertions.Result result = entry.hasVisibleRegion("NexusLauncherActivity#2",
-                expectedVisibleRegion);
-
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains(
-                "Layer com.google.android.apps.nexuslauncher/com.google.android.apps"
-                        + ".nexuslauncher.NexusLauncherActivity#2 is invisible: activeBuffer=null"
-                        + " type != ColorLayer flags=1 (FLAG_HIDDEN set) visible region is empty");
-    }
-
-    @Test
-    public void canTestLayerVisibleRegion_layerIsHiddenByParent() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2308455948035L);
-
-        final Rect expectedVisibleRegion = new Rect(0, 0, 1, 1);
-        Assertions.Result result = entry.hasVisibleRegion(
-                "SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main",
-                expectedVisibleRegion);
-
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains(
-                "Layer SurfaceView - com.android.chrome/com.google.android.apps.chrome.Main#0 is "
-                        + "hidden by parent: com.android.chrome/com.google.android.apps.chrome"
-                        + ".Main#0");
-    }
-
-    @Test
-    public void canTestLayerVisibleRegion_incorrectRegionSize() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2308008331271L);
-
-        final Rect expectedVisibleRegion = new Rect(0, 0, 1440, 99);
-        Assertions.Result result = entry.hasVisibleRegion(
-                "StatusBar",
-                expectedVisibleRegion);
-
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("StatusBar#0 has visible "
-                + "region:Rect(0, 0 - 1440, 98) expected:Rect(0, 0 - 1440, 99)");
-    }
-
-    @Test
-    public void canTestLayerVisibleRegion() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_emptyregion.pb");
-        LayersTrace.Entry entry = trace.getEntry(2308008331271L);
-
-        final Rect expectedVisibleRegion = new Rect(0, 0, 1440, 98);
-        Assertions.Result result = entry.hasVisibleRegion("StatusBar", expectedVisibleRegion);
-
-        assertThat(result.passed()).isTrue();
-    }
-
-    @Test
-    public void canTestLayerVisibleRegion_layerIsNotVisible() {
-        LayersTrace trace = readLayerTraceFromFile(
-                "layers_trace_invalid_layer_visibility.pb");
-        LayersTrace.Entry entry = trace.getEntry(252794268378458L);
-
-        Assertions.Result result = entry.isVisible("com.android.server.wm.flicker.testapp");
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains(
-                "Layer com.android.server.wm.flicker.testapp/com.android.server.wm.flicker"
-                        + ".testapp.SimpleActivity#0 is invisible: type != ColorLayer visible "
-                        + "region is empty");
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java
deleted file mode 100644
index c46175c..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TestFileUtils.java
+++ /dev/null
@@ -1,36 +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.server.wm.flicker;
-
-import android.content.Context;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.google.common.io.ByteStreams;
-
-import java.io.InputStream;
-
-/**
- * Helper functions for test file resources.
- */
-class TestFileUtils {
-    static byte[] readTestFile(String relativePath) throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        InputStream in = context.getResources().getAssets().open("testdata/" + relativePath);
-        return ByteStreams.toByteArray(in);
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TransitionRunnerTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TransitionRunnerTest.java
deleted file mode 100644
index 9c5e2059a..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/TransitionRunnerTest.java
+++ /dev/null
@@ -1,258 +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.server.wm.flicker;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.os.Environment;
-
-import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder;
-import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
-import com.android.server.wm.flicker.monitor.LayersTraceMonitor;
-import com.android.server.wm.flicker.monitor.ScreenRecorder;
-import com.android.server.wm.flicker.monitor.WindowAnimationFrameStatsMonitor;
-import com.android.server.wm.flicker.monitor.WindowManagerTraceMonitor;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.InOrder;
-import org.mockito.InjectMocks;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-import java.io.IOException;
-import java.nio.file.Paths;
-import java.util.List;
-
-/**
- * Contains {@link TransitionRunner} tests.
- * {@code atest FlickerLibTest:TransitionRunnerTest}
- */
-public class TransitionRunnerTest {
-    @Mock
-    private SimpleUiTransitions mTransitionsMock;
-    @Mock
-    private ScreenRecorder mScreenRecorderMock;
-    @Mock
-    private WindowManagerTraceMonitor mWindowManagerTraceMonitorMock;
-    @Mock
-    private LayersTraceMonitor mLayersTraceMonitorMock;
-    @Mock
-    private WindowAnimationFrameStatsMonitor mWindowAnimationFrameStatsMonitor;
-    @InjectMocks
-    private TransitionBuilder mTransitionBuilder;
-
-    @Before
-    public void init() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    @Test
-    public void transitionsRunInOrder() {
-        TransitionRunner.newBuilder()
-                .runBeforeAll(mTransitionsMock::turnOnDevice)
-                .runBefore(mTransitionsMock::openApp)
-                .run(mTransitionsMock::performMagic)
-                .runAfter(mTransitionsMock::closeApp)
-                .runAfterAll(mTransitionsMock::cleanUpTracks)
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .build()
-                .run();
-
-        InOrder orderVerifier = inOrder(mTransitionsMock);
-        orderVerifier.verify(mTransitionsMock).turnOnDevice();
-        orderVerifier.verify(mTransitionsMock).openApp();
-        orderVerifier.verify(mTransitionsMock).performMagic();
-        orderVerifier.verify(mTransitionsMock).closeApp();
-        orderVerifier.verify(mTransitionsMock).cleanUpTracks();
-    }
-
-    @Test
-    public void canCombineTransitions() {
-        TransitionRunner.newBuilder()
-                .runBeforeAll(mTransitionsMock::turnOnDevice)
-                .runBeforeAll(mTransitionsMock::turnOnDevice)
-                .runBefore(mTransitionsMock::openApp)
-                .runBefore(mTransitionsMock::openApp)
-                .run(mTransitionsMock::performMagic)
-                .run(mTransitionsMock::performMagic)
-                .runAfter(mTransitionsMock::closeApp)
-                .runAfter(mTransitionsMock::closeApp)
-                .runAfterAll(mTransitionsMock::cleanUpTracks)
-                .runAfterAll(mTransitionsMock::cleanUpTracks)
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .build()
-                .run();
-
-        final int wantedNumberOfInvocations = 2;
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).turnOnDevice();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).openApp();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).performMagic();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).closeApp();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).cleanUpTracks();
-    }
-
-    @Test
-    public void emptyTransitionPasses() {
-        List<TransitionResult> results = TransitionRunner.newBuilder()
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .build()
-                .run()
-                .getResults();
-        assertThat(results).hasSize(1);
-        assertThat(results.get(0).layersTraceExists()).isFalse();
-        assertThat(results.get(0).windowManagerTraceExists()).isFalse();
-        assertThat(results.get(0).screenCaptureVideoExists()).isFalse();
-    }
-
-    @Test
-    public void canRepeatTransitions() {
-        final int wantedNumberOfInvocations = 10;
-        TransitionRunner.newBuilder()
-                .runBeforeAll(mTransitionsMock::turnOnDevice)
-                .runBefore(mTransitionsMock::openApp)
-                .run(mTransitionsMock::performMagic)
-                .runAfter(mTransitionsMock::closeApp)
-                .runAfterAll(mTransitionsMock::cleanUpTracks)
-                .repeat(wantedNumberOfInvocations)
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .build()
-                .run();
-        verify(mTransitionsMock).turnOnDevice();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).openApp();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).performMagic();
-        verify(mTransitionsMock, times(wantedNumberOfInvocations)).closeApp();
-        verify(mTransitionsMock).cleanUpTracks();
-    }
-
-    private void emptyTask() {
-
-    }
-
-    @Test
-    public void canCaptureWindowManagerTrace() {
-        mTransitionBuilder
-                .run(this::emptyTask)
-                .includeJankyRuns()
-                .skipLayersTrace()
-                .withTag("mCaptureWmTraceTransitionRunner")
-                .build().run();
-        InOrder orderVerifier = inOrder(mWindowManagerTraceMonitorMock);
-        orderVerifier.verify(mWindowManagerTraceMonitorMock).start();
-        orderVerifier.verify(mWindowManagerTraceMonitorMock).stop();
-        orderVerifier.verify(mWindowManagerTraceMonitorMock)
-                .save("mCaptureWmTraceTransitionRunner", 0);
-        verifyNoMoreInteractions(mWindowManagerTraceMonitorMock);
-    }
-
-    @Test
-    public void canCaptureLayersTrace() {
-        mTransitionBuilder
-                .run(this::emptyTask)
-                .includeJankyRuns()
-                .skipWindowManagerTrace()
-                .withTag("mCaptureLayersTraceTransitionRunner")
-                .build().run();
-        InOrder orderVerifier = inOrder(mLayersTraceMonitorMock);
-        orderVerifier.verify(mLayersTraceMonitorMock).start();
-        orderVerifier.verify(mLayersTraceMonitorMock).stop();
-        orderVerifier.verify(mLayersTraceMonitorMock)
-                .save("mCaptureLayersTraceTransitionRunner", 0);
-        verifyNoMoreInteractions(mLayersTraceMonitorMock);
-    }
-
-    @Test
-    public void canRecordEachRun() throws IOException {
-        mTransitionBuilder
-                .run(this::emptyTask)
-                .withTag("mRecordEachRun")
-                .recordEachRun()
-                .includeJankyRuns()
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .repeat(2)
-                .build().run();
-        InOrder orderVerifier = inOrder(mScreenRecorderMock);
-        orderVerifier.verify(mScreenRecorderMock).start();
-        orderVerifier.verify(mScreenRecorderMock).stop();
-        orderVerifier.verify(mScreenRecorderMock).save("mRecordEachRun", 0);
-        orderVerifier.verify(mScreenRecorderMock).start();
-        orderVerifier.verify(mScreenRecorderMock).stop();
-        orderVerifier.verify(mScreenRecorderMock).save("mRecordEachRun", 1);
-        verifyNoMoreInteractions(mScreenRecorderMock);
-    }
-
-    @Test
-    public void canRecordAllRuns() throws IOException {
-        doReturn(Paths.get(Environment.getExternalStorageDirectory().getAbsolutePath(),
-                "mRecordAllRuns.mp4")).when(mScreenRecorderMock).save("mRecordAllRuns");
-        mTransitionBuilder
-                .run(this::emptyTask)
-                .recordAllRuns()
-                .includeJankyRuns()
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .withTag("mRecordAllRuns")
-                .repeat(2)
-                .build().run();
-        InOrder orderVerifier = inOrder(mScreenRecorderMock);
-        orderVerifier.verify(mScreenRecorderMock).start();
-        orderVerifier.verify(mScreenRecorderMock).stop();
-        orderVerifier.verify(mScreenRecorderMock).save("mRecordAllRuns");
-        verifyNoMoreInteractions(mScreenRecorderMock);
-    }
-
-    @Test
-    public void canSkipJankyRuns() {
-        doReturn(false).doReturn(true).doReturn(false)
-                .when(mWindowAnimationFrameStatsMonitor).jankyFramesDetected();
-        List<TransitionResult> results = mTransitionBuilder
-                .run(this::emptyTask)
-                .skipLayersTrace()
-                .skipWindowManagerTrace()
-                .repeat(3)
-                .build().run().getResults();
-        assertThat(results).hasSize(2);
-    }
-
-    public static class SimpleUiTransitions {
-        public void turnOnDevice() {
-        }
-
-        public void openApp() {
-        }
-
-        public void performMagic() {
-        }
-
-        public void closeApp() {
-        }
-
-        public void cleanUpTracks() {
-        }
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WindowManagerTraceTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WindowManagerTraceTest.java
deleted file mode 100644
index 4927871..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WindowManagerTraceTest.java
+++ /dev/null
@@ -1,108 +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.server.wm.flicker;
-
-import static com.android.server.wm.flicker.TestFileUtils.readTestFile;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.wm.flicker.Assertions.Result;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Contains {@link WindowManagerTrace} tests.
- * To run this test: {@code atest FlickerLibTest:WindowManagerTraceTest}
- */
-public class WindowManagerTraceTest {
-    private WindowManagerTrace mTrace;
-
-    private static WindowManagerTrace readWindowManagerTraceFromFile(String relativePath) {
-        try {
-            return WindowManagerTrace.parseFrom(readTestFile(relativePath));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Before
-    public void setup() {
-        mTrace = readWindowManagerTraceFromFile("wm_trace_openchrome.pb");
-    }
-
-    @Test
-    public void canParseAllEntries() {
-        assertThat(mTrace.getEntries().get(0).getTimestamp()).isEqualTo(241777211939236L);
-        assertThat(mTrace.getEntries().get(mTrace.getEntries().size() - 1).getTimestamp()).isEqualTo
-                (241779809471942L);
-    }
-
-    @Test
-    public void canDetectAboveAppWindowVisibility() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241777211939236L);
-        Result result = entry.isAboveAppWindowVisible("NavigationBar");
-        assertThat(result.passed()).isTrue();
-    }
-
-    @Test
-    public void canDetectBelowAppWindowVisibility() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241777211939236L);
-        Result result = entry.isBelowAppWindowVisible("wallpaper");
-        assertThat(result.passed()).isTrue();
-    }
-
-    @Test
-    public void canDetectAppWindowVisibility() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241777211939236L);
-        Result result = entry.isAppWindowVisible("com.google.android.apps.nexuslauncher");
-        assertThat(result.passed()).isTrue();
-    }
-
-    @Test
-    public void canFailWithReasonForVisibilityChecks_windowNotFound() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241777211939236L);
-        Result result = entry.isAboveAppWindowVisible("ImaginaryWindow");
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("ImaginaryWindow cannot be found");
-    }
-
-    @Test
-    public void canFailWithReasonForVisibilityChecks_windowNotVisible() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241777211939236L);
-        Result result = entry.isAboveAppWindowVisible("AssistPreviewPanel");
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("AssistPreviewPanel is invisible");
-    }
-
-    @Test
-    public void canDetectAppZOrder() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241778130296410L);
-        Result result = entry.isVisibleAppWindowOnTop("com.google.android.apps.chrome");
-        assertThat(result.passed()).isTrue();
-    }
-
-    @Test
-    public void canFailWithReasonForZOrderChecks_windowNotOnTop() {
-        WindowManagerTrace.Entry entry = mTrace.getEntry(241778130296410L);
-        Result result = entry.isVisibleAppWindowOnTop("com.google.android.apps.nexuslauncher");
-        assertThat(result.failed()).isTrue();
-        assertThat(result.reason).contains("wanted=com.google.android.apps.nexuslauncher");
-        assertThat(result.reason).contains("found=com.android.chrome/"
-                + "com.google.android.apps.chrome.Main");
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WmTraceSubjectTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WmTraceSubjectTest.java
deleted file mode 100644
index d547a18..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/WmTraceSubjectTest.java
+++ /dev/null
@@ -1,49 +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.server.wm.flicker;
-
-import static com.android.server.wm.flicker.TestFileUtils.readTestFile;
-import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
-
-import org.junit.Test;
-
-/**
- * Contains {@link WmTraceSubject} tests.
- * To run this test: {@code atest FlickerLibTest:WmTraceSubjectTest}
- */
-public class WmTraceSubjectTest {
-    private static WindowManagerTrace readWmTraceFromFile(String relativePath) {
-        try {
-            return WindowManagerTrace.parseFrom(readTestFile(relativePath));
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Test
-    public void testCanTransitionInAppWindow() {
-        WindowManagerTrace trace = readWmTraceFromFile("wm_trace_openchrome2.pb");
-
-        assertThat(trace).showsAppWindowOnTop("com.google.android.apps.nexuslauncher/"
-                + ".NexusLauncherActivity").forRange(174684850717208L, 174685957511016L);
-        assertThat(trace).showsAppWindowOnTop(
-                "com.google.android.apps.nexuslauncher/.NexusLauncherActivity")
-                .then()
-                .showsAppWindowOnTop("com.android.chrome")
-                .forAllEntries();
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/LayersTraceMonitorTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/LayersTraceMonitorTest.java
deleted file mode 100644
index dbd6761..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/LayersTraceMonitorTest.java
+++ /dev/null
@@ -1,78 +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.server.wm.flicker.monitor;
-
-import static android.surfaceflinger.nano.Layerstrace.LayersTraceFileProto.MAGIC_NUMBER_H;
-import static android.surfaceflinger.nano.Layerstrace.LayersTraceFileProto.MAGIC_NUMBER_L;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.surfaceflinger.nano.Layerstrace.LayersTraceFileProto;
-
-import com.google.common.io.Files;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.File;
-
-/**
- * Contains {@link LayersTraceMonitor} tests.
- * To run this test: {@code atest FlickerLibTest:LayersTraceMonitorTest}
- */
-public class LayersTraceMonitorTest {
-    private LayersTraceMonitor mLayersTraceMonitor;
-
-    @Before
-    public void setup() {
-        mLayersTraceMonitor = new LayersTraceMonitor();
-    }
-
-    @After
-    public void teardown() {
-        mLayersTraceMonitor.stop();
-        mLayersTraceMonitor.getOutputTraceFilePath("captureLayersTrace").toFile().delete();
-    }
-
-    @Test
-    public void canStartLayersTrace() throws Exception {
-        mLayersTraceMonitor.start();
-        assertThat(mLayersTraceMonitor.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void canStopLayersTrace() throws Exception {
-        mLayersTraceMonitor.start();
-        assertThat(mLayersTraceMonitor.isEnabled()).isTrue();
-        mLayersTraceMonitor.stop();
-        assertThat(mLayersTraceMonitor.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void captureLayersTrace() throws Exception {
-        mLayersTraceMonitor.start();
-        mLayersTraceMonitor.stop();
-        File testFile = mLayersTraceMonitor.save("captureLayersTrace").toFile();
-        assertThat(testFile.exists()).isTrue();
-        byte[] trace = Files.toByteArray(testFile);
-        assertThat(trace.length).isGreaterThan(0);
-        LayersTraceFileProto mLayerTraceFileProto = LayersTraceFileProto.parseFrom(trace);
-        assertThat(mLayerTraceFileProto.magicNumber).isEqualTo(
-                (long) MAGIC_NUMBER_H << 32 | MAGIC_NUMBER_L);
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/ScreenRecorderTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/ScreenRecorderTest.java
deleted file mode 100644
index e73eecc..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/ScreenRecorderTest.java
+++ /dev/null
@@ -1,70 +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.server.wm.flicker.monitor;
-
-import static android.os.SystemClock.sleep;
-
-import static com.android.server.wm.flicker.monitor.ScreenRecorder.DEFAULT_OUTPUT_PATH;
-import static com.android.server.wm.flicker.monitor.ScreenRecorder.getPath;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Contains {@link ScreenRecorder} tests.
- * To run this test: {@code atest FlickerLibTest:ScreenRecorderTest}
- */
-public class ScreenRecorderTest {
-    private static final String TEST_VIDEO_FILENAME = "test.mp4";
-    private ScreenRecorder mScreenRecorder;
-
-    @Before
-    public void setup() {
-        mScreenRecorder = new ScreenRecorder();
-    }
-
-    @After
-    public void teardown() {
-        DEFAULT_OUTPUT_PATH.toFile().delete();
-        getPath(TEST_VIDEO_FILENAME).toFile().delete();
-    }
-
-    @Test
-    public void videoIsRecorded() {
-        mScreenRecorder.start();
-        sleep(100);
-        mScreenRecorder.stop();
-        File file = DEFAULT_OUTPUT_PATH.toFile();
-        assertThat(file.exists()).isTrue();
-    }
-
-    @Test
-    public void videoCanBeSaved() {
-        mScreenRecorder.start();
-        sleep(100);
-        mScreenRecorder.stop();
-        mScreenRecorder.save(TEST_VIDEO_FILENAME);
-        File file = getPath(TEST_VIDEO_FILENAME).toFile();
-        assertThat(file.exists()).isTrue();
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java
deleted file mode 100644
index f312384..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowAnimationFrameStatsMonitorTest.java
+++ /dev/null
@@ -1,50 +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.server.wm.flicker.monitor;
-
-import static com.android.server.wm.flicker.helpers.AutomationUtils.wakeUpAndGoToHomeScreen;
-
-import androidx.test.InstrumentationRegistry;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-
-/**
- * Contains {@link WindowAnimationFrameStatsMonitor} tests.
- * To run this test: {@code atest FlickerLibTest:WindowAnimationFrameStatsMonitorTest}
- */
-public class WindowAnimationFrameStatsMonitorTest {
-    private WindowAnimationFrameStatsMonitor mWindowAnimationFrameStatsMonitor;
-
-    @Before
-    public void setup() {
-        mWindowAnimationFrameStatsMonitor = new WindowAnimationFrameStatsMonitor(
-                InstrumentationRegistry.getInstrumentation());
-        wakeUpAndGoToHomeScreen();
-    }
-
-    // TODO(vishnun)
-    @Ignore("Disabled until app-helper libraries are available.")
-    @Test
-    public void captureWindowAnimationFrameStats() throws Exception {
-        mWindowAnimationFrameStatsMonitor.start();
-        //AppHelperWrapper.getInstance().getHelper(CHROME).open();
-        //AppHelperWrapper.getInstance().getHelper(CHROME).exit();
-        mWindowAnimationFrameStatsMonitor.stop();
-    }
-}
diff --git a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitorTest.java b/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitorTest.java
deleted file mode 100644
index 56284d7..0000000
--- a/tests/FlickerTests/lib/test/src/com/android/server/wm/flicker/monitor/WindowManagerTraceMonitorTest.java
+++ /dev/null
@@ -1,79 +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.server.wm.flicker.monitor;
-
-import static com.android.server.wm.nano.WindowManagerTraceFileProto.MAGIC_NUMBER_H;
-import static com.android.server.wm.nano.WindowManagerTraceFileProto.MAGIC_NUMBER_L;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import com.android.server.wm.nano.WindowManagerTraceFileProto;
-
-import com.google.common.io.Files;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.io.File;
-
-/**
- * Contains {@link WindowManagerTraceMonitor} tests.
- * To run this test: {@code atest FlickerLibTest:WindowManagerTraceMonitorTest}
- */
-public class WindowManagerTraceMonitorTest {
-    private WindowManagerTraceMonitor mWindowManagerTraceMonitor;
-
-    @Before
-    public void setup() {
-        mWindowManagerTraceMonitor = new WindowManagerTraceMonitor();
-    }
-
-    @After
-    public void teardown() {
-        mWindowManagerTraceMonitor.stop();
-        mWindowManagerTraceMonitor.getOutputTraceFilePath("captureWindowTrace").toFile().delete();
-    }
-
-    @Test
-    public void canStartWindowTrace() throws Exception {
-        mWindowManagerTraceMonitor.start();
-        assertThat(mWindowManagerTraceMonitor.isEnabled()).isTrue();
-    }
-
-    @Test
-    public void canStopWindowTrace() throws Exception {
-        mWindowManagerTraceMonitor.start();
-        assertThat(mWindowManagerTraceMonitor.isEnabled()).isTrue();
-        mWindowManagerTraceMonitor.stop();
-        assertThat(mWindowManagerTraceMonitor.isEnabled()).isFalse();
-    }
-
-    @Test
-    public void captureWindowTrace() throws Exception {
-        mWindowManagerTraceMonitor.start();
-        mWindowManagerTraceMonitor.stop();
-        File testFile = mWindowManagerTraceMonitor.save("captureWindowTrace").toFile();
-        assertThat(testFile.exists()).isTrue();
-        byte[] trace = Files.toByteArray(testFile);
-        assertThat(trace.length).isGreaterThan(0);
-        WindowManagerTraceFileProto mWindowTraceFileProto = WindowManagerTraceFileProto.parseFrom(
-                trace);
-        assertThat(mWindowTraceFileProto.magicNumber).isEqualTo(
-                (long) MAGIC_NUMBER_H << 32 | MAGIC_NUMBER_L);
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
index b6860cb..aa591d9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ChangeAppRotationTest.java
@@ -29,11 +29,15 @@
 import android.view.Surface;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
@@ -44,18 +48,19 @@
  * Cycle through supported app rotations.
  * To run this test: {@code atest FlickerTest:ChangeAppRotationTest}
  */
-@RunWith(Parameterized.class)
 @LargeTest
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class ChangeAppRotationTest extends FlickerTestBase {
-    private int beginRotation;
-    private int endRotation;
+    private int mBeginRotation;
+    private int mEndRotation;
 
     public ChangeAppRotationTest(String beginRotationName, String endRotationName,
             int beginRotation, int endRotation) {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
-        this.beginRotation = beginRotation;
-        this.endRotation = endRotation;
+        this.mBeginRotation = beginRotation;
+        this.mEndRotation = endRotation;
     }
 
     @Parameters(name = "{0}-{1}")
@@ -77,15 +82,19 @@
     @Before
     public void runTransition() {
         super.runTransition(
-                changeAppRotation(testApp, uiDevice, beginRotation, endRotation).build());
+                changeAppRotation(mTestApp, mUiDevice, mBeginRotation, mEndRotation).build());
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkVisibility_navBarWindowIsAlwaysVisible() {
         checkResults(result -> assertThat(result)
                 .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkVisibility_statusBarWindowIsAlwaysVisible() {
         checkResults(result -> assertThat(result)
@@ -94,8 +103,8 @@
 
     @Test
     public void checkPosition_navBarLayerRotatesAndScales() {
-        Rect startingPos = getNavigationBarPosition(beginRotation);
-        Rect endingPos = getNavigationBarPosition(endRotation);
+        Rect startingPos = getNavigationBarPosition(mBeginRotation);
+        Rect endingPos = getNavigationBarPosition(mEndRotation);
         checkResults(result -> {
                     LayersTraceSubject.assertThat(result)
                             .hasVisibleRegion(NAVIGATION_BAR_WINDOW_TITLE, startingPos)
@@ -108,22 +117,22 @@
 
     @Test
     public void checkPosition_appLayerRotates() {
-        Rect startingPos = getAppPosition(beginRotation);
-        Rect endingPos = getAppPosition(endRotation);
+        Rect startingPos = getAppPosition(mBeginRotation);
+        Rect endingPos = getAppPosition(mEndRotation);
         Log.e(TAG, "startingPos=" + startingPos + " endingPos=" + endingPos);
         checkResults(result -> {
                     LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(testApp.getPackage(), startingPos).inTheBeginning();
+                            .hasVisibleRegion(mTestApp.getPackage(), startingPos).inTheBeginning();
                     LayersTraceSubject.assertThat(result)
-                            .hasVisibleRegion(testApp.getPackage(), endingPos).atTheEnd();
+                            .hasVisibleRegion(mTestApp.getPackage(), endingPos).atTheEnd();
                 }
         );
     }
 
     @Test
     public void checkPosition_statusBarLayerScales() {
-        Rect startingPos = getStatusBarPosition(beginRotation);
-        Rect endingPos = getStatusBarPosition(endRotation);
+        Rect startingPos = getStatusBarPosition(mBeginRotation);
+        Rect endingPos = getStatusBarPosition(mEndRotation);
         checkResults(result -> {
                     LayersTraceSubject.assertThat(result)
                             .hasVisibleRegion(STATUS_BAR_WINDOW_TITLE, startingPos)
@@ -134,12 +143,16 @@
         );
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkVisibility_navBarLayerIsAlwaysVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
                 .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkVisibility_statusBarLayerIsAlwaysVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
new file mode 100644
index 0000000..022f798
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToAppTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.flicker;
+
+import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.LargeTest;
+
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
+
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
+ */
+@LargeTest
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CloseImeAutoOpenWindowToAppTest extends CloseImeWindowToAppTest {
+
+    public CloseImeAutoOpenWindowToAppTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
+    }
+
+    @Before
+    public void runTransition() {
+        run(editTextLoseFocusToApp((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns().build());
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible();
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_imeAppLayerIsAlwaysVisible() {
+        super.checkVisibility_imeAppLayerIsAlwaysVisible();
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_imeAppWindowIsAlwaysVisible() {
+        super.checkVisibility_imeAppWindowIsAlwaysVisible();
+    }
+
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
new file mode 100644
index 0000000..d6f994b
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeAutoOpenWindowToHomeTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.flicker;
+
+import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.LargeTest;
+
+import com.android.server.wm.flicker.helpers.ImeAppAutoFocusHelper;
+
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+
+/**
+ * Test IME window closing back to app window transitions.
+ * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
+ */
+@LargeTest
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CloseImeAutoOpenWindowToHomeTest extends CloseImeWindowToHomeTest {
+
+    public CloseImeAutoOpenWindowToHomeTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        mTestApp = new ImeAppAutoFocusHelper(InstrumentationRegistry.getInstrumentation());
+    }
+
+    @Before
+    public void runTransition() {
+        run(editTextLoseFocusToHome((ImeAppAutoFocusHelper) mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns().build());
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_imeWindowBecomesInvisible() {
+        super.checkVisibility_imeWindowBecomesInvisible();
+    }
+
+    @FlakyTest(bugId = 141458352)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_imeLayerBecomesInvisible() {
+        super.checkVisibility_imeLayerBecomesInvisible();
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
index 6590b86..28da3af 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToAppTest.java
@@ -17,34 +17,39 @@
 package com.android.server.wm.flicker;
 
 import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToApp;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-
-import android.platform.helpers.IAppHelper;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test IME window closing back to app window transitions.
  * To run this test: {@code atest FlickerTests:CloseImeWindowToAppTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class CloseImeWindowToAppTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CloseImeWindowToAppTest extends NonRotationTestBase {
 
-    private static final String IME_WINDOW_TITLE = "InputMethod";
-    private IAppHelper mImeTestApp = new StandardAppHelper(
-            InstrumentationRegistry.getInstrumentation(),
-            "com.android.server.wm.flicker.testapp", "ImeApp");
+    static final String IME_WINDOW_TITLE = "InputMethod";
+
+    public CloseImeWindowToAppTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+    }
 
     @Before
     public void runTransition() {
-        super.runTransition(editTextLoseFocusToApp(uiDevice)
+        run(editTextLoseFocusToApp((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
                 .includeJankyRuns().build());
     }
 
@@ -60,20 +65,14 @@
     @Test
     public void checkVisibility_imeAppLayerIsAlwaysVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mImeTestApp.getPackage())
+                .showsLayer(mTestApp.getPackage())
                 .forAllEntries());
     }
 
     @Test
     public void checkVisibility_imeAppWindowIsAlwaysVisible() {
         checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mImeTestApp.getPackage())
+                .showsAppWindowOnTop(mTestApp.getPackage())
                 .forAllEntries());
     }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                getDisplayBounds()).forAllEntries());
-    }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
index 4771b02..fc6719e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CloseImeWindowToHomeTest.java
@@ -17,34 +17,39 @@
 package com.android.server.wm.flicker;
 
 import static com.android.server.wm.flicker.CommonTransitions.editTextLoseFocusToHome;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
-
-import android.platform.helpers.IAppHelper;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test IME window closing to home transitions.
  * To run this test: {@code atest FlickerTests:CloseImeWindowToHomeTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class CloseImeWindowToHomeTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CloseImeWindowToHomeTest extends NonRotationTestBase {
 
-    private static final String IME_WINDOW_TITLE = "InputMethod";
-    private IAppHelper mImeTestApp = new StandardAppHelper(
-            InstrumentationRegistry.getInstrumentation(),
-            "com.android.server.wm.flicker.testapp", "ImeApp");
+    static final String IME_WINDOW_TITLE = "InputMethod";
+
+    public CloseImeWindowToHomeTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+    }
 
     @Before
     public void runTransition() {
-        super.runTransition(editTextLoseFocusToHome(uiDevice)
+        run(editTextLoseFocusToHome((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
                 .includeJankyRuns().build());
     }
 
@@ -69,24 +74,18 @@
     @Test
     public void checkVisibility_imeAppLayerBecomesInvisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(mImeTestApp.getPackage())
+                .showsLayer(mTestApp.getPackage())
                 .then()
-                .hidesLayer(mImeTestApp.getPackage())
+                .hidesLayer(mTestApp.getPackage())
                 .forAllEntries());
     }
 
     @Test
     public void checkVisibility_imeAppWindowBecomesInvisible() {
         checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindowOnTop(mImeTestApp.getPackage())
+                .showsAppWindowOnTop(mTestApp.getPackage())
                 .then()
-                .hidesAppWindowOnTop(mImeTestApp.getPackage())
+                .hidesAppWindowOnTop(mTestApp.getPackage())
                 .forAllEntries());
     }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                getDisplayBounds()).forAllEntries());
-    }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
index 5cf2c1c..fd31aa5 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/CommonTransitions.java
@@ -37,10 +37,10 @@
 import android.util.Rational;
 import android.view.Surface;
 
-import androidx.test.InstrumentationRegistry;
-
 import com.android.server.wm.flicker.TransitionRunner.TransitionBuilder;
 import com.android.server.wm.flicker.helpers.AutomationUtils;
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
+import com.android.server.wm.flicker.helpers.PipAppHelper;
 
 /**
  * Collection of common transitions which can be used to test different apps or scenarios.
@@ -67,32 +67,23 @@
                     device.setOrientationNatural();
             }
             // Wait for animation to complete
-            sleep(3000);
+            sleep(1000);
         } catch (RemoteException e) {
             throw new RuntimeException(e);
         }
     }
 
-    private static void clickEditTextWidget(UiDevice device, IAppHelper testApp) {
-        UiObject2 editText = device.findObject(By.res(testApp.getPackage(), "plain_text_input"));
-        editText.click();
-        sleep(500);
-    }
-
-    private static void clickEnterPipButton(UiDevice device, IAppHelper testApp) {
-        UiObject2 enterPipButton = device.findObject(By.res(testApp.getPackage(), "enter_pip"));
-        enterPipButton.click();
-        sleep(500);
-    }
-
     static TransitionBuilder openAppWarm(IAppHelper testApp, UiDevice
-            device) {
+            device, int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("OpenAppWarm_" + testApp.getLauncherName())
+                .withTag("OpenAppWarm_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
+                .runBeforeAll(() -> setRotation(device, beginRotation))
                 .runBeforeAll(testApp::open)
                 .runBefore(device::pressHome)
                 .runBefore(device::waitForIdle)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .run(testApp::open)
                 .runAfterAll(testApp::exit)
                 .runAfterAll(AutomationUtils::setDefaultWait)
@@ -127,16 +118,19 @@
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder getOpenAppCold(IAppHelper testApp,
-            UiDevice device) {
+    static TransitionBuilder openAppCold(IAppHelper testApp,
+            UiDevice device, int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("OpenAppCold_" + testApp.getLauncherName())
+                .withTag("OpenAppCold_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBeforeAll(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::exit)
                 .runBefore(device::waitForIdle)
                 .run(testApp::open)
                 .runAfterAll(testApp::exit)
+                .runAfterAll(() -> setRotation(device, Surface.ROTATION_0))
                 .repeat(ITERATIONS);
     }
 
@@ -201,28 +195,31 @@
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder editTextSetFocus(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "ImeApp");
+    static TransitionBuilder editTextSetFocus(ImeAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("editTextSetFocus_" + testApp.getLauncherName())
+                .withTag("editTextSetFocus_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
-                .run(() -> clickEditTextWidget(device, testApp))
+                .run(() -> testApp.clickEditTextWidget(device))
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder resizeSplitScreen(IAppHelper testAppTop, IAppHelper testAppBottom,
-            UiDevice device, Rational startRatio, Rational stopRatio) {
-        String testTag = "resizeSplitScreen_" + testAppTop.getLauncherName() + "_" +
-                testAppBottom.getLauncherName() + "_" +
-                startRatio.toString().replace("/", ":") + "_to_" +
-                stopRatio.toString().replace("/", ":");
+    static TransitionBuilder resizeSplitScreen(IAppHelper testAppTop, ImeAppHelper testAppBottom,
+            UiDevice device, int beginRotation, Rational startRatio, Rational stopRatio) {
+        String testTag = "resizeSplitScreen_" + testAppTop.getLauncherName() + "_"
+                + testAppBottom.getLauncherName() + "_"
+                + startRatio.toString().replace("/", ":") + "_to_"
+                + stopRatio.toString().replace("/", ":") + "_"
+                + rotationToString(beginRotation);
         return TransitionRunner.newBuilder()
                 .withTag(testTag)
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
+                .runBeforeAll(() -> setRotation(device, beginRotation))
                 .runBeforeAll(() -> clearRecents(device))
                 .runBefore(testAppBottom::open)
                 .runBefore(device::pressHome)
@@ -231,9 +228,10 @@
                 .runBefore(() -> launchSplitScreen(device))
                 .runBefore(() -> {
                     UiObject2 snapshot = device.findObject(
-                            By.res("com.google.android.apps.nexuslauncher", "snapshot"));
+                            By.res(device.getLauncherPackageName(), "snapshot"));
                     snapshot.click();
                 })
+                .runBefore(() -> testAppBottom.clickEditTextWidget(device))
                 .runBefore(() -> AutomationUtils.resizeSplitScreen(device, startRatio))
                 .run(() -> AutomationUtils.resizeSplitScreen(device, stopRatio))
                 .runAfter(() -> exitSplitScreen(device))
@@ -243,77 +241,73 @@
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder editTextLoseFocusToHome(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "ImeApp");
+    static TransitionBuilder editTextLoseFocusToHome(ImeAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("editTextLoseFocusToHome_" + testApp.getLauncherName())
+                .withTag("editTextLoseFocusToHome_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
-                .runBefore(() -> clickEditTextWidget(device, testApp))
+                .runBefore(() -> testApp.clickEditTextWidget(device))
                 .run(device::pressHome)
                 .run(device::waitForIdle)
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder editTextLoseFocusToApp(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "ImeApp");
+    static TransitionBuilder editTextLoseFocusToApp(ImeAppHelper testApp, UiDevice device,
+            int beginRotation) {
         return TransitionRunner.newBuilder()
-                .withTag("editTextLoseFocusToApp_" + testApp.getLauncherName())
+                .withTag("editTextLoseFocusToApp_" + testApp.getLauncherName()
+                        + rotationToString(beginRotation))
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
+                .runBefore(() -> setRotation(device, beginRotation))
                 .runBefore(testApp::open)
-                .runBefore(() -> clickEditTextWidget(device, testApp))
+                .runBefore(() -> testApp.clickEditTextWidget(device))
                 .run(device::pressBack)
                 .run(device::waitForIdle)
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder enterPipMode(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "PipApp");
+    static TransitionBuilder enterPipMode(PipAppHelper testApp, UiDevice device) {
         return TransitionRunner.newBuilder()
                 .withTag("enterPipMode_" + testApp.getLauncherName())
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
                 .runBefore(testApp::open)
-                .run(() -> clickEnterPipButton(device, testApp))
+                .run(() -> testApp.clickEnterPipButton(device))
                 .runAfter(() -> closePipWindow(device))
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder exitPipModeToHome(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "PipApp");
+    static TransitionBuilder exitPipModeToHome(PipAppHelper testApp, UiDevice device) {
         return TransitionRunner.newBuilder()
                 .withTag("exitPipModeToHome_" + testApp.getLauncherName())
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
                 .runBefore(testApp::open)
-                .runBefore(() -> clickEnterPipButton(device, testApp))
+                .runBefore(() -> testApp.clickEnterPipButton(device))
                 .run(() -> closePipWindow(device))
                 .run(device::waitForIdle)
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
 
-    static TransitionBuilder exitPipModeToApp(UiDevice device) {
-        IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "PipApp");
+    static TransitionBuilder exitPipModeToApp(PipAppHelper testApp, UiDevice device) {
         return TransitionRunner.newBuilder()
                 .withTag("exitPipModeToApp_" + testApp.getLauncherName())
                 .runBeforeAll(AutomationUtils::wakeUpAndGoToHomeScreen)
                 .runBefore(device::pressHome)
                 .runBefore(testApp::open)
-                .runBefore(() -> clickEnterPipButton(device, testApp))
+                .runBefore(() -> testApp.clickEnterPipButton(device))
                 .run(() -> expandPipWindow(device))
                 .run(device::waitForIdle)
                 .runAfterAll(testApp::exit)
                 .repeat(ITERATIONS);
     }
-}
\ No newline at end of file
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
index 61cca0d..8f0177c 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/DebugTest.java
@@ -22,40 +22,50 @@
 import android.view.Surface;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
+import com.android.server.wm.flicker.helpers.PipAppHelper;
+
+import org.junit.FixMethodOrder;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 
 /**
  * Tests to help debug individual transitions, capture video recordings and create test cases.
  */
+@LargeTest
 @Ignore("Used for debugging transitions used in FlickerTests.")
 @RunWith(AndroidJUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class DebugTest {
     private IAppHelper testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
             "com.android.server.wm.flicker.testapp", "SimpleApp");
     private UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
 
     /**
-     * atest FlickerTest:DebugTests#openAppCold
+     * atest FlickerTests:DebugTest#openAppCold
      */
     @Test
     public void openAppCold() {
-        CommonTransitions.getOpenAppCold(testApp, uiDevice).recordAllRuns().build().run();
+        CommonTransitions.openAppCold(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run();
     }
 
     /**
-     * atest FlickerTest:DebugTests#openAppWarm
+     * atest FlickerTests:DebugTest#openAppWarm
      */
     @Test
     public void openAppWarm() {
-        CommonTransitions.openAppWarm(testApp, uiDevice).recordAllRuns().build().run();
+        CommonTransitions.openAppWarm(testApp, uiDevice, Surface.ROTATION_0)
+                .recordAllRuns().build().run();
     }
 
     /**
-     * atest FlickerTest:DebugTests#changeOrientationFromNaturalToLeft
+     * atest FlickerTests:DebugTest#changeOrientationFromNaturalToLeft
      */
     @Test
     public void changeOrientationFromNaturalToLeft() {
@@ -64,7 +74,7 @@
     }
 
     /**
-     * atest FlickerTest:DebugTests#closeAppWithBackKey
+     * atest FlickerTests:DebugTest#closeAppWithBackKey
      */
     @Test
     public void closeAppWithBackKey() {
@@ -72,7 +82,7 @@
     }
 
     /**
-     * atest FlickerTest:DebugTests#closeAppWithHomeKey
+     * atest FlickerTests:DebugTest#closeAppWithHomeKey
      */
     @Test
     public void closeAppWithHomeKey() {
@@ -80,7 +90,7 @@
     }
 
     /**
-     * atest FlickerTest:DebugTests#openAppToSplitScreen
+     * atest FlickerTests:DebugTest#openAppToSplitScreen
      */
     @Test
     public void openAppToSplitScreen() {
@@ -89,7 +99,7 @@
     }
 
     /**
-     * atest FlickerTest:DebugTests#splitScreenToLauncher
+     * atest FlickerTests:DebugTest#splitScreenToLauncher
      */
     @Test
     public void splitScreenToLauncher() {
@@ -99,70 +109,80 @@
     }
 
     /**
-     * atest FlickerTest:DebugTests#resizeSplitScreen
+     * atest FlickerTests:DebugTest#resizeSplitScreen
      */
     @Test
     public void resizeSplitScreen() {
-        IAppHelper bottomApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "ImeApp");
-        CommonTransitions.resizeSplitScreen(testApp, bottomApp, uiDevice, new Rational(1, 3),
-                new Rational(2, 3)).includeJankyRuns().recordEachRun().build().run();
+        ImeAppHelper bottomApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.resizeSplitScreen(testApp, bottomApp, uiDevice, Surface.ROTATION_0,
+                new Rational(1, 3), new Rational(2, 3))
+                .includeJankyRuns().recordEachRun().build().run();
     }
 
     // IME tests
 
     /**
-     * atest FlickerTest:DebugTests#editTextSetFocus
+     * atest FlickerTests:DebugTest#editTextSetFocus
      */
     @Test
     public void editTextSetFocus() {
-        CommonTransitions.editTextSetFocus(uiDevice).includeJankyRuns().recordEachRun()
+        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.editTextSetFocus(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().recordEachRun()
                 .build().run();
     }
 
     /**
-     * atest FlickerTest:DebugTests#editTextLoseFocusToHome
+     * atest FlickerTests:DebugTest#editTextLoseFocusToHome
      */
     @Test
     public void editTextLoseFocusToHome() {
-        CommonTransitions.editTextLoseFocusToHome(uiDevice).includeJankyRuns().recordEachRun()
+        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().recordEachRun()
                 .build().run();
     }
 
     /**
-     * atest FlickerTest:DebugTests#editTextLoseFocusToApp
+     * atest FlickerTests:DebugTest#editTextLoseFocusToApp
      */
     @Test
     public void editTextLoseFocusToApp() {
-        CommonTransitions.editTextLoseFocusToHome(uiDevice).includeJankyRuns().recordEachRun()
+        ImeAppHelper testApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.editTextLoseFocusToHome(testApp, uiDevice, Surface.ROTATION_0)
+                .includeJankyRuns().recordEachRun()
                 .build().run();
     }
 
     // PIP tests
 
     /**
-     * atest FlickerTest:DebugTests#enterPipMode
+     * atest FlickerTests:DebugTest#enterPipMode
      */
     @Test
     public void enterPipMode() {
-        CommonTransitions.enterPipMode(uiDevice).includeJankyRuns().recordEachRun().build().run();
-    }
-
-    /**
-     * atest FlickerTest:DebugTests#exitPipModeToHome
-     */
-    @Test
-    public void exitPipModeToHome() {
-        CommonTransitions.exitPipModeToHome(uiDevice).includeJankyRuns().recordEachRun()
+        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.enterPipMode(testApp, uiDevice).includeJankyRuns().recordEachRun()
                 .build().run();
     }
 
     /**
-     * atest FlickerTest:DebugTests#exitPipModeToApp
+     * atest FlickerTests:DebugTest#exitPipModeToHome
+     */
+    @Test
+    public void exitPipModeToHome() {
+        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.exitPipModeToHome(testApp, uiDevice).includeJankyRuns().recordEachRun()
+                .build().run();
+    }
+
+    /**
+     * atest FlickerTests:DebugTest#exitPipModeToApp
      */
     @Test
     public void exitPipModeToApp() {
-        CommonTransitions.exitPipModeToApp(uiDevice).includeJankyRuns().recordEachRun()
+        PipAppHelper testApp = new PipAppHelper(InstrumentationRegistry.getInstrumentation());
+        CommonTransitions.exitPipModeToApp(testApp, uiDevice).includeJankyRuns().recordEachRun()
                 .build().run();
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
index 8c9d6b4d..883d59e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/FlickerTestBase.java
@@ -16,20 +16,23 @@
 
 package com.android.server.wm.flicker;
 
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
 import static com.android.server.wm.flicker.helpers.AutomationUtils.setDefaultWait;
 
 import static com.google.common.truth.Truth.assertWithMessage;
 
+import android.os.Bundle;
 import android.platform.helpers.IAppHelper;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.UiDevice;
 import android.util.Log;
 
-import androidx.test.InstrumentationRegistry;
-
 import com.android.server.wm.flicker.TransitionRunner.TransitionResult;
 
 import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Before;
 
 import java.util.HashMap;
 import java.util.List;
@@ -51,10 +54,16 @@
     static final String DOCKED_STACK_DIVIDER = "DockedStackDivider";
     private static HashMap<String, List<TransitionResult>> transitionResults =
             new HashMap<>();
-    IAppHelper testApp;
-    UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
-    private List<TransitionResult> results;
-    private TransitionResult lastResult = null;
+    IAppHelper mTestApp;
+    UiDevice mUiDevice;
+    private List<TransitionResult> mResults;
+    private TransitionResult mLastResult = null;
+
+    @Before
+    public void setUp() {
+        InstrumentationRegistry.registerInstance(getInstrumentation(), new Bundle());
+        mUiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
+    }
 
     /**
      * Teardown any system settings and clean up test artifacts from the file system.
@@ -89,16 +98,23 @@
     /**
      * Runs a transition, returns a cached result if the transition has run before.
      */
-    void runTransition(TransitionRunner transition) {
+    void run(TransitionRunner transition) {
         if (transitionResults.containsKey(transition.getTestTag())) {
-            results = transitionResults.get(transition.getTestTag());
+            mResults = transitionResults.get(transition.getTestTag());
             return;
         }
-        results = transition.run().getResults();
+        mResults = transition.run().getResults();
         /* Fail if we don't have any results due to jank */
         assertWithMessage("No results to test because all transition runs were invalid because "
-                + "of Jank").that(results).isNotEmpty();
-        transitionResults.put(transition.getTestTag(), results);
+                + "of Jank").that(mResults).isNotEmpty();
+        transitionResults.put(transition.getTestTag(), mResults);
+    }
+
+    /**
+     * Runs a transition, returns a cached result if the transition has run before.
+     */
+    void runTransition(TransitionRunner transition) {
+        run(transition);
     }
 
     /**
@@ -106,11 +122,11 @@
      */
     void checkResults(Consumer<TransitionResult> assertion) {
 
-        for (TransitionResult result : results) {
-            lastResult = result;
+        for (TransitionResult result : mResults) {
+            mLastResult = result;
             assertion.accept(result);
         }
-        lastResult = null;
+        mLastResult = null;
     }
 
     /**
@@ -119,8 +135,8 @@
      */
     @After
     public void markArtifactsForSaving() {
-        if (lastResult != null) {
-            lastResult.flagForSaving();
+        if (mLastResult != null) {
+            mLastResult.flagForSaving();
         }
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
new file mode 100644
index 0000000..54941dc
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/NonRotationTestBase.java
@@ -0,0 +1,80 @@
+/*
+ * 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.flicker;
+
+import static android.view.Surface.rotationToString;
+
+import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
+
+import android.graphics.Rect;
+import android.view.Surface;
+
+import androidx.test.filters.FlakyTest;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class NonRotationTestBase extends FlickerTestBase {
+
+    int mBeginRotation;
+
+    public NonRotationTestBase(String beginRotationName, int beginRotation) {
+        this.mBeginRotation = beginRotation;
+    }
+
+    @Parameters(name = "{0}")
+    public static Collection<Object[]> getParams() {
+        int[] supportedRotations =
+                {Surface.ROTATION_0, Surface.ROTATION_90};
+        Collection<Object[]> params = new ArrayList<>();
+
+        for (int begin : supportedRotations) {
+            params.add(new Object[]{rotationToString(begin), begin});
+        }
+
+        return params;
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkCoveredRegion_noUncoveredRegions() {
+        Rect displayBounds = getDisplayBounds(mBeginRotation);
+        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
+                displayBounds).forAllEntries());
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_navBarLayerIsAlwaysVisible() {
+        checkResults(result -> LayersTraceSubject.assertThat(result)
+                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
+    }
+
+    @FlakyTest(bugId = 141361128)
+    @Ignore("Waiting bug feedback")
+    @Test
+    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
+        checkResults(result -> LayersTraceSubject.assertThat(result)
+                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
index 7818c4e..efdfaee 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppColdTest.java
@@ -16,91 +16,70 @@
 
 package com.android.server.wm.flicker;
 
-import static com.android.server.wm.flicker.CommonTransitions.getOpenAppCold;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
+import static com.android.server.wm.flicker.CommonTransitions.openAppCold;
 import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test cold launch app from launcher.
  * To run this test: {@code atest FlickerTests:OpenAppColdTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class OpenAppColdTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class OpenAppColdTest extends NonRotationTestBase {
 
-    public OpenAppColdTest() {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+    public OpenAppColdTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        super.runTransition(getOpenAppCold(testApp, uiDevice).build());
-    }
-
-    @Test
-    public void checkVisibility_navBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarWindowIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
+        run(openAppCold(mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns().build());
     }
 
     @Test
     public void checkVisibility_wallpaperWindowBecomesInvisible() {
         checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("wallpaper")
+                .showsBelowAppWindow("Wallpaper")
                 .then()
-                .hidesBelowAppWindow("wallpaper")
+                .hidesBelowAppWindow("Wallpaper")
                 .forAllEntries());
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
         checkResults(result -> assertThat(result)
                 .showsAppWindowOnTop(
-                        "com.google.android.apps.nexuslauncher/.NexusLauncherActivity")
+                        "com.android.launcher3/.Launcher")
                 .then()
-                .showsAppWindowOnTop(testApp.getPackage())
+                .showsAppWindowOnTop(mTestApp.getPackage())
                 .forAllEntries());
     }
 
     @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                getDisplayBounds()).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
     public void checkVisibility_wallpaperLayerBecomesInvisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("wallpaper")
+                .showsLayer("Wallpaper")
                 .then()
-                .hidesLayer("wallpaper")
+                .hidesLayer("Wallpaper")
                 .forAllEntries());
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
index 63018ec..f8b7938 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppToSplitScreenTest.java
@@ -24,8 +24,10 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 
 /**
  * Test open app to split screen.
@@ -33,16 +35,17 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class OpenAppToSplitScreenTest extends FlickerTestBase {
 
     public OpenAppToSplitScreenTest() {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        super.runTransition(appToSplitScreen(testApp, uiDevice).includeJankyRuns().build());
+        super.runTransition(appToSplitScreen(mTestApp, mUiDevice).includeJankyRuns().build());
     }
 
     @Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
index 1aba930..7ce6315 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenAppWarmTest.java
@@ -17,90 +17,69 @@
 package com.android.server.wm.flicker;
 
 import static com.android.server.wm.flicker.CommonTransitions.openAppWarm;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
 import static com.android.server.wm.flicker.WmTraceSubject.assertThat;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test warm launch app.
  * To run this test: {@code atest FlickerTests:OpenAppWarmTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class OpenAppWarmTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class OpenAppWarmTest extends NonRotationTestBase {
 
-    public OpenAppWarmTest() {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+    public OpenAppWarmTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        super.runTransition(openAppWarm(testApp, uiDevice).build());
-    }
-
-    @Test
-    public void checkVisibility_navBarIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarIsAlwaysVisible() {
-        checkResults(result -> assertThat(result)
-                .showsAboveAppWindow(STATUS_BAR_WINDOW_TITLE).forAllEntries());
+        super.runTransition(openAppWarm(mTestApp, mUiDevice, mBeginRotation)
+                .includeJankyRuns().build());
     }
 
     @Test
     public void checkVisibility_wallpaperBecomesInvisible() {
         checkResults(result -> assertThat(result)
-                .showsBelowAppWindow("wallpaper")
+                .showsBelowAppWindow("Wallpaper")
                 .then()
-                .hidesBelowAppWindow("wallpaper")
+                .hidesBelowAppWindow("Wallpaper")
                 .forAllEntries());
     }
 
+    @FlakyTest(bugId = 140855415)
+    @Ignore("Waiting bug feedback")
     @Test
     public void checkZOrder_appWindowReplacesLauncherAsTopWindow() {
         checkResults(result -> assertThat(result)
                 .showsAppWindowOnTop(
-                        "com.google.android.apps.nexuslauncher/.NexusLauncherActivity")
+                        "com.android.launcher3/.Launcher")
                 .then()
-                .showsAppWindowOnTop(testApp.getPackage())
+                .showsAppWindowOnTop(mTestApp.getPackage())
                 .forAllEntries());
     }
 
     @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                getDisplayBounds()).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE).forAllEntries());
-    }
-
-    @Test
     public void checkVisibility_wallpaperLayerBecomesInvisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("wallpaper")
+                .showsLayer("Wallpaper")
                 .then()
-                .hidesLayer("wallpaper")
+                .hidesLayer("Wallpaper")
                 .forAllEntries());
     }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
index a81fa8e..91d4a05 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/OpenImeWindowTest.java
@@ -17,28 +17,39 @@
 package com.android.server.wm.flicker;
 
 import static com.android.server.wm.flicker.CommonTransitions.editTextSetFocus;
-import static com.android.server.wm.flicker.WindowUtils.getDisplayBounds;
 
+import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test IME window opening transitions.
  * To run this test: {@code atest FlickerTests:OpenImeWindowTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class OpenImeWindowTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class OpenImeWindowTest extends NonRotationTestBase {
 
     private static final String IME_WINDOW_TITLE = "InputMethod";
 
+    public OpenImeWindowTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        mTestApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+    }
+
     @Before
     public void runTransition() {
-        super.runTransition(editTextSetFocus(uiDevice)
+        run(editTextSetFocus((ImeAppHelper) mTestApp, mUiDevice, mBeginRotation)
                 .includeJankyRuns().build());
     }
 
@@ -59,10 +70,4 @@
                 .showsLayer(IME_WINDOW_TITLE)
                 .forAllEntries());
     }
-
-    @Test
-    public void checkCoveredRegion_noUncoveredRegions() {
-        checkResults(result -> LayersTraceSubject.assertThat(result).coversRegion(
-                getDisplayBounds()).forAllEntries());
-    }
 }
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
index 50dba81..29b6240 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/ResizeSplitScreenTest.java
@@ -24,64 +24,62 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.graphics.Rect;
-import android.platform.helpers.IAppHelper;
 import android.util.Rational;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.FlakyTest;
 import androidx.test.filters.LargeTest;
-import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.wm.flicker.helpers.ImeAppHelper;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
 
 /**
  * Test split screen resizing window transitions.
  * To run this test: {@code atest FlickerTests:ResizeSplitScreenTest}
  */
 @LargeTest
-@RunWith(AndroidJUnit4.class)
-public class ResizeSplitScreenTest extends FlickerTestBase {
+@RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 140854698)
+@Ignore("Waiting bug feedback")
+public class ResizeSplitScreenTest extends NonRotationTestBase {
 
-    public ResizeSplitScreenTest() {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+    private static String sSimpleActivity = "SimpleActivity";
+    private static String sImeActivity = "ImeActivity";
+
+    public ResizeSplitScreenTest(String beginRotationName, int beginRotation) {
+        super(beginRotationName, beginRotation);
+
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        IAppHelper bottomApp = new StandardAppHelper(InstrumentationRegistry
-                .getInstrumentation(),
-                "com.android.server.wm.flicker.testapp", "ImeApp");
-        super.runTransition(resizeSplitScreen(testApp, bottomApp, uiDevice, new Rational(1, 3),
-                new Rational(2, 3)).includeJankyRuns().build());
-    }
-
-    @Test
-    public void checkVisibility_navBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(NAVIGATION_BAR_WINDOW_TITLE)
-                .forAllEntries());
-    }
-
-    @Test
-    public void checkVisibility_statusBarLayerIsAlwaysVisible() {
-        checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(STATUS_BAR_WINDOW_TITLE)
-                .forAllEntries());
+        ImeAppHelper bottomApp = new ImeAppHelper(InstrumentationRegistry.getInstrumentation());
+        run(resizeSplitScreen(mTestApp, bottomApp, mUiDevice, mBeginRotation,
+                new Rational(1, 3), new Rational(2, 3))
+                .includeJankyRuns().build());
     }
 
     @Test
     public void checkVisibility_topAppLayerIsAlwaysVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("SimpleActivity")
+                .showsLayer(sSimpleActivity)
                 .forAllEntries());
     }
 
     @Test
     public void checkVisibility_bottomAppLayerIsAlwaysVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer("ImeActivity")
+                .showsLayer(sImeActivity)
                 .forAllEntries());
     }
 
@@ -142,11 +140,11 @@
                     displayBounds.bottom - getNavigationBarHeight());
 
             LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("SimpleActivity", startingTopAppBounds)
+                    .hasVisibleRegion(sSimpleActivity, startingTopAppBounds)
                     .atTheEnd();
 
             LayersTraceSubject.assertThat(result)
-                    .hasVisibleRegion("ImeActivity", startingBottomAppBounds)
+                    .hasVisibleRegion(sImeActivity, startingBottomAppBounds)
                     .atTheEnd();
         });
     }
@@ -168,14 +166,14 @@
     @Test
     public void checkVisibility_topAppWindowIsAlwaysVisible() {
         checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow("SimpleActivity")
+                .showsAppWindow(sSimpleActivity)
                 .forAllEntries());
     }
 
     @Test
     public void checkVisibility_bottomAppWindowIsAlwaysVisible() {
         checkResults(result -> WmTraceSubject.assertThat(result)
-                .showsAppWindow("ImeActivity")
+                .showsAppWindow(sImeActivity)
                 .forAllEntries());
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
index 117ac5a..ae55a75 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SeamlessAppRotationTest.java
@@ -33,8 +33,10 @@
 import androidx.test.filters.LargeTest;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 
@@ -47,6 +49,7 @@
  */
 @LargeTest
 @RunWith(Parameterized.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class SeamlessAppRotationTest extends FlickerTestBase {
     private int mBeginRotation;
     private int mEndRotation;
@@ -105,7 +108,7 @@
 
         super.runTransition(
                 changeAppRotation(mIntent, intentId, InstrumentationRegistry.getContext(),
-                        uiDevice, mBeginRotation, mEndRotation).repeat(5).build());
+                        mUiDevice, mBeginRotation, mEndRotation).repeat(5).build());
     }
 
     @Test
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
index 1d30df9..85a1494 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/SplitScreenToLauncherTest.java
@@ -25,8 +25,11 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
 
 /**
  * Test open app to split screen.
@@ -34,16 +37,19 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@FlakyTest(bugId = 140856143)
+@Ignore("Waiting bug feedback")
 public class SplitScreenToLauncherTest extends FlickerTestBase {
 
     public SplitScreenToLauncherTest() {
-        this.testApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
+        this.mTestApp = new StandardAppHelper(InstrumentationRegistry.getInstrumentation(),
                 "com.android.server.wm.flicker.testapp", "SimpleApp");
     }
 
     @Before
     public void runTransition() {
-        super.runTransition(splitScreenToLauncher(testApp, uiDevice).includeJankyRuns().build());
+        super.runTransition(splitScreenToLauncher(mTestApp, mUiDevice).includeJankyRuns().build());
     }
 
     @Test
@@ -62,13 +68,12 @@
                 .forAllEntries());
     }
 
-    @FlakyTest(bugId = 79686616)
     @Test
     public void checkVisibility_appLayerBecomesInVisible() {
         checkResults(result -> LayersTraceSubject.assertThat(result)
-                .showsLayer(testApp.getPackage())
+                .showsLayer(mTestApp.getPackage())
                 .then()
-                .hidesLayer(testApp.getPackage())
+                .hidesLayer(mTestApp.getPackage())
                 .forAllEntries());
     }
 
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/StandardAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/StandardAppHelper.java
deleted file mode 100644
index 79a0220..0000000
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/StandardAppHelper.java
+++ /dev/null
@@ -1,59 +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.server.wm.flicker;
-
-import android.app.Instrumentation;
-import android.platform.helpers.AbstractStandardAppHelper;
-
-/**
- * Class to take advantage of {@code IAppHelper} interface so the same test can be run against
- * first party and third party apps.
- */
-public class StandardAppHelper extends AbstractStandardAppHelper {
-    private final String mPackageName;
-    private final String mLauncherName;
-
-    public StandardAppHelper(Instrumentation instr, String packageName, String launcherName) {
-        super(instr);
-        mPackageName = packageName;
-        mLauncherName = launcherName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getPackage() {
-        return mPackageName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public String getLauncherName() {
-        return mLauncherName;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public void dismissInitialDialogs() {
-
-    }
-}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
new file mode 100644
index 0000000..42977f5
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/FlickerAppHelper.java
@@ -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 com.android.server.wm.flicker.helpers;
+
+import android.app.Instrumentation;
+
+import com.android.server.wm.flicker.StandardAppHelper;
+
+public abstract class FlickerAppHelper extends StandardAppHelper {
+
+    static int sFindTimeout = 10000;
+    static String sFlickerPackage = "com.android.server.wm.flicker.testapp";
+
+    public FlickerAppHelper(Instrumentation instr, String launcherName) {
+        super(instr, sFlickerPackage, launcherName);
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
new file mode 100644
index 0000000..56e1118
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppAutoFocusHelper.java
@@ -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 com.android.server.wm.flicker.helpers;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.UiDevice;
+
+public class ImeAppAutoFocusHelper extends ImeAppHelper {
+
+    public ImeAppAutoFocusHelper(Instrumentation instr) {
+        super(instr, "ImeAppAutoFocus");
+    }
+
+    public void clickEditTextWidget(UiDevice device) {
+        // do nothing (the app is focused automatically)
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
new file mode 100644
index 0000000..098fd6d
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/ImeAppHelper.java
@@ -0,0 +1,41 @@
+/*
+ * 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.flicker.helpers;
+
+import static android.os.SystemClock.sleep;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+
+public class ImeAppHelper extends FlickerAppHelper {
+
+    ImeAppHelper(Instrumentation instr, String launcherName) {
+        super(instr, launcherName);
+    }
+
+    public ImeAppHelper(Instrumentation instr) {
+        this(instr, "ImeApp");
+    }
+
+    public void clickEditTextWidget(UiDevice device) {
+        UiObject2 editText = device.findObject(By.res(getPackage(), "plain_text_input"));
+        editText.click();
+        sleep(500);
+    }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
new file mode 100644
index 0000000..d00e11b
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/helpers/PipAppHelper.java
@@ -0,0 +1,43 @@
+/*
+ * 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.flicker.helpers;
+
+import static com.android.server.wm.flicker.helpers.AutomationUtils.getPipWindowSelector;
+
+import android.app.Instrumentation;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+public class PipAppHelper extends FlickerAppHelper {
+
+    public PipAppHelper(Instrumentation instr) {
+        super(instr, "PipApp");
+    }
+
+    public void clickEnterPipButton(UiDevice device) {
+        UiObject2 enterPipButton = device.findObject(By.res(getPackage(), "enter_pip"));
+        enterPipButton.click();
+        UiObject2 pipWindow = device.wait(Until.findObject(getPipWindowSelector()), sFindTimeout);
+
+        if (pipWindow == null) {
+            throw new RuntimeException("Unable to find PIP window");
+        }
+    }
+
+}
diff --git a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
index b694172..0fe9682 100644
--- a/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/AndroidManifest.xml
@@ -38,6 +38,15 @@
                 <category android:name="android.intent.category.LAUNCHER"/>
             </intent-filter>
         </activity>
+        <activity android:name=".ImeActivityAutoFocus"
+                  android:taskAffinity="com.android.server.wm.flicker.testapp.ImeActivityAutoFocus"
+                  android:windowSoftInputMode="stateVisible"
+                  android:label="ImeAppAutoFocus">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.LAUNCHER"/>
+            </intent-filter>
+        </activity>
         <activity android:name=".PipActivity"
                   android:resizeableActivity="true"
                   android:supportsPictureInPicture="true"
diff --git a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
index d5eb023..4708cfd 100644
--- a/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
+++ b/tests/FlickerTests/test-apps/flickerapp/res/layout/activity_ime.xml
@@ -18,6 +18,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    android:focusableInTouchMode="true"
     android:background="@android:color/holo_green_light">
     <EditText android:id="@+id/plain_text_input"
               android:layout_height="wrap_content"
diff --git a/services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
similarity index 65%
rename from services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl
rename to tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
index 6f006d4..05da717 100644
--- a/services/net/java/android/net/NattKeepalivePacketDataParcelable.aidl
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/ImeActivityAutoFocus.java
@@ -14,12 +14,17 @@
  * limitations under the License.
  */
 
-package android.net;
+package com.android.server.wm.flicker.testapp;
 
-parcelable NattKeepalivePacketDataParcelable {
-    byte[] srcAddress;
-    int srcPort;
-    byte[] dstAddress;
-    int dstPort;
+import android.widget.EditText;
+
+public class ImeActivityAutoFocus extends ImeActivity {
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+
+        EditText editTextField = findViewById(R.id.plain_text_input);
+        editTextField.requestFocus();
+    }
 }
-
diff --git a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
index 3a0c1c9..5cf81cb 100644
--- a/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
+++ b/tests/FlickerTests/test-apps/flickerapp/src/com/android/server/wm/flicker/testapp/SeamlessRotationActivity.java
@@ -17,7 +17,6 @@
 package com.android.server.wm.flicker.testapp;
 
 import static android.os.SystemClock.sleep;
-import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
 
 import static com.android.server.wm.flicker.testapp.ActivityOptions.EXTRA_STARVE_UI_THREAD;
 
@@ -39,8 +38,8 @@
         super.onCreate(savedInstanceState);
         enableSeamlessRotation();
         setContentView(R.layout.activity_simple);
-        boolean starveUiThread = getIntent().getExtras() != null &&
-                getIntent().getExtras().getBoolean(EXTRA_STARVE_UI_THREAD);
+        boolean starveUiThread = getIntent().getExtras() != null
+                && getIntent().getExtras().getBoolean(EXTRA_STARVE_UI_THREAD);
         if (starveUiThread) {
             starveUiThread();
         }
diff --git a/tests/libs-permissions/Android.bp b/tests/libs-permissions/Android.bp
index c7c4b10..330bfc9 100644
--- a/tests/libs-permissions/Android.bp
+++ b/tests/libs-permissions/Android.bp
@@ -14,16 +14,16 @@
 }
 
 java_library {
-    name: "com.android.test.libs.product_services",
+    name: "com.android.test.libs.system_ext",
     installable: true,
-    product_services_specific: true,
-    srcs: ["product_services/java/**/*.java"],
-    required: ["com.android.test.libs.product_services.xml"],
+    system_ext_specific: true,
+    srcs: ["system_ext/java/**/*.java"],
+    required: ["com.android.test.libs.system_ext.xml"],
 }
 
 prebuilt_etc {
-    name: "com.android.test.libs.product_services.xml",
-    src: "product_services/com.android.test.libs.product_services.xml",
+    name: "com.android.test.libs.system_ext.xml",
+    src: "system_ext/com.android.test.libs.system_ext.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
similarity index 81%
rename from tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
rename to tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
index 082a9be..fa56004 100644
--- a/tests/libs-permissions/product_services/com.android.test.libs.product_services.xml
+++ b/tests/libs-permissions/system_ext/com.android.test.libs.system_ext.xml
@@ -15,6 +15,6 @@
 -->
 
 <permissions>
-    <library name="com.android.test.libs.product_services"
-            file="/product_services/framework/com.android.test.libs.product_services.jar" />
+    <library name="com.android.test.libs.system_ext"
+            file="/system_ext/framework/com.android.test.libs.system_ext.jar" />
 </permissions>
diff --git a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
similarity index 84%
rename from tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
rename to tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
index dcbdae8..9999aba 100644
--- a/tests/libs-permissions/product_services/java/com/android/test/libs/product_services/LibsProductServicesTest.java
+++ b/tests/libs-permissions/system_ext/java/com/android/test/libs/system_ext/LibsSystemExtTest.java
@@ -14,12 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.test.libs.product_services;
+package com.android.test.libs.system_ext;
 
 /**
- * Test class for product_services libs.
+ * Test class for system_ext libs.
  */
-public class LibsProductServicesTest {
+public class LibsSystemExtTest {
 
     /**
      * Dummy method for testing.
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index f2f258a..9e21db7 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -504,6 +504,8 @@
             // Waits for the NetworkAgent to be registered, which includes the creation of the
             // NetworkMonitor.
             waitForIdle(TIMEOUT_MS);
+            HandlerUtilsKt.waitForIdle(mCsHandlerThread, TIMEOUT_MS);
+            HandlerUtilsKt.waitForIdle(ConnectivityThread.get(), TIMEOUT_MS);
         }
 
         @Override
@@ -4315,16 +4317,16 @@
         assertFalse(mCm.isNetworkSupported(TYPE_NONE));
 
         assertThrows(IllegalArgumentException.class,
-                () -> { mCm.networkCapabilitiesForType(TYPE_NONE); });
+                () -> mCm.networkCapabilitiesForType(TYPE_NONE));
 
         Class<UnsupportedOperationException> unsupported = UnsupportedOperationException.class;
-        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_WIFI, ""); });
-        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_WIFI, ""); });
+        assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_WIFI, ""));
+        assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_WIFI, ""));
         // TODO: let test context have configuration application target sdk version
         // and test that pre-M requesting for TYPE_NONE sends back APN_REQUEST_FAILED
-        assertThrows(unsupported, () -> { mCm.startUsingNetworkFeature(TYPE_NONE, ""); });
-        assertThrows(unsupported, () -> { mCm.stopUsingNetworkFeature(TYPE_NONE, ""); });
-        assertThrows(unsupported, () -> { mCm.requestRouteToHostAddress(TYPE_NONE, null); });
+        assertThrows(unsupported, () -> mCm.startUsingNetworkFeature(TYPE_NONE, ""));
+        assertThrows(unsupported, () -> mCm.stopUsingNetworkFeature(TYPE_NONE, ""));
+        assertThrows(unsupported, () -> mCm.requestRouteToHostAddress(TYPE_NONE, null));
     }
 
     @Test
diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
index cd2bd26..7029218 100644
--- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java
@@ -561,11 +561,17 @@
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{SYSTEM_UID1});
     }
 
-    private PackageInfo addPackage(String packageName, int uid, String[] permissions)
+    private PackageInfo setPackagePermissions(String packageName, int uid, String[] permissions)
             throws Exception {
         PackageInfo packageInfo = packageInfoWithPermissions(permissions, PARTITION_SYSTEM);
         when(mPackageManager.getPackageInfo(eq(packageName), anyInt())).thenReturn(packageInfo);
         when(mPackageManager.getPackagesForUid(eq(uid))).thenReturn(new String[]{packageName});
+        return packageInfo;
+    }
+
+    private PackageInfo addPackage(String packageName, int uid, String[] permissions)
+            throws Exception {
+        PackageInfo packageInfo = setPackagePermissions(packageName, uid, permissions);
         mObserver.onPackageAdded(packageName, uid);
         return packageInfo;
     }
@@ -616,14 +622,13 @@
     }
 
     @Test
-    public void testPackageUpdate() throws Exception {
+    public void testPackageRemoveThenAdd() throws Exception {
         final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
 
         addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET, UPDATE_DEVICE_STATS});
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET
                 | INetd.PERMISSION_UPDATE_DEVICE_STATS, new int[]{MOCK_UID1});
 
-        // Remove and install the same package to simulate the update action
         when(mPackageManager.getPackagesForUid(MOCK_UID1)).thenReturn(new String[]{});
         mObserver.onPackageRemoved(MOCK_PACKAGE1, MOCK_UID1);
         mNetdServiceMonitor.expectPermission(INetd.PERMISSION_UNINSTALLED, new int[]{MOCK_UID1});
@@ -633,6 +638,20 @@
     }
 
     @Test
+    public void testPackageUpdate() throws Exception {
+        final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
+
+        addPackage(MOCK_PACKAGE1, MOCK_UID1, new String[] {});
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_NONE, new int[]{MOCK_UID1});
+
+        // When updating a package, the broadcast receiver gets two broadcasts (a remove and then an
+        // add), but the observer sees only one callback (an update).
+        setPackagePermissions(MOCK_PACKAGE1, MOCK_UID1, new String[] {INTERNET});
+        mObserver.onPackageChanged(MOCK_PACKAGE1, MOCK_UID1);
+        mNetdServiceMonitor.expectPermission(INetd.PERMISSION_INTERNET, new int[]{MOCK_UID1});
+    }
+
+    @Test
     public void testPackageUninstallWithMultiplePackages() throws Exception {
         final NetdServiceMonitor mNetdServiceMonitor = new NetdServiceMonitor(mNetdService);
 
diff --git a/tests/privapp-permissions/Android.bp b/tests/privapp-permissions/Android.bp
index ca7864f..b661850 100644
--- a/tests/privapp-permissions/Android.bp
+++ b/tests/privapp-permissions/Android.bp
@@ -45,17 +45,17 @@
 }
 
 android_app {
-    name: "ProductServicesPrivAppPermissionTest",
+    name: "SystemExtPrivAppPermissionTest",
     sdk_version: "current",
     privileged: true,
-    manifest: "product_services/AndroidManifest.xml",
-    product_services_specific: true,
-    required: ["product_servicesprivapp-permissions-test.xml"],
+    manifest: "system_ext/AndroidManifest.xml",
+    system_ext_specific: true,
+    required: ["system_extprivapp-permissions-test.xml"],
 }
 
 prebuilt_etc {
-    name: "product_servicesprivapp-permissions-test.xml",
-    src: "product_services/privapp-permissions-test.xml",
+    name: "system_extprivapp-permissions-test.xml",
+    src: "system_ext/privapp-permissions-test.xml",
     sub_dir: "permissions",
-    product_services_specific: true,
+    system_ext_specific: true,
 }
diff --git a/tests/privapp-permissions/product_services/AndroidManifest.xml b/tests/privapp-permissions/system_ext/AndroidManifest.xml
similarity index 97%
rename from tests/privapp-permissions/product_services/AndroidManifest.xml
rename to tests/privapp-permissions/system_ext/AndroidManifest.xml
index 511ddee..4a0e82f 100644
--- a/tests/privapp-permissions/product_services/AndroidManifest.xml
+++ b/tests/privapp-permissions/system_ext/AndroidManifest.xml
@@ -16,7 +16,7 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-          package="com.android.framework.permission.privapp.tests.product_services">
+          package="com.android.framework.permission.privapp.tests.system_ext">
 
     <!-- MANAGE_USB is signature|privileged -->
     <uses-permission android:name="android.permission.MANAGE_USB"/>
diff --git a/tests/privapp-permissions/product_services/privapp-permissions-test.xml b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
similarity index 85%
rename from tests/privapp-permissions/product_services/privapp-permissions-test.xml
rename to tests/privapp-permissions/system_ext/privapp-permissions-test.xml
index 43baebb..ad63e86 100644
--- a/tests/privapp-permissions/product_services/privapp-permissions-test.xml
+++ b/tests/privapp-permissions/system_ext/privapp-permissions-test.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <permissions>
-    <privapp-permissions package="com.android.framework.permission.privapp.tests.product_services">
+    <privapp-permissions package="com.android.framework.permission.privapp.tests.system_ext">
         <permission name="android.permission.MANAGE_USB"/>
     </privapp-permissions>
 </permissions>
diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp
index 213bdd2..7966ba2 100644
--- a/tools/aapt2/Main.cpp
+++ b/tools/aapt2/Main.cpp
@@ -177,6 +177,11 @@
   return main_command->Execute(args, &std::cerr);
 }
 
+// TODO(b/141312058) stop leaks
+extern "C" const char *__asan_default_options() {
+    return "detect_leaks=0";
+}
+
 int main(int argc, char** argv) {
 #ifdef _WIN32
   LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &argc);