diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 58a3bb4..1e8ab05 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -6907,10 +6907,6 @@
                     android:resource="@xml/autofill_compat_accessibility_service" />
         </service>
 
-        <service android:name="com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy"
-                 android:permission="android.permission.BIND_JOB_SERVICE" >
-        </service>
-
         <service android:name="com.android.server.blob.BlobStoreIdleJobService"
                  android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
diff --git a/services/Android.bp b/services/Android.bp
index 2e4405f..c9d7ca2 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -106,7 +106,6 @@
         ":services.selectiontoolbar-sources",
         ":services.smartspace-sources",
         ":services.speech-sources",
-        ":services.startop.iorap-sources",
         ":services.systemcaptions-sources",
         ":services.translation-sources",
         ":services.texttospeech-sources",
@@ -163,7 +162,6 @@
         "services.selectiontoolbar",
         "services.smartspace",
         "services.speech",
-        "services.startop",
         "services.systemcaptions",
         "services.translation",
         "services.texttospeech",
@@ -216,7 +214,6 @@
         " --hide-annotation android.annotation.Hide" +
         " --hide InternalClasses" + // com.android.* classes are okay in this interface
         // TODO: remove the --hide options below
-        " --hide-package com.google.android.startop.iorap" +
         " --hide DeprecationMismatch" +
         " --hide HiddenTypedefConstant",
     visibility: ["//frameworks/base:__subpackages__"],
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 5098abe..1360fad 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -214,8 +214,6 @@
 
 import dalvik.system.VMRuntime;
 
-import com.google.android.startop.iorap.IorapForwardingService;
-
 import java.io.File;
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -1642,10 +1640,6 @@
             mSystemServiceManager.startService(PinnerService.class);
             t.traceEnd();
 
-            t.traceBegin("IorapForwardingService");
-            mSystemServiceManager.startService(IorapForwardingService.class);
-            t.traceEnd();
-
             if (Build.IS_DEBUGGABLE && ProfcollectForwardingService.enabled()) {
                 t.traceBegin("ProfcollectForwardingService");
                 mSystemServiceManager.startService(ProfcollectForwardingService.class);
diff --git a/services/startop/Android.bp b/services/startop/Android.bp
deleted file mode 100644
index c56c463..0000000
--- a/services/startop/Android.bp
+++ /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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    //   SPDX-license-identifier-MIT
-    //   SPDX-license-identifier-Unicode-DFS
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library_static {
-    name: "services.startop",
-    defaults: ["platform_service_defaults"],
-
-    static_libs: [
-        // frameworks/base/startop/iorap
-        "services.startop.iorap",
-    ],
-}
diff --git a/startop/iorap/Android.bp b/startop/iorap/Android.bp
deleted file mode 100644
index 4fdf34c..0000000
--- a/startop/iorap/Android.bp
+++ /dev/null
@@ -1,44 +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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-filegroup {
-  name: "services.startop.iorap-javasources",
-  srcs: ["src/**/*.java"],
-  path: "src",
-  visibility: ["//visibility:private"],
-}
-
-filegroup {
-  name: "services.startop.iorap-sources",
-  srcs: [
-    ":services.startop.iorap-javasources",
-    ":iorap-aidl",
-  ],
-  visibility: ["//frameworks/base/services:__subpackages__"],
-}
-
-java_library_static {
-  name: "services.startop.iorap",
-  srcs: [":services.startop.iorap-sources"],
-  libs: ["services.core"],
-}
diff --git a/startop/iorap/TEST_MAPPING b/startop/iorap/TEST_MAPPING
deleted file mode 100644
index 8c9d4df..0000000
--- a/startop/iorap/TEST_MAPPING
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "presubmit": [
-    {
-      "name": "libiorap-java-tests"
-    }
-  ],
-  "imports": [
-    {
-      "path": "system/iorap"
-    }
-  ]
-}
diff --git a/startop/iorap/functional_tests/Android.bp b/startop/iorap/functional_tests/Android.bp
deleted file mode 100644
index 43c6155..0000000
--- a/startop/iorap/functional_tests/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2020 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-android_test {
-    name: "iorap-functional-tests",
-    srcs: ["src/**/*.java"],
-    data: [":iorap-functional-test-apps"],
-    static_libs: [
-        // Non-test dependencies
-        // library under test
-        "services.startop.iorap",
-        // Test Dependencies
-        // test android dependencies
-        "platform-test-annotations",
-        "androidx.test.rules",
-        "androidx.test.ext.junit",
-        "androidx.test.uiautomator_uiautomator",
-        // test framework dependencies
-        "truth-prebuilt",
-    ],
-    dxflags: ["--multi-dex"],
-    test_suites: ["device-tests"],
-    compile_multilib: "both",
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    certificate: "platform",
-    platform_apis: true,
-}
diff --git a/startop/iorap/functional_tests/AndroidManifest.xml b/startop/iorap/functional_tests/AndroidManifest.xml
deleted file mode 100644
index 6bddc4a3..0000000
--- a/startop/iorap/functional_tests/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.startop.iorap.tests"
-    android:sharedUserId="com.google.android.startop.iorap.tests.functional"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <!--suppress AndroidDomInspection -->
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.google.android.startop.iorap.tests" />
-
-      <!--
-       'debuggable=true' is required to properly load mockito jvmti dependencies,
-         otherwise it gives the following error at runtime:
-
-       Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
-       Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-</manifest>
diff --git a/startop/iorap/functional_tests/AndroidTest.xml b/startop/iorap/functional_tests/AndroidTest.xml
deleted file mode 100644
index 31d4f6c..0000000
--- a/startop/iorap/functional_tests/AndroidTest.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2020 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="Runs iorap-functional-tests.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-instrumentation" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="iorap-functional-tests.apk" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
-
-    <target_preparer
-        class="com.android.tradefed.targetprep.DeviceSetup">
-
-        <!-- iorapd does not pick up the above changes until we restart it -->
-        <option name="run-command" value="stop iorapd" />
-
-        <!-- Clean up the existing iorap database. -->
-        <option name="run-command" value="rm -r /data/misc/iorapd/*" />
-        <option name="run-command" value="sleep 1" />
-
-        <!-- Set system properties to enable perfetto tracing, readahead and detailed logging. -->
-        <option name="run-command" value="setprop iorapd.perfetto.enable true" />
-        <option name="run-command" value="setprop iorapd.readahead.enable true" />
-        <option name="run-command" value="setprop iorapd.log.verbose true" />
-
-        <option name="run-command" value="start iorapd" />
-
-        <!-- give it some time to restart the service; otherwise the first unit test might fail -->
-        <option name="run-command" value="sleep 1" />
-    </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="abort-on-push-failure" value="true" />
-        <option name="push-file"
-          key="iorap_test_app_v1.apk"
-          value="/data/misc/iorapd/iorap_test_app_v1.apk" />
-        <option name="push-file"
-          key="iorap_test_app_v2.apk"
-          value="/data/misc/iorapd/iorap_test_app_v2.apk" />
-        <option name="push-file"
-          key="iorap_test_app_v3.apk"
-          value="/data/misc/iorapd/iorap_test_app_v3.apk" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.google.android.startop.iorap.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-        <!-- test-timeout unit is ms, value = 30 min -->
-        <option name="test-timeout" value="1800000" />
-    </test>
-
-</configuration>
-
diff --git a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java b/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
deleted file mode 100644
index 5352be6..0000000
--- a/startop/iorap/functional_tests/src/com/google/android/startop/iorap/IorapWorkFlowTest.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2020 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.google.android.startop.iorapd;
-
-import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
-import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
-
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.util.Log;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.uiautomator.By;
-import androidx.test.uiautomator.UiDevice;
-import androidx.test.uiautomator.Until;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.Date;
-import java.util.function.BooleanSupplier;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.List;
-import java.text.SimpleDateFormat;
-
-/**
- * Test for the work flow of iorap.
- *
- * <p> This test tests the function of iorap from:
- * perfetto collection -> compilation ->  prefetching -> version update -> perfetto collection.
- */
-@RunWith(AndroidJUnit4.class)
-public class IorapWorkFlowTest {
-  private static final String TAG = "IorapWorkFlowTest";
-
-  private static final String TEST_APP_VERSION_ONE_PATH = "/data/misc/iorapd/iorap_test_app_v1.apk";
-  private static final String TEST_APP_VERSION_TWO_PATH = "/data/misc/iorapd/iorap_test_app_v2.apk";
-  private static final String TEST_APP_VERSION_THREE_PATH = "/data/misc/iorapd/iorap_test_app_v3.apk";
-
-  private static final String DB_PATH = "/data/misc/iorapd/sqlite.db";
-  private static final Duration TIMEOUT = Duration.ofSeconds(300L);
-
-  private UiDevice mDevice;
-
-  @Before
-  public void setUp() throws Exception {
-    // Initialize UiDevice instance
-    mDevice = UiDevice.getInstance(getInstrumentation());
-
-    // Start from the home screen
-    mDevice.pressHome();
-
-    // Wait for launcher
-    final String launcherPackage = mDevice.getLauncherPackageName();
-    assertThat(launcherPackage, notNullValue());
-    mDevice.wait(Until.hasObject(By.pkg(launcherPackage).depth(0)), TIMEOUT.getSeconds());
-  }
-
-  @After
-  public void tearDown() throws Exception {
-    String packageName = "com.example.ioraptestapp";
-    uninstallApk(packageName);
-  }
-
-  @Test (timeout = 300000)
-  public void testNormalWorkFlow() throws Exception {
-    assertThat(mDevice, notNullValue());
-
-    // Install test app version one
-    installApk(TEST_APP_VERSION_ONE_PATH);
-    String packageName = "com.example.ioraptestapp";
-    String activityName = "com.example.ioraptestapp.MainActivity";
-
-    // Perfetto trace collection phase.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/1L));
-
-    // Trigger maintenance service for compilation.
-    TimeUnit.SECONDS.sleep(5L);
-    assertTrue(compile(packageName, activityName, /*version=*/1L));
-
-    // Run app with prefetching
-    assertTrue(startAppWithCompiledTrace(
-        packageName, activityName, /*version=*/1L));
-  }
-
-  @Test (timeout = 300000)
-  public void testUpdateApp() throws Exception {
-    assertThat(mDevice, notNullValue());
-
-    // Install test app version two,
-    String packageName = "com.example.ioraptestapp";
-    String activityName = "com.example.ioraptestapp.MainActivity";
-    installApk(TEST_APP_VERSION_TWO_PATH);
-
-    // Perfetto trace collection phase.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/2L));
-
-    // Trigger maintenance service for compilation.
-    TimeUnit.SECONDS.sleep(5L);
-    assertTrue(compile(packageName, activityName, /*version=*/2L));
-
-    // Run app with prefetching
-    assertTrue(startAppWithCompiledTrace(
-        packageName, activityName, /*version=*/2L));
-
-    // Update test app to version 3
-    installApk(TEST_APP_VERSION_THREE_PATH);
-
-    // Rerun app, should do pefetto tracing.
-    assertTrue(startAppForPerfettoTrace(
-        packageName, activityName, /*version=*/3L));
-  }
-
-  private static void installApk(String apkPath) throws Exception {
-    // Disable the selinux to allow pm install apk in the dir.
-    executeShellCommand("setenforce 0");
-    executeShellCommand("pm install -r -d " + apkPath);
-    executeShellCommand("setenforce 1");
-
-  }
-
-  private static void uninstallApk(String apkPath) throws Exception {
-    executeShellCommand("pm uninstall " + apkPath);
-  }
-
-  /**
-   * Starts the testing app to collect the perfetto trace.
-   *
-   * @param expectPerfettoTraceCount is the expected count of perfetto traces.
-   */
-  private boolean startAppForPerfettoTrace(
-      String packageName, String activityName, long version)
-      throws Exception {
-    LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
-    return waitForPerfettoTraceSavedFromLogcat(
-        packageName, activityName, version, timestamp);
-  }
-
-  private boolean startAppWithCompiledTrace(
-      String packageName, String activityName, long version)
-      throws Exception {
-    LogcatTimestamp timestamp = runAppOnce(packageName, activityName);
-    return waitForPrefetchingFromLogcat(
-        packageName, activityName, version, timestamp);
-  }
-
-  private LogcatTimestamp runAppOnce(String packageName, String activityName) throws Exception {
-    // Close the specified app if it's open
-    closeApp(packageName);
-    LogcatTimestamp timestamp = new LogcatTimestamp();
-    // Launch the specified app
-    startApp(packageName, activityName);
-    // Wait for the app to appear
-    mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), TIMEOUT.getSeconds());
-    return timestamp;
-  }
-
-  // Invokes the maintenance to compile the perfetto traces to compiled trace.
-  private boolean compile(
-      String packageName, String activityName, long version) throws Exception {
-    // The job id (283673059) is defined in class IorapForwardingService.
-    executeShellCommandViaTmpFile("cmd jobscheduler run -f android 283673059");
-    return waitForFileExistence(getCompiledTracePath(packageName, activityName, version));
-  }
-
-  private String getCompiledTracePath(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "/data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
-        packageName, version, activityName);
-  }
-
-  /**
-   * Starts the testing app.
-   */
-  private void startApp(String packageName, String activityName) throws Exception {
-    executeShellCommandViaTmpFile(
-        String.format("am start %s/%s", packageName, activityName));
-  }
-
-  /**
-   * Closes the testing app.
-   * <p> Keep trying to kill the process of the app until no process of the app package
-   * appears.</p>
-   */
-  private void closeApp(String packageName) throws Exception {
-    while (true) {
-      String pid = executeShellCommand("pidof " + packageName);
-      if (pid.isEmpty()) {
-        Log.i(TAG, "Closed app " + packageName);
-        return;
-      }
-      executeShellCommand("kill -9 " + pid);
-      TimeUnit.SECONDS.sleep(1L);
-    }
-  }
-
-  /** Waits for a file to appear. */
-  private boolean waitForFileExistence(String fileName) throws Exception {
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String fileExists = executeShellCommandViaTmpFile(
-            String.format("test -f %s; echo $?", fileName));
-        Log.i(TAG, fileName + " existence is " +  fileExists);
-        return fileExists.trim().equals("0");
-      } catch (Exception e) {
-        Log.i(TAG, e.getMessage());
-        return false;
-      }
-    });
-  }
-
-  /** Waits for the perfetto trace saved message from logcat. */
-  private boolean waitForPerfettoTraceSavedFromLogcat(
-      String packageName, String activityName, long version, LogcatTimestamp timestamp)
-      throws Exception {
-    Pattern p = Pattern.compile(".*"
-        + getPerfettoTraceSavedIndicator(packageName, activityName, version)
-        + "(.*[.]perfetto_trace[.]pb)\n.*", Pattern.DOTALL);
-
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String log = timestamp.getLogcatAfter();
-        Matcher m = p.matcher(log);
-        Log.d(TAG, "Tries to find perfetto trace...");
-        if (!m.matches()) {
-          Log.i(TAG, "Cannot find perfetto trace saved in log.");
-          return false;
-        }
-        String filePath = m.group(1);
-        Log.i(TAG, "Perfetto trace is saved to " + filePath);
-        return true;
-      } catch(Exception e) {
-        Log.e(TAG, e.getMessage());
-        return false;
-      }
-   });
-  }
-
-  private String getPerfettoTraceSavedIndicator(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "Perfetto TraceBuffer saved to file: /data/misc/iorapd/%s/%d/%s/raw_traces/",
-        packageName, version, activityName);
-  }
-
-  /**
-   * Waits for the prefetching log in the logcat.
-   *
-   * <p> When prefetching works, the perfetto traces should not be collected. </p>
-   */
-  private boolean waitForPrefetchingFromLogcat(
-      String packageName, String activityName, long version, LogcatTimestamp timestamp)
-      throws Exception {
-    Pattern p = Pattern.compile(
-    ".*" + getReadaheadIndicator(packageName, activityName, version) +
-    ".*Total File Paths=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
-        + ".*Total Entries=(\\d+) \\(good: (\\d+[.]?\\d*)%\\)\n"
-        + ".*Total Bytes=(\\d+) \\(good: (\\d+[.]?\\d*)%\\).*",
-    Pattern.DOTALL);
-
-    return retryWithTimeout(TIMEOUT, () -> {
-      try {
-        String log = timestamp.getLogcatAfter();
-        Matcher m = p.matcher(log);
-        if (!m.matches()) {
-          Log.i(TAG, "Cannot find readahead log.");
-          return false;
-        }
-
-        int totalFilePath = Integer.parseInt(m.group(1));
-        float totalFilePathGoodRate = Float.parseFloat(m.group(2)) / 100;
-        int totalEntries = Integer.parseInt(m.group(3));
-        float totalEntriesGoodRate = Float.parseFloat(m.group(4)) / 100;
-        int totalBytes = Integer.parseInt(m.group(5));
-        float totalBytesGoodRate = Float.parseFloat(m.group(6)) / 100;
-
-        Log.i(TAG, String.format(
-            "totalFilePath: %d (good %.2f) totalEntries: %d (good %.2f) totalBytes: %d (good %.2f)",
-            totalFilePath, totalFilePathGoodRate, totalEntries, totalEntriesGoodRate, totalBytes,
-            totalBytesGoodRate));
-
-        return totalFilePath > 0 &&
-          totalEntries > 0 &&
-          totalBytes > 0 &&
-          totalFilePathGoodRate > 0.5 &&
-          totalEntriesGoodRate > 0.5 &&
-          totalBytesGoodRate > 0.5;
-      } catch(Exception e) {
-        return false;
-      }
-   });
-  }
-
-  private static String getReadaheadIndicator(
-      String packageName, String activityName, long version) {
-    return String.format(
-        "Description = /data/misc/iorapd/%s/%d/%s/compiled_traces/compiled_trace.pb",
-        packageName, version, activityName);
-  }
-
-  /** Retry until timeout. */
-  private boolean retryWithTimeout(Duration timeout, BooleanSupplier supplier) throws Exception {
-    long totalSleepTimeSeconds = 0L;
-    long sleepIntervalSeconds = 2L;
-    while (true) {
-      if (supplier.getAsBoolean()) {
-        return true;
-      }
-      TimeUnit.SECONDS.sleep(sleepIntervalSeconds);
-      totalSleepTimeSeconds += sleepIntervalSeconds;
-      if (totalSleepTimeSeconds > timeout.getSeconds()) {
-        return false;
-      }
-    }
-  }
-
-  /**
-   * Executes command in adb shell via a tmp file.
-   *
-   * <p> This should be run as root.</p>
-   */
-  private static String executeShellCommandViaTmpFile(String cmd) throws Exception {
-    Log.i(TAG, "Execute via tmp file: " + cmd);
-    Path tmp = null;
-    try {
-      tmp = Files.createTempFile(/*prefix=*/null, /*suffix=*/".sh");
-      Files.write(tmp, cmd.getBytes(StandardCharsets.UTF_8));
-      tmp.toFile().setExecutable(true);
-      return UiDevice.getInstance(
-          InstrumentationRegistry.getInstrumentation()).
-          executeShellCommand(tmp.toString());
-    } finally {
-      if (tmp != null) {
-        Files.delete(tmp);
-      }
-    }
-  }
-
-  /**
-   * Executes command in adb shell.
-   *
-   * <p> This should be run as root.</p>
-   */
-  private static String executeShellCommand(String cmd) throws Exception {
-    Log.i(TAG, "Execute: " + cmd);
-    return UiDevice.getInstance(
-        InstrumentationRegistry.getInstrumentation()).executeShellCommand(cmd);
-  }
-
-  static class LogcatTimestamp {
-    private String epochTime;
-
-    public LogcatTimestamp() throws Exception{
-      long currentTimeMillis = System.currentTimeMillis();
-      epochTime = String.format(
-          "%d.%03d", currentTimeMillis/1000, currentTimeMillis%1000);
-      Log.i(TAG, "Current logcat timestamp is " + epochTime);
-    }
-
-    // For example, 1585264100.000
-    public String getEpochTime() {
-      return epochTime;
-    }
-
-    // Gets the logcat after this epoch time.
-    public String getLogcatAfter() throws Exception {
-      return executeShellCommandViaTmpFile(
-          "logcat -v epoch -t '" + epochTime + "'");
-    }
-  }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
deleted file mode 100644
index 1d38f4c..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityHintEvent.java
+++ /dev/null
@@ -1,139 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an activity has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onActivityHintEvent<br /><br />
- *
- * Once an activity hint is in {@link #TYPE_STARTED} it must transition to another type.
- * All other states could be terminal, see below: <br /><br />
- *
- * <pre>
- *
- *          ┌──────────────────────────────────────┐
- *          │                                      ▼
- *        ┌─────────┐     ╔════════════════╗     ╔═══════════╗
- *    ──▶ │ STARTED │ ──▶ ║   COMPLETED    ║ ──▶ ║ CANCELLED ║
- *        └─────────┘     ╚════════════════╝     ╚═══════════╝
- *                          │
- *                          │
- *                          ▼
- *                        ╔════════════════╗
- *                        ║ POST_COMPLETED ║
- *                        ╚════════════════╝
- *
- * </pre> <!-- system/iorap/docs/binder/ActivityHint.dot -->
- *
- * @hide
- */
-public class ActivityHintEvent implements Parcelable {
-
-    public static final int TYPE_STARTED = 0;
-    public static final int TYPE_CANCELLED = 1;
-    public static final int TYPE_COMPLETED = 2;
-    public static final int TYPE_POST_COMPLETED = 3;
-    private static final int TYPE_MAX = TYPE_POST_COMPLETED;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_STARTED,
-            TYPE_CANCELLED,
-            TYPE_COMPLETED,
-            TYPE_POST_COMPLETED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final ActivityInfo activityInfo;
-
-    public ActivityHintEvent(@Type int type, ActivityInfo activityInfo) {
-        this.type = type;
-        this.activityInfo = activityInfo;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(activityInfo, "activityInfo");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d, activityInfo: %s}", type, activityInfo);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof ActivityHintEvent) {
-            return equals((ActivityHintEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(ActivityHintEvent other) {
-        return type == other.type &&
-                Objects.equals(activityInfo, other.activityInfo);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        activityInfo.writeToParcel(out, flags);
-    }
-
-    private ActivityHintEvent(Parcel in) {
-        this.type = in.readInt();
-        this.activityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<ActivityHintEvent> CREATOR
-            = new Parcelable.Creator<ActivityHintEvent>() {
-        public ActivityHintEvent createFromParcel(Parcel in) {
-            return new ActivityHintEvent(in);
-        }
-
-        public ActivityHintEvent[] newArray(int size) {
-            return new ActivityHintEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java b/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
deleted file mode 100644
index f47a42c..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/ActivityInfo.java
+++ /dev/null
@@ -1,104 +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.google.android.startop.iorap;
-
-import java.util.Objects;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * Provide minimal information for launched activities to iorap.<br /><br />
- *
- * This uniquely identifies a system-wide activity by providing the {@link #packageName} and
- * {@link #activityName}.
- *
- * @see ActivityHintEvent
- * @see AppIntentEvent
- *
- * @hide
- */
-public class ActivityInfo implements Parcelable {
-
-    /** The name of the package, for example {@code com.android.calculator}. */
-    public final String packageName;
-    /** The name of the activity, for example {@code .activities.activity.MainActivity} */
-    public final String activityName;
-
-    public ActivityInfo(String packageName, String activityName) {
-        this.packageName = packageName;
-        this.activityName = activityName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        Objects.requireNonNull(packageName, "packageName");
-        Objects.requireNonNull(activityName, "activityName");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{packageName: %s, activityName: %s}", packageName, activityName);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof ActivityInfo) {
-            return equals((ActivityInfo) other);
-        }
-        return false;
-    }
-
-    private boolean equals(ActivityInfo other) {
-        return Objects.equals(packageName, other.packageName) &&
-                Objects.equals(activityName, other.activityName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeString(packageName);
-        out.writeString(activityName);
-    }
-
-    private ActivityInfo(Parcel in) {
-        packageName = in.readString();
-        activityName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<ActivityInfo> CREATOR
-            = new Parcelable.Creator<ActivityInfo>() {
-        public ActivityInfo createFromParcel(Parcel in) {
-            return new ActivityInfo(in);
-        }
-
-        public ActivityInfo[] newArray(int size) {
-            return new ActivityInfo[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
deleted file mode 100644
index 1cd37b5..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppIntentEvent.java
+++ /dev/null
@@ -1,138 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a system-wide intent defaults change.<br /><br />
- *
- * Intent defaults provide a mechanism for an app to register itself as an automatic handler.
- * For example the camera app might be registered as the default handler for
- * {@link android.provider.MediaStore#INTENT_ACTION_STILL_IMAGE_CAMERA} intent. Subsequently,
- * if an arbitrary other app requests for a still image camera photo to be taken, the system
- * will launch the respective default camera app to be launched to handle that request.<br /><br />
- *
- * In some cases iorapd might need to know default intents, e.g. for boot-time pinning of
- * applications that resolve from the default intent. If the application would now be resolved
- * differently, iorapd would unpin the old application and pin the new application.<br /><br />
- *
- * @hide
- */
-public class AppIntentEvent implements Parcelable {
-
-    /** @see android.content.Intent#CATEGORY_DEFAULT */
-    public static final int TYPE_DEFAULT_INTENT_CHANGED = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_DEFAULT_INTENT_CHANGED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    public final ActivityInfo oldActivityInfo;
-    public final ActivityInfo newActivityInfo;
-
-    // TODO: Probably need the corresponding action here as well.
-
-    public static AppIntentEvent createDefaultIntentChanged(ActivityInfo oldActivityInfo,
-            ActivityInfo newActivityInfo) {
-        return new AppIntentEvent(TYPE_DEFAULT_INTENT_CHANGED, oldActivityInfo,
-                newActivityInfo);
-    }
-
-    private AppIntentEvent(@Type int type, ActivityInfo oldActivityInfo,
-            ActivityInfo newActivityInfo) {
-        this.type = type;
-        this.oldActivityInfo = oldActivityInfo;
-        this.newActivityInfo = newActivityInfo;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(oldActivityInfo, "oldActivityInfo");
-        Objects.requireNonNull(oldActivityInfo, "newActivityInfo");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{oldActivityInfo: %s, newActivityInfo: %s}", oldActivityInfo,
-                newActivityInfo);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof AppIntentEvent) {
-            return equals((AppIntentEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(AppIntentEvent other) {
-        return type == other.type &&
-                Objects.equals(oldActivityInfo, other.oldActivityInfo) &&
-                Objects.equals(newActivityInfo, other.newActivityInfo);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        oldActivityInfo.writeToParcel(out, flags);
-        newActivityInfo.writeToParcel(out, flags);
-    }
-
-    private AppIntentEvent(Parcel in) {
-        this.type = in.readInt();
-        this.oldActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-        this.newActivityInfo = ActivityInfo.CREATOR.createFromParcel(in);
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<AppIntentEvent> CREATOR
-            = new Parcelable.Creator<AppIntentEvent>() {
-        public AppIntentEvent createFromParcel(Parcel in) {
-            return new AppIntentEvent(in);
-        }
-
-        public AppIntentEvent[] newArray(int size) {
-            return new AppIntentEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java b/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
deleted file mode 100644
index 8263e0a..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/AppLaunchEvent.java
+++ /dev/null
@@ -1,459 +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.google.android.startop.iorap;
-
-import android.annotation.LongDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.proto.ProtoOutputStream;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserver.ActivityRecordProto;
-import com.android.server.wm.ActivityMetricsLaunchObserver.Temperature;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * Provide a hint to iorapd that an app launch sequence has transitioned state.<br /><br />
- *
- * Knowledge of when an activity starts/stops can be used by iorapd to increase system
- * performance (e.g. by launching perfetto tracing to record an io profile, or by
- * playing back an ioprofile via readahead) over the long run.<br /><br />
- *
- * /@see com.google.android.startop.iorap.IIorap#onAppLaunchEvent <br /><br />
- * @see com.android.server.wm.ActivityMetricsLaunchObserver
- *      ActivityMetricsLaunchObserver for the possible event states.
- * @hide
- */
-public abstract class AppLaunchEvent implements Parcelable {
-    @LongDef
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface SequenceId {}
-
-    public final @SequenceId
-    long sequenceId;
-
-    protected AppLaunchEvent(@SequenceId long sequenceId) {
-        this.sequenceId = sequenceId;
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (other instanceof AppLaunchEvent) {
-            return equals((AppLaunchEvent) other);
-        }
-        return false;
-    }
-
-    protected boolean equals(AppLaunchEvent other) {
-        return sequenceId == other.sequenceId;
-    }
-
-
-    @Override
-    public String toString() {
-        return getClass().getSimpleName() +
-                "{" + "sequenceId=" + Long.toString(sequenceId) +
-                toStringBody() + "}";
-    }
-
-    protected String toStringBody() { return ""; };
-
-    // List of possible variants:
-
-    public static final class IntentStarted extends AppLaunchEvent {
-        @NonNull
-        public final Intent intent;
-        public final long timestampNs;
-
-        public IntentStarted(@SequenceId long sequenceId,
-                             Intent intent,
-                             long timestampNs) {
-            super(sequenceId);
-            this.intent = intent;
-            this.timestampNs = timestampNs;
-
-            Objects.requireNonNull(intent, "intent");
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof IntentStarted) {
-                return intent.equals(((IntentStarted)other).intent) &&
-                       timestampNs == ((IntentStarted)other).timestampNs &&
-                       super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return ", intent=" + intent.toString() +
-                   " , timestampNs=" + Long.toString(timestampNs);
-        }
-
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-            super.writeToParcelImpl(p, flags);
-            IntentProtoParcelable.write(p, intent, flags);
-            p.writeLong(timestampNs);
-        }
-
-        IntentStarted(Parcel p) {
-            super(p);
-            intent = IntentProtoParcelable.create(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-    public static final class IntentFailed extends AppLaunchEvent {
-        public IntentFailed(@SequenceId long sequenceId) {
-            super(sequenceId);
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof IntentFailed) {
-                return super.equals(other);
-            }
-            return false;
-        }
-
-        IntentFailed(Parcel p) {
-            super(p);
-        }
-    }
-
-    public static abstract class BaseWithActivityRecordData extends AppLaunchEvent {
-        public final @NonNull
-        @ActivityRecordProto byte[] activityRecordSnapshot;
-
-        protected BaseWithActivityRecordData(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot) {
-            super(sequenceId);
-            activityRecordSnapshot = snapshot;
-
-            Objects.requireNonNull(snapshot, "snapshot");
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof BaseWithActivityRecordData) {
-                return (Arrays.equals(activityRecordSnapshot,
-                      ((BaseWithActivityRecordData)other).activityRecordSnapshot)) &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return ", " + new String(activityRecordSnapshot);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
-        }
-
-        BaseWithActivityRecordData(Parcel p) {
-            super(p);
-            activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
-        }
-    }
-
-    public static final class ActivityLaunched extends BaseWithActivityRecordData {
-        public final @ActivityMetricsLaunchObserver.Temperature
-        int temperature;
-
-        public ActivityLaunched(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot, 
-                @ActivityMetricsLaunchObserver.Temperature int temperature) {
-            super(sequenceId, snapshot);
-            this.temperature = temperature;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunched) {
-                return temperature == ((ActivityLaunched)other).temperature &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", temperature=" + Integer.toString(temperature);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeInt(temperature);
-        }
-
-        ActivityLaunched(Parcel p) {
-            super(p);
-            temperature = p.readInt();
-        }
-    }
-
-    public static final class ActivityLaunchFinished extends BaseWithActivityRecordData {
-        public final long timestampNs;
-
-        public ActivityLaunchFinished(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot,
-                long timestampNs) {
-            super(sequenceId, snapshot);
-            this.timestampNs = timestampNs;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunchFinished) {
-                return timestampNs == ((ActivityLaunchFinished)other).timestampNs &&
-                       super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeLong(timestampNs);
-        }
-
-        ActivityLaunchFinished(Parcel p) {
-            super(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-     public static class ActivityLaunchCancelled extends AppLaunchEvent {
-        public final @Nullable @ActivityRecordProto byte[] activityRecordSnapshot;
-
-        public ActivityLaunchCancelled(@SequenceId long sequenceId,
-                @Nullable @ActivityRecordProto byte[] snapshot) {
-            super(sequenceId);
-            activityRecordSnapshot = snapshot;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ActivityLaunchCancelled) {
-                return Arrays.equals(activityRecordSnapshot,
-                    ((ActivityLaunchCancelled)other).activityRecordSnapshot) &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", " + new String(activityRecordSnapshot);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           if (activityRecordSnapshot != null) {
-               p.writeBoolean(true);
-               ActivityRecordProtoParcelable.write(p, activityRecordSnapshot, flags);
-           } else {
-               p.writeBoolean(false);
-           }
-        }
-
-        ActivityLaunchCancelled(Parcel p) {
-            super(p);
-            if (p.readBoolean()) {
-                activityRecordSnapshot = ActivityRecordProtoParcelable.create(p);
-            } else {
-                activityRecordSnapshot = null;
-            }
-        }
-    }
-
-    public static final class ReportFullyDrawn extends BaseWithActivityRecordData {
-        public final long timestampNs;
-
-        public ReportFullyDrawn(@SequenceId long sequenceId,
-                @NonNull @ActivityRecordProto byte[] snapshot,
-                long timestampNs) {
-            super(sequenceId, snapshot);
-            this.timestampNs = timestampNs;
-        }
-
-        @Override
-        public boolean equals(Object other) {
-            if (other instanceof ReportFullyDrawn) {
-                return timestampNs == ((ReportFullyDrawn)other).timestampNs &&
-                        super.equals(other);
-            }
-            return false;
-        }
-
-        @Override
-        protected String toStringBody() {
-            return super.toStringBody() + ", timestampNs=" + Long.toString(timestampNs);
-        }
-
-        @Override
-        protected void writeToParcelImpl(Parcel p, int flags) {
-           super.writeToParcelImpl(p, flags);
-           p.writeLong(timestampNs);
-        }
-
-        ReportFullyDrawn(Parcel p) {
-            super(p);
-            timestampNs = p.readLong();
-        }
-    }
-
-    @Override
-    public @ContentsFlags int describeContents() { return 0; }
-
-    @Override
-    public void writeToParcel(Parcel p, @WriteFlags int flags) {
-        p.writeInt(getTypeIndex());
-
-        writeToParcelImpl(p, flags);
-    }
-
-
-    public static Creator<AppLaunchEvent> CREATOR =
-            new Creator<AppLaunchEvent>() {
-        @Override
-        public AppLaunchEvent createFromParcel(Parcel source) {
-            int typeIndex = source.readInt();
-
-            Class<?> kls = getClassFromTypeIndex(typeIndex);
-            if (kls == null) {
-                throw new IllegalArgumentException("Invalid type index: " + typeIndex);
-            }
-
-            try {
-                return (AppLaunchEvent) kls.getConstructor(Parcel.class).newInstance(source);
-            } catch (InstantiationException e) {
-                throw new AssertionError(e);
-            } catch (IllegalAccessException e) {
-                throw new AssertionError(e);
-            } catch (InvocationTargetException e) {
-                throw new AssertionError(e);
-            } catch (NoSuchMethodException e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        @Override
-        public AppLaunchEvent[] newArray(int size) {
-            return new AppLaunchEvent[0];
-        }
-    };
-
-    protected void writeToParcelImpl(Parcel p, int flags) {
-        p.writeLong(sequenceId);
-    }
-
-    protected AppLaunchEvent(Parcel p) {
-        sequenceId = p.readLong();
-    }
-
-    private int getTypeIndex() {
-        for (int i = 0; i < sTypes.length; ++i) {
-            if (sTypes[i].equals(this.getClass())) {
-                return i;
-            }
-        }
-        throw new AssertionError("sTypes did not include this type: " + this.getClass());
-    }
-
-    private static @Nullable Class<?> getClassFromTypeIndex(int typeIndex) {
-        if (typeIndex >= 0 && typeIndex < sTypes.length) {
-            return sTypes[typeIndex];
-        }
-        return null;
-    }
-
-    // Index position matters: It is used to encode the specific type in parceling.
-    // Keep up-to-date with C++ side.
-    private static Class<?>[] sTypes = new Class[] {
-            IntentStarted.class,
-            IntentFailed.class,
-            ActivityLaunched.class,
-            ActivityLaunchFinished.class,
-            ActivityLaunchCancelled.class,
-            ReportFullyDrawn.class,
-    };
-
-    public static class ActivityRecordProtoParcelable {
-        public static void write(Parcel p, @ActivityRecordProto byte[] activityRecordSnapshot,
-                int flags) {
-            p.writeByteArray(activityRecordSnapshot);
-        }
-
-        public static @ActivityRecordProto byte[] create(Parcel p) {
-            byte[] data = p.createByteArray();
-
-            return data;
-        }
-    }
-
-    public static class IntentProtoParcelable {
-        private static final int INTENT_PROTO_CHUNK_SIZE = 1024;
-
-        public static void write(Parcel p, @NonNull Intent intent, int flags) {
-            // There does not appear to be a way to 'reset' a ProtoOutputBuffer stream,
-            // so create a new one every time.
-            final ProtoOutputStream protoOutputStream =
-                    new ProtoOutputStream(INTENT_PROTO_CHUNK_SIZE);
-            // Write this data out as the top-most IntentProto (i.e. it is not a sub-object).
-            intent.dumpDebug(protoOutputStream);
-            final byte[] bytes = protoOutputStream.getBytes();
-
-            p.writeByteArray(bytes);
-        }
-
-        // TODO: Should be mockable for testing?
-        // We cannot deserialize in the platform because we don't have a 'readFromProto'
-        // code.
-        public static @NonNull Intent create(Parcel p) {
-            // This will "read" the correct amount of data, but then we discard it.
-            byte[] data = p.createByteArray();
-
-            // Never called by real code in a platform, this binder API is implemented only in C++.
-            return new Intent("<cannot deserialize IntentProto>");
-        }
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java b/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
deleted file mode 100644
index 34aedd7..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/CheckHelpers.java
+++ /dev/null
@@ -1,46 +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.google.android.startop.iorap;
-
-/**
- * Convenience short-hand to throw {@link IllegalAccessException} when the arguments
- * are out-of-range.
- */
-public class CheckHelpers {
-    /** @throws IllegalAccessException if {@param type} is not in {@code [0..maxValue]} */
-    public static void checkTypeInRange(int type, int maxValue) {
-        if (type < 0) {
-            throw new IllegalArgumentException(
-                    String.format("type must be non-negative (value=%d)", type));
-        }
-        if (type > maxValue) {
-            throw new IllegalArgumentException(
-                    String.format("type out of range (value=%d, max=%d)", type, maxValue));
-        }
-    }
-
-    /** @throws IllegalAccessException if {@param state} is not in {@code [0..maxValue]} */
-    public static void checkStateInRange(int state, int maxValue) {
-        if (state < 0) {
-            throw new IllegalArgumentException(
-                    String.format("state must be non-negative (value=%d)", state));
-        }
-        if (state > maxValue) {
-            throw new IllegalArgumentException(
-                    String.format("state out of range (value=%d, max=%d)", state, maxValue));
-        }
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java b/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
deleted file mode 100644
index 72c5eaa..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/DexOptEvent.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2020 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.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Notifications for iorapd specifying when a package is updated by dexopt service.<br /><br />
- *
- * @hide
- */
-public class DexOptEvent implements Parcelable {
-    public static final int TYPE_PACKAGE_UPDATE = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_PACKAGE_UPDATE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final String packageName;
-
-    @NonNull
-    public static DexOptEvent createPackageUpdate(String packageName) {
-        return new DexOptEvent(TYPE_PACKAGE_UPDATE, packageName);
-    }
-
-    private DexOptEvent(@Type int type, String packageName) {
-        this.type = type;
-        this.packageName = packageName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(packageName, "packageName");
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{DexOptEvent: packageName: %s}", packageName);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof DexOptEvent) {
-            return equals((DexOptEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(DexOptEvent other) {
-        return packageName.equals(other.packageName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeString(packageName);
-    }
-
-    private DexOptEvent(Parcel in) {
-        this.type = in.readInt();
-        this.packageName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<DexOptEvent> CREATOR
-            = new Parcelable.Creator<DexOptEvent>() {
-        public DexOptEvent createFromParcel(Parcel in) {
-            return new DexOptEvent(in);
-        }
-
-        public DexOptEvent[] newArray(int size) {
-            return new DexOptEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java b/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
deleted file mode 100644
index dcaff26..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/EventSequenceValidator.java
+++ /dev/null
@@ -1,267 +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 com.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.util.Log;
-
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-
-import java.io.StringWriter;
-import java.io.PrintWriter;
-
-/**
- * A validator to check the correctness of event sequence during app startup.
- *
- * <p> A valid state transition of event sequence is shown as the following:
- *
- * <pre>
- *
- *                                +--------------------+
- *                                |                    |
- *                                |        INIT        |
- *                                |                    |
- *                                +--------------------+
- *                                          |
- *                                          |
- *                                          ↓
- *                                +--------------------+
- *                                |                    |
- *            +-------------------|   INTENT_STARTED   | ←--------------------------------+
- *            |                   |                    |                                  |
- *            |                   +--------------------+                                  |
- *            |                             |                                             |
- *            |                             |                                             |
- *            ↓                             ↓                                             |
- * +--------------------+         +--------------------+                                  |
- * |                    |         |                    |                                  |
- * |   INTENT_FAILED    |         | ACTIVITY_LAUNCHED  |------------------+               |
- * |                    |         |                    |                  |               |
- * +--------------------+         +--------------------+                  |               |
- *            |                              |                            |               |
- *            |                              ↓                            ↓               |
- *            |                   +--------------------+       +--------------------+     |
- *            |                   |                    |       |                    |     |
- *            +------------------ |  ACTIVITY_FINISHED |       | ACTIVITY_CANCELLED |     |
- *            |                   |                    |       |                    |     |
- *            |                   +--------------------+       +--------------------+     |
- *            |                              |                            |               |
- *            |                              |                            |               |
- *            |                              ↓                            |               |
- *            |                   +--------------------+                  |               |
- *            |                   |                    |                  |               |
- *            |                   | REPORT_FULLY_DRAWN |                  |               |
- *            |                   |                    |                  |               |
- *            |                   +--------------------+                  |               |
- *            |                              |                            |               |
- *            |                              |                            |               |
- *            |                              ↓                            |               |
- *            |                   +--------------------+                  |               |
- *            |                   |                    |                  |               |
- *            +-----------------→ |        END         |←-----------------+               |
- *                                |                    |                                  |
- *                                +--------------------+                                  |
- *                                           |                                            |
- *                                           |                                            |
- *                                           |                                            |
- *                                           +---------------------------------------------
- *
- * <p> END is not a real state in implementation. All states that points to END directly
- * could transition to INTENT_STARTED.
- *
- * <p> If any bad transition happened, the state becomse UNKNOWN. The UNKNOWN state
- * could be accumulated, because during the UNKNOWN state more IntentStarted may
- * be triggered. To recover from UNKNOWN to INIT, all the accumualted IntentStarted
- * should termniate.
- *
- * <p> During UNKNOWN state, each IntentStarted increases the accumulation, and any of
- * IntentFailed, ActivityLaunchCancelled and ActivityFinished decreases the accumulation.
- * ReportFullyDrawn doesn't impact the accumulation.
- */
-public class EventSequenceValidator implements ActivityMetricsLaunchObserver {
-  static final String TAG = "EventSequenceValidator";
-  /** $> adb shell 'setprop log.tag.EventSequenceValidator VERBOSE' */
-  public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-  private State state = State.INIT;
-  private long accIntentStartedEvents = 0;
-
-  @Override
-  public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("IntentStarted during UNKNOWN. " + intent);
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    if (state != State.INIT &&
-        state != State.INTENT_FAILED &&
-        state != State.ACTIVITY_CANCELLED &&
-        state != State.ACTIVITY_FINISHED &&
-        state != State.REPORT_FULLY_DRAWN) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.INTENT_STARTED));
-      incAccIntentStartedEvents();
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_STARTED));
-    state = State.INTENT_STARTED;
-  }
-
-  @Override
-  public void onIntentFailed() {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onIntentFailed during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-    if (state != State.INTENT_STARTED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.INTENT_FAILED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.INTENT_FAILED));
-    state = State.INTENT_FAILED;
-  }
-
-  @Override
-  public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
-      @Temperature int temperature) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunched during UNKNOWN.");
-      return;
-    }
-    if (state != State.INTENT_STARTED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_LAUNCHED));
-    state = State.ACTIVITY_LAUNCHED;
-  }
-
-  @Override
-  public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunchCancelled during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-    if (state != State.ACTIVITY_LAUNCHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_CANCELLED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_CANCELLED));
-    state = State.ACTIVITY_CANCELLED;
-  }
-
-  @Override
-  public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
-      long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onActivityLaunchFinished during UNKNOWN.");
-      decAccIntentStartedEvents();
-      return;
-    }
-
-    if (state != State.ACTIVITY_LAUNCHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.ACTIVITY_FINISHED));
-      incAccIntentStartedEvents();
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.ACTIVITY_FINISHED));
-    state = State.ACTIVITY_FINISHED;
-  }
-
-  @Override
-  public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
-      long timestampNs) {
-    if (state == State.UNKNOWN) {
-      logWarningWithStackTrace("onReportFullyDrawn during UNKNOWN.");
-      return;
-    }
-    if (state == State.INIT) {
-      return;
-    }
-
-    if (state != State.ACTIVITY_FINISHED) {
-      logWarningWithStackTrace(
-          String.format("Cannot transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
-      return;
-    }
-
-    Log.i(TAG, String.format("Transition from %s to %s", state, State.REPORT_FULLY_DRAWN));
-    state = State.REPORT_FULLY_DRAWN;
-  }
-
-  enum State {
-    INIT,
-    INTENT_STARTED,
-    INTENT_FAILED,
-    ACTIVITY_LAUNCHED,
-    ACTIVITY_CANCELLED,
-    ACTIVITY_FINISHED,
-    REPORT_FULLY_DRAWN,
-    UNKNOWN,
-  }
-
-  private void incAccIntentStartedEvents() {
-    if (accIntentStartedEvents < 0) {
-      throw new AssertionError("The number of unknowns cannot be negative");
-    }
-    if (accIntentStartedEvents == 0) {
-      state = State.UNKNOWN;
-    }
-    ++accIntentStartedEvents;
-    Log.i(TAG,
-        String.format("inc AccIntentStartedEvents to %d", accIntentStartedEvents));
-  }
-
-  private void decAccIntentStartedEvents() {
-    if (accIntentStartedEvents <= 0) {
-      throw new AssertionError("The number of unknowns cannot be negative");
-    }
-    if(accIntentStartedEvents == 1) {
-      state = State.INIT;
-    }
-    --accIntentStartedEvents;
-    Log.i(TAG,
-        String.format("dec AccIntentStartedEvents to %d", accIntentStartedEvents));
-  }
-
-  private void logWarningWithStackTrace(String log) {
-    if (DEBUG) {
-      StringWriter sw = new StringWriter();
-      PrintWriter pw = new PrintWriter(sw);
-      new Throwable("EventSequenceValidator#getStackTrace").printStackTrace(pw);
-      Log.wtf(TAG, String.format("%s\n%s", log, sw));
-    }
-  }
-}
-
diff --git a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java b/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
deleted file mode 100644
index 77046f2..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/IorapForwardingService.java
+++ /dev/null
@@ -1,806 +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.google.android.startop.iorap;
-// TODO: rename to com.android.server.startop.iorap
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.job.JobInfo;
-import android.app.job.JobParameters;
-import android.app.job.JobScheduler;
-import android.app.job.JobService;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder.DeathRecipient;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
-import android.provider.DeviceConfig;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.server.IoThread;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.pm.BackgroundDexOptService;
-import com.android.server.pm.PackageManagerService;
-import com.android.server.wm.ActivityMetricsLaunchObserver;
-import com.android.server.wm.ActivityMetricsLaunchObserverRegistry;
-import com.android.server.wm.ActivityTaskManagerInternal;
-
-import java.time.Duration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.function.BooleanSupplier;
-
-/**
- * System-server-local proxy into the {@code IIorap} native service.
- */
-public class IorapForwardingService extends SystemService {
-
-    public static final String TAG = "IorapForwardingService";
-    /** $> adb shell 'setprop log.tag.IorapForwardingService VERBOSE' */
-    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    /** $> adb shell 'setprop ro.iorapd.enable true' */
-    private static boolean IS_ENABLED = SystemProperties.getBoolean("ro.iorapd.enable", true);
-    /** $> adb shell 'setprop iorapd.forwarding_service.wtf_crash true' */
-    private static boolean WTF_CRASH = SystemProperties.getBoolean(
-            "iorapd.forwarding_service.wtf_crash", false);
-    private static final Duration TIMEOUT = Duration.ofSeconds(600L);
-
-    // "Unique" job ID from the service name. Also equal to 283673059.
-    public static final int JOB_ID_IORAPD = encodeEnglishAlphabetStringIntoInt("iorapd");
-    // Run every 24 hours.
-    public static final long JOB_INTERVAL_MS = TimeUnit.HOURS.toMillis(24);
-
-    private IIorap mIorapRemote;
-    private final Object mLock = new Object();
-    /** Handle onBinderDeath by periodically trying to reconnect. */
-    private final Handler mHandler =
-            new BinderConnectionHandler(IoThread.getHandler().getLooper());
-
-    private volatile IorapdJobService mJobService;  // Write-once (null -> non-null forever).
-    private volatile static IorapForwardingService sSelfService;  // Write once (null -> non-null).
-
-
-    /**
-     * Atomics set to true if the JobScheduler requests an abort.
-     */
-    private final AtomicBoolean mAbortIdleCompilation = new AtomicBoolean(false);
-
-    /**
-     * Initializes the system service.
-     * <p>
-     * Subclasses must define a single argument constructor that accepts the context
-     * and passes it to super.
-     * </p>
-     *
-     * @param context The system server context.
-     */
-    public IorapForwardingService(Context context) {
-        super(context);
-
-        if (DEBUG) {
-            Log.v(TAG, "IorapForwardingService (Context=" + context.toString() + ")");
-        }
-
-        if (sSelfService != null) {
-            throw new AssertionError("only one service instance allowed");
-        }
-        sSelfService = this;
-    }
-
-    //<editor-fold desc="Providers">
-    /*
-     * Providers for external dependencies:
-     * - These are marked as protected to allow tests to inject different values via mocks.
-     */
-
-    @VisibleForTesting
-    protected ActivityMetricsLaunchObserverRegistry provideLaunchObserverRegistry() {
-        ActivityTaskManagerInternal amtInternal =
-                LocalServices.getService(ActivityTaskManagerInternal.class);
-        ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
-                amtInternal.getLaunchObserverRegistry();
-        return launchObserverRegistry;
-    }
-
-    @VisibleForTesting
-    protected IIorap provideIorapRemote() {
-        IIorap iorap;
-        try {
-            iorap = IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"));
-        } catch (ServiceManager.ServiceNotFoundException e) {
-            Log.w(TAG, e.getMessage());
-            return null;
-        }
-
-        try {
-            iorap.asBinder().linkToDeath(provideDeathRecipient(), /*flags*/0);
-        } catch (RemoteException e) {
-            handleRemoteError(e);
-            return null;
-        }
-
-        return iorap;
-    }
-
-    @VisibleForTesting
-    protected DeathRecipient provideDeathRecipient() {
-        return new DeathRecipient() {
-            @Override
-            public void binderDied() {
-                Log.w(TAG, "iorapd has died");
-                retryConnectToRemoteAndConfigure(/*attempts*/0);
-
-                if (mJobService != null) {
-                    mJobService.onIorapdDisconnected();
-                }
-            }
-        };
-    }
-
-    @VisibleForTesting
-    protected boolean isIorapEnabled() {
-        // These two mendel flags should match those in iorapd native process
-        // system/iorapd/src/common/property.h
-        boolean isTracingEnabled =
-            getMendelFlag("iorap_perfetto_enable", "iorapd.perfetto.enable", false);
-        boolean isReadAheadEnabled =
-            getMendelFlag("iorap_readahead_enable", "iorapd.readahead.enable", false);
-        // Same as the property in iorapd.rc -- disabling this will mean the 'iorapd' binder process
-        // never comes up, so all binder connections will fail indefinitely.
-        return IS_ENABLED && (isTracingEnabled || isReadAheadEnabled);
-    }
-
-    private boolean getMendelFlag(String mendelFlag, String sysProperty, boolean defaultValue) {
-        // TODO(yawanng) use DeviceConfig to get mendel property.
-        // DeviceConfig doesn't work and the reason is not clear.
-        // Provider service is already up before IORapForwardService.
-        String mendelProperty = "persist.device_config."
-            + DeviceConfig.NAMESPACE_RUNTIME_NATIVE_BOOT
-            + "."
-            + mendelFlag;
-        return SystemProperties.getBoolean(mendelProperty,
-            SystemProperties.getBoolean(sysProperty, defaultValue));
-    }
-
-    //</editor-fold>
-
-    @Override
-    public void onStart() {
-        if (DEBUG) {
-            Log.v(TAG, "onStart");
-        }
-
-        retryConnectToRemoteAndConfigure(/*attempts*/0);
-    }
-
-    @Override
-    public void onBootPhase(int phase) {
-        if (phase == PHASE_BOOT_COMPLETED) {
-            if (DEBUG) {
-                Log.v(TAG, "onBootPhase(PHASE_BOOT_COMPLETED)");
-            }
-
-            if (isIorapEnabled()) {
-                // Set up a recurring background job. This has to be done in a later phase since it
-                // has a dependency the job scheduler.
-                //
-                // Doing this too early can result in a ServiceNotFoundException for 'jobservice'
-                // or a null reference for #getSystemService(JobScheduler.class)
-                mJobService = new IorapdJobService(getContext());
-            }
-        }
-    }
-
-    private class BinderConnectionHandler extends Handler {
-        public BinderConnectionHandler(android.os.Looper looper) {
-            super(looper);
-        }
-
-        public static final int MESSAGE_BINDER_CONNECT = 0;
-
-        private int mAttempts = 0;
-
-        @Override
-        public void handleMessage(android.os.Message message) {
-           switch (message.what) {
-               case MESSAGE_BINDER_CONNECT:
-                   if (!retryConnectToRemoteAndConfigure(mAttempts)) {
-                       mAttempts++;
-                   } else {
-                       mAttempts = 0;
-                   }
-                   break;
-               default:
-                   throw new AssertionError("Unknown message: " + message.toString());
-           }
-        }
-    }
-
-    /**
-     * Handle iorapd shutdowns and crashes, by attempting to reconnect
-     * until the service is reached again.
-     *
-     * <p>The first connection attempt is synchronous,
-     * subsequent attempts are done by posting delayed tasks to the IoThread.</p>
-     *
-     * @return true if connection succeeded now, or false if it failed now [and needs to requeue].
-     */
-    private boolean retryConnectToRemoteAndConfigure(int attempts) {
-        final int sleepTime = 1000;  // ms
-
-        if (DEBUG) {
-            Log.v(TAG, "retryConnectToRemoteAndConfigure - attempt #" + attempts);
-        }
-
-        if (connectToRemoteAndConfigure()) {
-            return true;
-        }
-
-        // Either 'iorapd' is stuck in a crash loop (ouch!!) or we manually
-        // called 'adb shell stop iorapd' , which means this would loop until it comes back
-        // up.
-        //
-        // TODO: it would be good to get nodified of 'adb shell stop iorapd' to avoid
-        // printing this warning.
-        if (DEBUG) {
-            Log.v(TAG, "Failed to connect to iorapd, is it down? Delay for " + sleepTime);
-        }
-
-        // Use a handler instead of Thread#sleep to avoid backing up the binder thread
-        // when this is called from the death recipient callback.
-        mHandler.sendMessageDelayed(
-                mHandler.obtainMessage(BinderConnectionHandler.MESSAGE_BINDER_CONNECT),
-                sleepTime);
-
-        return false;
-
-        // Log.e(TAG, "Can't connect to iorapd - giving up after " + attempts + " attempts");
-    }
-
-    private boolean connectToRemoteAndConfigure() {
-        synchronized (mLock) {
-            // Synchronize against any concurrent calls to this via the DeathRecipient.
-            return connectToRemoteAndConfigureLocked();
-        }
-    }
-
-    private boolean connectToRemoteAndConfigureLocked() {
-        if (!isIorapEnabled()) {
-            if (DEBUG) {
-                Log.v(TAG, "connectToRemoteAndConfigure - iorapd is disabled, skip rest of work");
-            }
-            // When we see that iorapd is disabled (when system server comes up),
-            // it stays disabled permanently until the next system server reset.
-
-            // TODO: consider listening to property changes as a callback, then we can
-            // be more dynamic about handling enable/disable.
-            return true;
-        }
-
-        // Connect to the native binder service.
-        mIorapRemote = provideIorapRemote();
-        if (mIorapRemote == null) {
-            if (DEBUG) {
-                Log.e(TAG, "connectToRemoteAndConfigure - null iorap remote. check for Log.wtf?");
-            }
-            return false;
-        }
-        invokeRemote(mIorapRemote,
-            (IIorap remote) -> remote.setTaskListener(new RemoteTaskListener()) );
-        registerInProcessListenersLocked();
-
-        Log.i(TAG, "Connected to iorapd native service.");
-
-        return true;
-    }
-
-    private final AppLaunchObserver mAppLaunchObserver = new AppLaunchObserver();
-    private final EventSequenceValidator mEventSequenceValidator = new EventSequenceValidator();
-    private final DexOptPackagesUpdated mDexOptPackagesUpdated = new DexOptPackagesUpdated();
-    private boolean mRegisteredListeners = false;
-
-    private void registerInProcessListenersLocked() {
-        if (mRegisteredListeners) {
-            // Listeners are registered only once (idempotent operation).
-            //
-            // Today listeners are tolerant of the remote side going away
-            // by handling remote errors.
-            //
-            // We could try to 'unregister' the listener when we get a binder disconnect,
-            // but we'd still have to handle the case of encountering synchronous errors so
-            // it really wouldn't be a win (other than having less log spew).
-            return;
-        }
-
-        // Listen to App Launch Sequence events from ActivityTaskManager,
-        // and forward them to the native binder service.
-        ActivityMetricsLaunchObserverRegistry launchObserverRegistry =
-                provideLaunchObserverRegistry();
-        launchObserverRegistry.registerLaunchObserver(mAppLaunchObserver);
-        launchObserverRegistry.registerLaunchObserver(mEventSequenceValidator);
-
-        BackgroundDexOptService.getService().addPackagesUpdatedListener(
-                mDexOptPackagesUpdated);
-
-
-        mRegisteredListeners = true;
-    }
-
-    private class DexOptPackagesUpdated implements BackgroundDexOptService.PackagesUpdatedListener {
-        @Override
-        public void onPackagesUpdated(ArraySet<String> updatedPackages) {
-            String[] updated = updatedPackages.toArray(new String[0]);
-            for (String packageName : updated) {
-                Log.d(TAG, "onPackagesUpdated: " + packageName);
-                invokeRemote(mIorapRemote,
-                    (IIorap remote) ->
-                        remote.onDexOptEvent(RequestId.nextValueForSequence(),
-                                DexOptEvent.createPackageUpdate(packageName))
-                );
-            }
-        }
-    }
-
-    private class AppLaunchObserver implements ActivityMetricsLaunchObserver {
-        // We add a synthetic sequence ID here to make it easier to differentiate new
-        // launch sequences on the native side.
-        private @AppLaunchEvent.SequenceId long mSequenceId = -1;
-
-        // All callbacks occur on the same background thread. Don't synchronize explicitly.
-
-        @Override
-        public void onIntentStarted(@NonNull Intent intent, long timestampNs) {
-            // #onIntentStarted [is the only transition that] initiates a new launch sequence.
-            ++mSequenceId;
-
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onIntentStarted(%d, %s, %d)",
-                        mSequenceId, intent, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.IntentStarted(mSequenceId, intent, timestampNs))
-            );
-        }
-
-        @Override
-        public void onIntentFailed() {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onIntentFailed(%d)", mSequenceId));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.IntentFailed(mSequenceId))
-            );
-        }
-
-        @Override
-        public void onActivityLaunched(@NonNull @ActivityRecordProto byte[] activity,
-                @Temperature int temperature) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunched(%d, %s, %d)",
-                        mSequenceId, activity, temperature));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                            new AppLaunchEvent.ActivityLaunched(mSequenceId, activity, temperature))
-            );
-        }
-
-        @Override
-        public void onActivityLaunchCancelled(@Nullable @ActivityRecordProto byte[] activity) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchCancelled(%d, %s)",
-                        mSequenceId, activity));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                            new AppLaunchEvent.ActivityLaunchCancelled(mSequenceId,
-                                    activity)));
-        }
-
-        @Override
-        public void onActivityLaunchFinished(@NonNull @ActivityRecordProto byte[] activity,
-            long timestampNs) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onActivityLaunchFinished(%d, %s, %d)",
-                        mSequenceId, activity, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.ActivityLaunchFinished(mSequenceId,
-                            activity,
-                            timestampNs))
-            );
-        }
-
-        @Override
-        public void onReportFullyDrawn(@NonNull @ActivityRecordProto byte[] activity,
-            long timestampNs) {
-            if (DEBUG) {
-                Log.v(TAG, String.format("AppLaunchObserver#onReportFullyDrawn(%d, %s, %d)",
-                        mSequenceId, activity, timestampNs));
-            }
-
-            invokeRemote(mIorapRemote,
-                (IIorap remote) ->
-                    remote.onAppLaunchEvent(RequestId.nextValueForSequence(),
-                        new AppLaunchEvent.ReportFullyDrawn(mSequenceId, activity, timestampNs))
-            );
-        }
-    }
-
-    /**
-     * Debugging:
-     *
-     * $> adb shell dumpsys jobscheduler
-     *
-     * Search for 'IorapdJobServiceProxy'.
-     *
-     *   JOB #1000/283673059: 6e54ed android/com.google.android.startop.iorap.IorapForwardingService$IorapdJobServiceProxy
-     *   ^    ^                      ^
-     *   (uid, job id)               ComponentName(package/class)
-     *
-     * Forcing the job to be run, ignoring constraints:
-     *
-     * $> adb shell cmd jobscheduler run -f android 283673059
-     *                                      ^        ^
-     *                                      package  job_id
-     *
-     * ------------------------------------------------------------
-     *
-     * This class is instantiated newly by the JobService every time
-     * it wants to run a new job.
-     *
-     * We need to forward invocations to the current running instance of
-     * IorapForwardingService#IorapdJobService.
-     *
-     * Visibility: Must be accessible from android.app.AppComponentFactory
-     */
-    public static class IorapdJobServiceProxy extends JobService {
-
-        public IorapdJobServiceProxy() {
-            getActualIorapdJobService().bindProxy(this);
-        }
-
-
-        @NonNull
-        private IorapdJobService getActualIorapdJobService() {
-            // Can't ever be null, because the guarantee is that the
-            // IorapForwardingService is always running.
-            // We are in the same process as Job Service.
-            return sSelfService.mJobService;
-        }
-
-        // Called by system to start the job.
-        @Override
-        public boolean onStartJob(JobParameters params) {
-            return getActualIorapdJobService().onStartJob(params);
-        }
-
-        // Called by system to prematurely stop the job.
-        @Override
-        public boolean onStopJob(JobParameters params) {
-            return getActualIorapdJobService().onStopJob(params);
-        }
-    }
-
-    private class IorapdJobService extends JobService {
-        private final ComponentName IORAPD_COMPONENT_NAME;
-
-        private final Object mLock = new Object();
-        // Jobs currently running remotely on iorapd.
-        // They were started by the JobScheduler and need to be finished.
-        private final HashMap<RequestId, JobParameters> mRunningJobs = new HashMap<>();
-
-        private final JobInfo IORAPD_JOB_INFO;
-
-        private volatile IorapdJobServiceProxy mProxy;
-
-        public void bindProxy(IorapdJobServiceProxy proxy) {
-            mProxy = proxy;
-        }
-
-        // Create a new job service which immediately schedules a 24-hour idle maintenance mode
-        // background job to execute.
-        public IorapdJobService(Context context) {
-            if (DEBUG) {
-                Log.v(TAG, "IorapdJobService (Context=" + context.toString() + ")");
-            }
-
-            // Schedule the proxy class to be instantiated by the JobScheduler
-            // when it is time to invoke background jobs for IorapForwardingService.
-
-
-            // This also needs a BIND_JOB_SERVICE permission in
-            // frameworks/base/core/res/AndroidManifest.xml
-            IORAPD_COMPONENT_NAME = new ComponentName(context, IorapdJobServiceProxy.class);
-
-            JobInfo.Builder builder = new JobInfo.Builder(JOB_ID_IORAPD, IORAPD_COMPONENT_NAME);
-            builder.setPeriodic(JOB_INTERVAL_MS);
-
-            builder.setRequiresCharging(true);
-            builder.setRequiresDeviceIdle(true);
-
-            builder.setRequiresStorageNotLow(true);
-
-            IORAPD_JOB_INFO = builder.build();
-
-            JobScheduler js = context.getSystemService(JobScheduler.class);
-            js.schedule(IORAPD_JOB_INFO);
-            Log.d(TAG,
-                    "BgJob Scheduled (jobId=" + JOB_ID_IORAPD
-                            + ", interval: " + JOB_INTERVAL_MS + "ms)");
-        }
-
-        // Called by system to start the job.
-        @Override
-        public boolean onStartJob(JobParameters params) {
-            // Tell iorapd to start a background job.
-            Log.d(TAG, "Starting background job: " + params.toString());
-
-            mAbortIdleCompilation.set(false);
-            // PackageManagerService starts before IORap service.
-            PackageManagerService pm = (PackageManagerService)ServiceManager.getService("package");
-            List<String> pkgs = pm.getAllPackages();
-            runIdleCompilationAsync(params, pkgs);
-            return true;
-        }
-
-        private void runIdleCompilationAsync(final JobParameters params, final List<String> pkgs) {
-            new Thread("IORap_IdleCompilation") {
-                @Override
-                public void run() {
-                    for (int i = 0; i < pkgs.size(); i++) {
-                        String pkg = pkgs.get(i);
-                        if (mAbortIdleCompilation.get()) {
-                            Log.i(TAG, "The idle compilation is aborted");
-                            return;
-                        }
-
-                        // We wait until that job's sequence ID returns to us with 'Completed',
-                        RequestId request;
-                        synchronized (mLock) {
-                            // TODO: would be cleaner if we got the request from the
-                            // 'invokeRemote' function. Better yet, consider
-                            // a Pair<RequestId, Future<TaskResult>> or similar.
-                            request = RequestId.nextValueForSequence();
-                            mRunningJobs.put(request, params);
-                        }
-
-                        Log.i(TAG, String.format("IORap compile package: %s, [%d/%d]",
-                              pkg, i + 1, pkgs.size()));
-                        boolean shouldUpdateVersions = (i == 0);
-                        if (!invokeRemote(mIorapRemote, (IIorap remote) ->
-                                remote.onJobScheduledEvent(request,
-                                        JobScheduledEvent.createIdleMaintenance(
-                                                JobScheduledEvent.TYPE_START_JOB,
-                                                params,
-                                                pkg,
-                                                shouldUpdateVersions)))) {
-                            synchronized (mLock) {
-                                mRunningJobs.remove(request); // Avoid memory leaks.
-                            }
-                        }
-
-                        // Wait until the job is complete and removed from the running jobs.
-                        retryWithTimeout(TIMEOUT, () -> {
-                            synchronized (mLock) {
-                                return !mRunningJobs.containsKey(request);
-                            }
-                        });
-                    }
-
-                    // Finish the job after all packages are compiled.
-                    if (mProxy != null) {
-                        mProxy.jobFinished(params, /*reschedule*/false);
-                    }
-                }
-          }.start();
-        }
-
-        /** Retry until timeout. */
-        private boolean retryWithTimeout(final Duration timeout, BooleanSupplier supplier) {
-            long totalSleepTimeMs = 0L;
-            long sleepIntervalMs = 10L;
-            while (true) {
-                if (supplier.getAsBoolean()) {
-                    return true;
-                }
-                try {
-                    TimeUnit.MILLISECONDS.sleep(sleepIntervalMs);
-                } catch (InterruptedException e) {
-                    Log.e(TAG, e.getMessage());
-                    return false;
-                }
-
-                totalSleepTimeMs += sleepIntervalMs;
-                if (totalSleepTimeMs > timeout.toMillis()) {
-                    return false;
-                }
-            }
-        }
-
-        // Called by system to prematurely stop the job.
-        @Override
-        public boolean onStopJob(JobParameters params) {
-            // As this is unexpected behavior, print a warning.
-            Log.w(TAG, "onStopJob(params=" + params.toString() + ")");
-            mAbortIdleCompilation.set(true);
-
-            // Yes, retry the job at a later time no matter what.
-            return true;
-        }
-
-        // Listen to *all* task completes for all requests.
-        // The majority of these might be unrelated to background jobs.
-        public void onIorapdTaskCompleted(RequestId requestId) {
-            JobParameters jobParameters;
-            synchronized (mLock) {
-                jobParameters = mRunningJobs.remove(requestId);
-            }
-
-            // Typical case: This was a task callback unrelated to our jobs.
-            if (jobParameters == null) {
-                return;
-            }
-
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("IorapdJobService#onIorapdTaskCompleted(%s), found params=%s",
-                                requestId, jobParameters));
-            }
-
-            Log.d(TAG, "Finished background job: " + jobParameters.toString());
-        }
-
-        public void onIorapdDisconnected() {
-            synchronized (mLock) {
-                mRunningJobs.clear();
-            }
-
-            if (DEBUG) {
-                Log.v(TAG, String.format("IorapdJobService#onIorapdDisconnected"));
-            }
-
-            // TODO: should we try to resubmit all incomplete jobs after it's reconnected?
-        }
-    }
-
-    private class RemoteTaskListener extends ITaskListener.Stub {
-        @Override
-        public void onProgress(RequestId requestId, TaskResult result) throws RemoteException {
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("RemoteTaskListener#onProgress(%s, %s)", requestId, result));
-            }
-
-            // TODO: implement rest.
-        }
-
-        @Override
-        public void onComplete(RequestId requestId, TaskResult result) throws RemoteException {
-            if (DEBUG) {
-                Log.v(TAG,
-                        String.format("RemoteTaskListener#onComplete(%s, %s)", requestId, result));
-            }
-
-            if (mJobService != null) {
-                mJobService.onIorapdTaskCompleted(requestId);
-            }
-
-            // TODO: implement rest.
-        }
-    }
-
-    /** Allow passing lambdas to #invokeRemote */
-    private interface RemoteRunnable {
-        // TODO: run(RequestId) ?
-        void run(IIorap iorap) throws RemoteException;
-    }
-
-    // Always pass in the iorap directly here to avoid data race.
-    private static boolean invokeRemote(IIorap iorap, RemoteRunnable r) {
-       if (iorap == null) {
-         Log.w(TAG, "IIorap went to null in this thread, drop invokeRemote.");
-         return false;
-       }
-       try {
-           r.run(iorap);
-           return true;
-       } catch (RemoteException e) {
-           // This could be a logic error (remote side returning error), which we need to fix.
-           //
-           // This could also be a DeadObjectException in which case its probably just iorapd
-           // being manually restarted.
-           //
-           // Don't make any assumption, since DeadObjectException could also mean iorapd crashed
-           // unexpectedly.
-           //
-           // DeadObjectExceptions are recovered from using DeathRecipient and #linkToDeath.
-           handleRemoteError(e);
-           return false;
-       }
-    }
-
-    private static void handleRemoteError(Throwable t) {
-        if (WTF_CRASH) {
-            // In development modes, we just want to crash.
-            throw new AssertionError("unexpected remote error", t);
-        } else {
-            // Log to wtf which gets sent to dropbox, and in system_server this does not crash.
-            Log.wtf(TAG, t);
-        }
-    }
-
-    // Encode A-Z bitstring into bits. Every character is bits.
-    // Characters outside of the range [a,z] are considered out of range.
-    //
-    // The least significant bits hold the last character.
-    // First 2 bits are left as 0.
-    private static int encodeEnglishAlphabetStringIntoInt(String name) {
-        int value = 0;
-
-        final int CHARS_PER_INT = 6;
-        final int BITS_PER_CHAR = 5;
-        // Note: 2 top bits are unused, this also means our values are non-negative.
-        final char CHAR_LOWER = 'a';
-        final char CHAR_UPPER = 'z';
-
-        if (name.length() > CHARS_PER_INT) {
-            throw new IllegalArgumentException(
-                    "String too long. Cannot encode more than 6 chars: " + name);
-        }
-
-        for (int i = 0; i < name.length(); ++i) {
-           char c = name.charAt(i);
-
-           if (c < CHAR_LOWER || c > CHAR_UPPER) {
-               throw new IllegalArgumentException("String has out-of-range [a-z] chars: " + name);
-           }
-
-           // Avoid sign extension during promotion.
-           int cur_value = (c & 0xFFFF) - (CHAR_LOWER & 0xFFFF);
-           if (cur_value >= (1 << BITS_PER_CHAR)) {
-               throw new AssertionError("wtf? i=" + i + ", name=" + name);
-           }
-
-           value = value << BITS_PER_CHAR;
-           value = value | cur_value;
-        }
-
-        return value;
-    }
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java b/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
deleted file mode 100644
index b91dd71..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/JobScheduledEvent.java
+++ /dev/null
@@ -1,174 +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.google.android.startop.iorap;
-
-import android.app.job.JobParameters;
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward JobService events to iorapd. <br /><br />
- *
- * iorapd sometimes need to use background jobs. Forwarding these events to iorapd
- * notifies iorapd when it is an opportune time to execute these background jobs.
- *
- * @hide
- */
-public class JobScheduledEvent implements Parcelable {
-
-    /** JobService#onJobStarted */
-    public static final int TYPE_START_JOB = 0;
-    /** JobService#onJobStopped */
-    public static final int TYPE_STOP_JOB = 1;
-    private static final int TYPE_MAX = 1;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_START_JOB,
-            TYPE_STOP_JOB,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    /** @see JobParameters#getJobId() */
-    public final int jobId;
-
-    public final String packageName;
-
-    public final boolean shouldUpdateVersions;
-
-    /** Device is 'idle' and it's charging (plugged in). */
-    public static final int SORT_IDLE_MAINTENANCE = 0;
-    private static final int SORT_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "SORT_" }, value = {
-            SORT_IDLE_MAINTENANCE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Sort {}
-
-    /**
-     * Roughly corresponds to the {@code extras} fields in a JobParameters.
-     */
-    @Sort public final int sort;
-
-    /**
-     * Creates a {@link #SORT_IDLE_MAINTENANCE} event from the type and job parameters.
-     *
-     * Only the job ID is retained from {@code jobParams}, all other param info is dropped.
-     */
-    @NonNull
-    public static JobScheduledEvent createIdleMaintenance(
-        @Type int type, JobParameters jobParams, String packageName, boolean shouldUpdateVersions) {
-        return new JobScheduledEvent(
-            type, jobParams.getJobId(), SORT_IDLE_MAINTENANCE, packageName, shouldUpdateVersions);
-    }
-
-    private JobScheduledEvent(@Type int type,
-                              int jobId,
-                              @Sort int sort,
-                              String packageName,
-                              boolean shouldUpdateVersions) {
-        this.type = type;
-        this.jobId = jobId;
-        this.sort = sort;
-        this.packageName = packageName;
-        this.shouldUpdateVersions = shouldUpdateVersions;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        // No check for 'jobId': any int is valid.
-        CheckHelpers.checkTypeInRange(sort, SORT_MAX);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof JobScheduledEvent) {
-            return equals((JobScheduledEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(JobScheduledEvent other) {
-        return type == other.type &&
-                jobId == other.jobId &&
-                sort == other.sort &&
-                packageName.equals(other.packageName) &&
-                shouldUpdateVersions == other.shouldUpdateVersions;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-            "{type: %d, jobId: %d, sort: %d, packageName: %s, shouldUpdateVersions %b}",
-            type, jobId, sort, packageName, shouldUpdateVersions);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeInt(jobId);
-        out.writeInt(sort);
-        out.writeString(packageName);
-        out.writeBoolean(shouldUpdateVersions);
-
-        // We do not parcel the entire JobParameters here because there is no C++ equivalent
-        // of that class [which the iorapd side of the binder interface requires].
-    }
-
-    private JobScheduledEvent(Parcel in) {
-        this.type = in.readInt();
-        this.jobId = in.readInt();
-        this.sort = in.readInt();
-        this.packageName = in.readString();
-        this.shouldUpdateVersions = in.readBoolean();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<JobScheduledEvent> CREATOR
-            = new Parcelable.Creator<JobScheduledEvent>() {
-        public JobScheduledEvent createFromParcel(Parcel in) {
-            return new JobScheduledEvent(in);
-        }
-
-        public JobScheduledEvent[] newArray(int size) {
-            return new JobScheduledEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java b/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
deleted file mode 100644
index aa4eea7..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/PackageEvent.java
+++ /dev/null
@@ -1,131 +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.google.android.startop.iorap;
-
-import android.annotation.NonNull;
-import android.os.Parcelable;
-import android.os.Parcel;
-import android.net.Uri;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Objects;
-
-/**
- * Forward package manager events to iorapd. <br /><br />
- *
- * Knowing when packages are modified by the system are a useful tidbit to help with performance:
- * for example when a package is replaced, it could be a hint used to invalidate any collected
- * io profiles used for prefetching or pinning.
- *
- * @hide
- */
-public class PackageEvent implements Parcelable {
-
-    /** @see android.content.Intent#ACTION_PACKAGE_REPLACED */
-    public static final int TYPE_REPLACED = 0;
-    private static final int TYPE_MAX = 0;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_REPLACED,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    /** The path that a package is installed in, for example {@code /data/app/.../base.apk}. */
-    public final Uri packageUri;
-    /** The name of the package, for example {@code com.android.calculator}. */
-    public final String packageName;
-
-    @NonNull
-    public static PackageEvent createReplaced(Uri packageUri, String packageName) {
-        return new PackageEvent(TYPE_REPLACED, packageUri, packageName);
-    }
-
-    private PackageEvent(@Type int type, Uri packageUri, String packageName) {
-        this.type = type;
-        this.packageUri = packageUri;
-        this.packageName = packageName;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        Objects.requireNonNull(packageUri, "packageUri");
-        Objects.requireNonNull(packageName, "packageName");
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof PackageEvent) {
-            return equals((PackageEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(PackageEvent other) {
-        return type == other.type &&
-                Objects.equals(packageUri, other.packageUri) &&
-                Objects.equals(packageName, other.packageName);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{packageUri: %s, packageName: %s}", packageUri, packageName);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        packageUri.writeToParcel(out, flags);
-        out.writeString(packageName);
-    }
-
-    private PackageEvent(Parcel in) {
-        this.type = in.readInt();
-        this.packageUri = Uri.CREATOR.createFromParcel(in);
-        this.packageName = in.readString();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<PackageEvent> CREATOR
-            = new Parcelable.Creator<PackageEvent>() {
-        public PackageEvent createFromParcel(Parcel in) {
-            return new PackageEvent(in);
-        }
-
-        public PackageEvent[] newArray(int size) {
-            return new PackageEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java b/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
deleted file mode 100644
index 503e1c6..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/RequestId.java
+++ /dev/null
@@ -1,125 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.NonNull;
-
-/**
- * Uniquely identify an {@link com.google.android.startop.iorap.IIorap} method invocation,
- * used for asynchronous callbacks by the server. <br /><br />
- *
- * As all system server binder calls must be {@code oneway}, this means all invocations
- * into {@link com.google.android.startop.iorap.IIorap} are non-blocking. The request ID
- * exists to associate all calls with their respective callbacks in
- * {@link com.google.android.startop.iorap.ITaskListener}.
- *
- * @see com.google.android.startop.iorap.IIorap
- *
- * @hide
- */
-public class RequestId implements Parcelable {
-
-    public final long requestId;
-
-    private static Object mLock = new Object();
-    private static long mNextRequestId = 0;
-
-    /**
-     * Create a monotonically increasing request ID.<br /><br />
-     *
-     * It is invalid to re-use the same request ID for multiple method calls on
-     * {@link com.google.android.startop.iorap.IIorap}; a new request ID must be created
-     * each time.
-     */
-    @NonNull public static RequestId nextValueForSequence() {
-        long currentRequestId;
-        synchronized (mLock) {
-            currentRequestId = mNextRequestId;
-            ++mNextRequestId;
-        }
-        return new RequestId(currentRequestId);
-    }
-
-    private RequestId(long requestId) {
-        this.requestId = requestId;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        if (requestId < 0) {
-            throw new IllegalArgumentException("request id must be non-negative");
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{requestId: %d}", requestId);
-    }
-
-    @Override
-    public int hashCode() {
-        return Long.hashCode(requestId);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof RequestId) {
-            return equals((RequestId) other);
-        }
-        return false;
-    }
-
-    private boolean equals(RequestId other) {
-        return requestId == other.requestId;
-    }
-
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeLong(requestId);
-    }
-
-    private RequestId(Parcel in) {
-        requestId = in.readLong();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<RequestId> CREATOR
-            = new Parcelable.Creator<RequestId>() {
-        public RequestId createFromParcel(Parcel in) {
-            return new RequestId(in);
-        }
-
-        public RequestId[] newArray(int size) {
-            return new RequestId[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
deleted file mode 100644
index 75d47f9..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceEvent.java
+++ /dev/null
@@ -1,109 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward system service events to iorapd.
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceEvent implements Parcelable {
-
-    /** @see com.android.server.SystemService#onBootPhase */
-    public static final int TYPE_BOOT_PHASE = 0;
-    /** @see com.android.server.SystemService#onStart */
-    public static final int TYPE_START = 1;
-    private static final int TYPE_MAX = TYPE_START;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_BOOT_PHASE,
-            TYPE_START,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-
-    // TODO: do we want to pass the exact build phase enum?
-
-    public SystemServiceEvent(@Type int type) {
-        this.type = type;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d}", type);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof SystemServiceEvent) {
-            return equals((SystemServiceEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(SystemServiceEvent other) {
-        return type == other.type;
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-    }
-
-    private SystemServiceEvent(Parcel in) {
-        this.type = in.readInt();
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<SystemServiceEvent> CREATOR
-            = new Parcelable.Creator<SystemServiceEvent>() {
-        public SystemServiceEvent createFromParcel(Parcel in) {
-            return new SystemServiceEvent(in);
-        }
-
-        public SystemServiceEvent[] newArray(int size) {
-            return new SystemServiceEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java b/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
deleted file mode 100644
index 2e7bafe..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/SystemServiceUserEvent.java
+++ /dev/null
@@ -1,127 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Forward user events to iorapd.<br /><br />
- *
- * Knowledge of the logged-in user is reserved to be used to set-up appropriate policies
- * by iorapd (e.g. to handle user default pinned applications changing).
- *
- * @see com.android.server.SystemService
- *
- * @hide
- */
-public class SystemServiceUserEvent implements Parcelable {
-
-    /** @see com.android.server.SystemService#onUserStarting */
-    public static final int TYPE_START_USER = 0;
-    /** @see com.android.server.SystemService#onUserUnlocking */
-    public static final int TYPE_UNLOCK_USER = 1;
-    /** @see com.android.server.SystemService#onUserSwitching*/
-    public static final int TYPE_SWITCH_USER = 2;
-    /** @see com.android.server.SystemService#onUserStopping */
-    public static final int TYPE_STOP_USER = 3;
-    /** @see com.android.server.SystemService#onUserStopped */
-    public static final int TYPE_CLEANUP_USER = 4;
-    private static final int TYPE_MAX = TYPE_CLEANUP_USER;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "TYPE_" }, value = {
-            TYPE_START_USER,
-            TYPE_UNLOCK_USER,
-            TYPE_SWITCH_USER,
-            TYPE_STOP_USER,
-            TYPE_CLEANUP_USER,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface Type {}
-
-    @Type public final int type;
-    public final int userHandle;
-
-    public SystemServiceUserEvent(@Type int type, int userHandle) {
-        this.type = type;
-        this.userHandle = userHandle;
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkTypeInRange(type, TYPE_MAX);
-        if (userHandle < 0) {
-            throw new IllegalArgumentException("userHandle must be non-negative");
-        }
-    }
-
-    @Override
-    public String toString() {
-        return String.format("{type: %d, userHandle: %d}", type, userHandle);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof SystemServiceUserEvent) {
-            return equals((SystemServiceUserEvent) other);
-        }
-        return false;
-    }
-
-    private boolean equals(SystemServiceUserEvent other) {
-        return type == other.type &&
-                userHandle == other.userHandle;
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(type);
-        out.writeInt(userHandle);
-    }
-
-    private SystemServiceUserEvent(Parcel in) {
-        this.type = in.readInt();
-        this.userHandle = in.readInt();
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<SystemServiceUserEvent> CREATOR
-            = new Parcelable.Creator<SystemServiceUserEvent>() {
-        public SystemServiceUserEvent createFromParcel(Parcel in) {
-            return new SystemServiceUserEvent(in);
-        }
-
-        public SystemServiceUserEvent[] newArray(int size) {
-            return new SystemServiceUserEvent[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java b/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
deleted file mode 100644
index b5fd6d8..0000000
--- a/startop/iorap/src/com/google/android/startop/iorap/TaskResult.java
+++ /dev/null
@@ -1,130 +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.google.android.startop.iorap;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-import android.annotation.IntDef;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Result data accompanying a request for {@link com.google.android.startop.iorap.ITaskListener}
- * callbacks.<br /><br />
- *
- * Following {@link com.google.android.startop.iorap.IIorap} method invocation,
- * iorapd will issue in-order callbacks for that corresponding {@link RequestId}.<br /><br />
- *
- * State transitions are as follows: <br /><br />
- *
- * <pre>
- *          ┌─────────────────────────────┐
- *          │                             ▼
- *        ┌───────┐     ┌─────────┐     ╔═══════════╗
- *    ──▶ │ BEGAN │ ──▶ │ ONGOING │ ──▶ ║ COMPLETED ║
- *        └───────┘     └─────────┘     ╚═══════════╝
- *          │             │
- *          │             │
- *          ▼             │
- *        ╔═══════╗       │
- *    ──▶ ║ ERROR ║ ◀─────┘
- *        ╚═══════╝
- *
- * </pre> <!-- system/iorap/docs/binder/TaskResult.dot -->
- *
- * @hide
- */
-public class TaskResult implements Parcelable {
-
-    public static final int STATE_BEGAN = 0;
-    public static final int STATE_ONGOING = 1;
-    public static final int STATE_COMPLETED = 2;
-    public static final int STATE_ERROR = 3;
-    private static final int STATE_MAX = STATE_ERROR;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "STATE_" }, value = {
-            STATE_BEGAN,
-            STATE_ONGOING,
-            STATE_COMPLETED,
-            STATE_ERROR,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface State {}
-
-    @State public final int state;
-
-    @Override
-    public String toString() {
-        return String.format("{state: %d}", state);
-    }
-
-    @Override
-    public boolean equals(Object other) {
-        if (this == other) {
-            return true;
-        } else if (other instanceof TaskResult) {
-            return equals((TaskResult) other);
-        }
-        return false;
-    }
-
-    private boolean equals(TaskResult other) {
-        return state == other.state;
-    }
-
-    public TaskResult(@State int state) {
-        this.state = state;
-
-        checkConstructorArguments();
-    }
-
-    private void checkConstructorArguments() {
-        CheckHelpers.checkStateInRange(state, STATE_MAX);
-    }
-
-    //<editor-fold desc="Binder boilerplate">
-    @Override
-    public void writeToParcel(Parcel out, int flags) {
-        out.writeInt(state);
-    }
-
-    private TaskResult(Parcel in) {
-        state = in.readInt();
-
-        checkConstructorArguments();
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    public static final Parcelable.Creator<TaskResult> CREATOR
-            = new Parcelable.Creator<TaskResult>() {
-        public TaskResult createFromParcel(Parcel in) {
-            return new TaskResult(in);
-        }
-
-        public TaskResult[] newArray(int size) {
-            return new TaskResult[size];
-        }
-    };
-    //</editor-fold>
-}
diff --git a/startop/iorap/stress/Android.bp b/startop/iorap/stress/Android.bp
deleted file mode 100644
index 6e8725d..0000000
--- a/startop/iorap/stress/Android.bp
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (C) 2020 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 {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-cc_binary {
-  name: "iorap.stress.memory",
-  srcs: ["main_memory.cc"],
-
-  cflags: [
-      "-Wall",
-      "-Wextra",
-      "-Werror",
-      "-Wno-unused-parameter"
-  ],
-
-  shared_libs: [
-      "libbase"
-  ],
-
-  host_supported: true,
-}
diff --git a/startop/iorap/stress/main_memory.cc b/startop/iorap/stress/main_memory.cc
deleted file mode 100644
index 1f26861..0000000
--- a/startop/iorap/stress/main_memory.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// Copyright (C) 2020 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.
-//
-
-#include <chrono>
-#include <fstream>
-#include <iostream>
-#include <random>
-#include <string>
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-
-#include <android-base/parseint.h>
-
-static constexpr size_t kBytesPerMb = 1048576;
-const size_t kMemoryAllocationSize = 2 * 1024 * kBytesPerMb;
-
-#define USE_MLOCKALL 0
-
-std::string GetProcessStatus(const char* key) {
-  // Build search pattern of key and separator.
-  std::string pattern(key);
-  pattern.push_back(':');
-
-  // Search for status lines starting with pattern.
-  std::ifstream fs("/proc/self/status");
-  std::string line;
-  while (std::getline(fs, line)) {
-    if (strncmp(pattern.c_str(), line.c_str(), pattern.size()) == 0) {
-      // Skip whitespace in matching line (if any).
-      size_t pos = line.find_first_not_of(" \t", pattern.size());
-      if (pos == std::string::npos) {
-        break;
-      }
-      return std::string(line, pos);
-    }
-  }
-  return "<unknown>";
-}
-
-int main(int argc, char** argv) {
-  size_t allocationSize = 0;
-  if (argc >= 2) {
-    if (!android::base::ParseUint(argv[1], /*out*/&allocationSize)) {
-      std::cerr << "Failed to parse the allocation size (must be 0,MAX_SIZE_T)" << std::endl;
-      return 1;
-    }
-  } else {
-    allocationSize = kMemoryAllocationSize;
-  }
-
-  void* mem = malloc(allocationSize);
-  if (mem == nullptr) {
-    std::cerr << "Malloc failed" << std::endl;
-    return 1;
-  }
-
-  volatile int* imem = static_cast<int *>(mem);  // don't optimize out memory usage
-
-  size_t imemCount = allocationSize / sizeof(int);
-
-  std::cout << "Allocated " << allocationSize << " bytes" << std::endl;
-
-  auto seed = std::chrono::high_resolution_clock::now().time_since_epoch().count();
-  std::mt19937 mt_rand(seed);
-
-  size_t randPrintCount = 10;
-
-  // Write random numbers:
-  // * Ensures each page is resident
-  // * Avoids zeroed out pages (zRAM)
-  // * Avoids same-page merging
-  for (size_t i = 0; i < imemCount; ++i) {
-    imem[i] = mt_rand();
-
-    if (i < randPrintCount) {
-      std::cout << "Generated random value: " << imem[i] << std::endl;
-    }
-  }
-
-#if USE_MLOCKALL
-  /*
-   * Lock all pages from the address space of this process.
-   */
-  if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
-    std::cerr << "Mlockall failed" << std::endl;
-    return 1;
-  }
-#else
-  // Use mlock because of the predictable VmLck size.
-  // Using mlockall tends to bring in anywhere from 2-2.5GB depending on the device.
-  if (mlock(mem, allocationSize) != 0) {
-    std::cerr << "Mlock failed" << std::endl;
-    return 1;
-  }
-#endif
-
-  // Validate memory is actually resident and locked with:
-  // $> cat /proc/$(pidof iorap.stress.memory)/status | grep VmLck
-  std::cout << "Locked memory (VmLck) = " << GetProcessStatus("VmLck") << std::endl;
-
-  std::cout << "Press any key to terminate" << std::endl;
-  int any_input;
-  std::cin >> any_input;
-
-  std::cout << "Terminating..." << std::endl;
-
-  munlockall();
-  free(mem);
-
-  return 0;
-}
diff --git a/startop/iorap/tests/Android.bp b/startop/iorap/tests/Android.bp
deleted file mode 100644
index ad3d001..0000000
--- a/startop/iorap/tests/Android.bp
+++ /dev/null
@@ -1,72 +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.
-
-// TODO: once b/80095087 is fixed, rewrite this back to android_test
-package {
-    // See: http://go/android-license-faq
-    // A large-scale-change added 'default_applicable_licenses' to import
-    // all of the 'license_kinds' from "frameworks_base_license"
-    // to get the below license kinds:
-    //   SPDX-license-identifier-Apache-2.0
-    default_applicable_licenses: ["frameworks_base_license"],
-}
-
-java_library {
-    name: "libiorap-java-test-lib",
-    srcs: ["src/**/*.kt"],
-    static_libs: [
-        // Non-test dependencies
-        // library under test
-        "services.startop.iorap",
-        // need the system_server code to be on the classpath,
-        "services.core",
-        // Test Dependencies
-        // test android dependencies
-        "platform-test-annotations",
-        "androidx.test.rules",
-        // test framework dependencies
-        "mockito-target-inline-minus-junit4",
-        // "mockito-target-minus-junit4",
-        // Mockito also requires JNI (see Android.mk)
-        // and android:debuggable=true (see AndroidManifest.xml)
-        "truth-prebuilt",
-    ],
-    // sdk_version: "current",
-    // certificate: "platform",
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    // test_suites: ["device-tests"],
-}
-
-android_test {
-    name: "libiorap-java-tests",
-    dxflags: ["--multi-dex"],
-    test_suites: ["device-tests"],
-    static_libs: ["libiorap-java-test-lib"],
-    compile_multilib: "both",
-    jni_libs: [
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        "libmultiplejvmtiagentsinterferenceagent",
-    ],
-    libs: [
-        "android.test.base",
-        "android.test.runner",
-    ],
-    // Use private APIs
-    certificate: "platform",
-    platform_apis: true,
-}
diff --git a/startop/iorap/tests/AndroidManifest.xml b/startop/iorap/tests/AndroidManifest.xml
deleted file mode 100644
index b967e72..0000000
--- a/startop/iorap/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-<!--suppress AndroidUnknownAttribute -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.google.android.startop.iorap.tests"
-    android:sharedUserId="com.google.android.startop.iorap.tests"
-    android:versionCode="1"
-    android:versionName="1.0" >
-
-    <!--suppress AndroidDomInspection -->
-    <instrumentation
-        android:name="androidx.test.runner.AndroidJUnitRunner"
-        android:targetPackage="com.google.android.startop.iorap.tests" />
-
-      <!--
-       'debuggable=true' is required to properly load mockito jvmti dependencies,
-         otherwise it gives the following error at runtime:
-
-       Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
-       Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
-    <application android:debuggable="true">
-        <uses-library android:name="android.test.runner" />
-    </application>
-</manifest>
diff --git a/startop/iorap/tests/AndroidTest.xml b/startop/iorap/tests/AndroidTest.xml
deleted file mode 100644
index 6102c44..0000000
--- a/startop/iorap/tests/AndroidTest.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- 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.
--->
-
-<configuration description="Runs libiorap-java-tests.">
-    <option name="test-suite-tag" value="apct" />
-    <option name="test-suite-tag" value="apct-instrumentation" />
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="libiorap-java-tests.apk" />
-    </target_preparer>
-
-    <!--
-      Our IIorapIntegrationTest.kt requires setlinux to be disabled:
-      it connects to the iorapd binder service but this requires selinux permissions:
-
-      avc:  denied  { find } for service=iorapd pid=2738 uid=10050
-        scontext=u:r:platform_app:s0:c512,c768 tcontext=u:object_r:iorapd_service:s0
-        tclass=service_manager permissive=0
-    -->
-    <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer">
-    </target_preparer>
-
-    <!-- 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" />
-
-        <!-- Crash instead of using Log.wtf within the system_server iorap code. -->
-        <option name="run-command" value="setprop iorapd.forwarding_service.wtf_crash true" />
-        <!-- IIorapd has fake behavior: it doesn't do anything but reply with 'DONE' status -->
-        <option name="run-command" value="setprop iorapd.binder.fake true" />
-
-        <!-- iorapd does not pick up the above changes until we restart it -->
-        <option name="run-command" value="stop iorapd" />
-        <option name="run-command" value="start iorapd" />
-        <!-- give it some time to restart the service; otherwise the first unit test might fail -->
-        <option name="run-command" value="sleep 1" />
-    </target_preparer>
-
-    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
-        <option name="package" value="com.google.android.startop.iorap.tests" />
-        <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
-    </test>
-
-    <!-- using DeviceSetup again does not work. we simply leave the device in a semi-bad
-         state. there is no way to clean this up as far as I know.
-         -->
-
-</configuration>
-
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
deleted file mode 100644
index 51e407d..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/AppLaunchEventTest.kt
+++ /dev/null
@@ -1,181 +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 com.google.android.startop.iorap
-
-import android.content.Intent;
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import com.google.android.startop.iorap.AppLaunchEvent;
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunched
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchCancelled
-import com.google.android.startop.iorap.AppLaunchEvent.ActivityLaunchFinished
-import com.google.android.startop.iorap.AppLaunchEvent.IntentStarted;
-import com.google.android.startop.iorap.AppLaunchEvent.IntentFailed;
-import com.google.android.startop.iorap.AppLaunchEvent.ReportFullyDrawn
-import com.google.common.truth.Truth.assertThat
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.Parameterized
-
-
-/**
- * Basic unit tests to test all of the [AppLaunchEvent]s in [com.google.android.startop.iorap].
- */
-@SmallTest
-class AppLaunchEventTest {
-  /**
-   * Test for IntentStarted.
-   */
-  @Test
-  fun testIntentStarted() {
-    var intent = Intent()
-    val valid = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
-    val copy = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 1L)
-    val noneCopy1 = IntentStarted(/* sequenceId= */1L, intent, /* timestampNs= */ 1L)
-    val noneCopy2 = IntentStarted(/* sequenceId= */2L, intent, /* timestampNs= */ 2L)
-    val noneCopy3 = IntentStarted(/* sequenceId= */2L, Intent(), /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("IntentStarted{sequenceId=2, intent=Intent {  } , timestampNs=1}")
-  }
-
-  /**
-   * Test for IntentFailed.
-   */
-  @Test
-  fun testIntentFailed() {
-    val valid = IntentFailed(/* sequenceId= */2L)
-    val copy = IntentFailed(/* sequenceId= */2L)
-    val noneCopy = IntentFailed(/* sequenceId= */1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("IntentFailed{sequenceId=2}")
-  }
-
-  /**
-   * Test for ActivityLaunched.
-   */
-  @Test
-  fun testActivityLaunched() {
-    //var activityRecord =
-    val valid = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val copy = ActivityLaunched(/* sequenceId= */2L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val noneCopy1 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
-      /* temperature= */ 0)
-    val noneCopy2 = ActivityLaunched(/* sequenceId= */1L, "test".toByteArray(),
-      /* temperature= */ 1)
-    val noneCopy3 = ActivityLaunched(/* sequenceId= */1L, "test1".toByteArray(),
-      /* temperature= */ 0)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunched{sequenceId=2, test, temperature=0}")
-  }
-
-
-  /**
-   * Test for ActivityLaunchFinished.
-   */
-  @Test
-  fun testActivityLaunchFinished() {
-    val valid = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val copy = ActivityLaunchFinished(/* sequenceId= */2L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy1 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy2 = ActivityLaunchFinished(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 2L)
-    val noneCopy3 = ActivityLaunchFinished(/* sequenceId= */2L, "test1".toByteArray(),
-      /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunchFinished{sequenceId=2, test, timestampNs=1}")
-  }
-
-  /**
-   * Test for ActivityLaunchCancelled.
-   */
-  @Test
-  fun testActivityLaunchCancelled() {
-    val valid = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
-    val copy = ActivityLaunchCancelled(/* sequenceId= */2L, "test".toByteArray())
-    val noneCopy1 = ActivityLaunchCancelled(/* sequenceId= */1L, "test".toByteArray())
-    val noneCopy2 = ActivityLaunchCancelled(/* sequenceId= */2L, "test1".toByteArray())
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ActivityLaunchCancelled{sequenceId=2, test}")
-  }
-
-  /**
-   * Test for ReportFullyDrawn.
-   */
-  @Test
-  fun testReportFullyDrawn() {
-    val valid = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
-    val copy = ReportFullyDrawn(/* sequenceId= */2L, "test".toByteArray(), /* timestampNs= */ 1L)
-    val noneCopy1 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy2 = ReportFullyDrawn(/* sequenceId= */1L, "test".toByteArray(),
-      /* timestampNs= */ 1L)
-    val noneCopy3 = ReportFullyDrawn(/* sequenceId= */2L, "test1".toByteArray(),
-      /* timestampNs= */ 1L)
-
-    // equals(Object other)
-    assertThat(valid).isEqualTo(copy)
-    assertThat(valid).isNotEqualTo(noneCopy1)
-    assertThat(valid).isNotEqualTo(noneCopy2)
-    assertThat(valid).isNotEqualTo(noneCopy3)
-
-    // test toString()
-    val result = valid.toString()
-    assertThat(result).isEqualTo("ReportFullyDrawn{sequenceId=2, test, timestampNs=1}")
-  }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
deleted file mode 100644
index 18c2491..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/IIorapIntegrationTest.kt
+++ /dev/null
@@ -1,137 +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.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.ServiceManager
-import androidx.test.filters.FlakyTest
-import androidx.test.filters.MediumTest
-import org.junit.Test
-import org.mockito.Mockito.argThat
-import org.mockito.Mockito.eq
-import org.mockito.Mockito.inOrder
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.timeout
-
-// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
-@MediumTest
-@FlakyTest(bugId = 149098310) // Failing on cuttlefish with SecurityException.
-class IIorapIntegrationTest {
-    /**
-     * @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
-     */
-    private val iorapService: IIorap by lazy {
-        // TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
-        IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
-
-        // Use 'adb shell setenforce 0' otherwise this whole test fails,
-        // because the servicemanager is not allowed to hand out the binder token for iorapd.
-
-        // TODO: implement the selinux policies for iorapd.
-    }
-
-    // A dummy binder stub implementation is required to use with mockito#spy.
-    // Mockito overrides the methods at runtime and tracks how methods were invoked.
-    open class DummyTaskListener : ITaskListener.Stub() {
-        // Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
-        // from using the mockito matchers (eq, argThat, etc).
-        override fun onProgress(requestId: RequestId?, result: TaskResult?) {
-        }
-
-        override fun onComplete(requestId: RequestId?, result: TaskResult?) {
-        }
-    }
-
-    private fun testAnyMethod(func: (RequestId) -> Unit) {
-        val taskListener = spy(DummyTaskListener())!!
-
-        // FIXME: b/149098310
-        return
-
-        try {
-            iorapService.setTaskListener(taskListener)
-            // Note: Binder guarantees total order for oneway messages sent to the same binder
-            // interface, so we don't need any additional blocking here before sending later calls.
-
-            // Every new method call should have a unique request id.
-            val requestId = RequestId.nextValueForSequence()!!
-
-            // Apply the specific function under test.
-            func(requestId)
-
-            // Typical mockito behavior is to allow any-order callbacks, but we want to test order.
-            val inOrder = inOrder(taskListener)
-
-            // The "stub" behavior of iorapd is that every request immediately gets a response of
-            //   BEGAN,ONGOING,COMPLETED
-            inOrder.verify(taskListener, timeout(100))
-                .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
-            inOrder.verify(taskListener, timeout(100))
-                .onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
-            inOrder.verify(taskListener, timeout(100))
-                .onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
-            inOrder.verifyNoMoreInteractions()
-        } finally {
-            // iorapService.setTaskListener(null)
-            // FIXME: null is broken, C++ side sees a non-null object.
-        }
-    }
-
-    @Test
-    fun testOnPackageEvent() {
-        // FIXME (b/137134253): implement PackageEvent parsing on the C++ side.
-        // This is currently (silently: b/137135024) failing because IIorap is 'oneway' and the
-        // C++ PackageEvent un-parceling fails since its not implemented fully.
-        /*
-        testAnyMethod { requestId : RequestId ->
-            iorapService.onPackageEvent(requestId,
-                    PackageEvent.createReplaced(
-                            Uri.parse("https://www.google.com"), "com.fake.package"))
-        }
-        */
-    }
-
-    @Test
-    fun testOnAppIntentEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
-                    ActivityInfo("dont care", "dont care"),
-                    ActivityInfo("dont care 2", "dont care 2")))
-        }
-    }
-
-    @Test
-    fun testOnAppLaunchEvent() {
-        testAnyMethod { requestId : RequestId ->
-            iorapService.onAppLaunchEvent(requestId, AppLaunchEvent.IntentFailed(/*sequenceId*/123))
-        }
-    }
-
-    @Test
-    fun testOnSystemServiceEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onSystemServiceEvent(requestId,
-                    SystemServiceEvent(SystemServiceEvent.TYPE_START))
-        }
-    }
-
-    @Test
-    fun testOnSystemServiceUserEvent() {
-        testAnyMethod { requestId: RequestId ->
-            iorapService.onSystemServiceUserEvent(requestId,
-                    SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 0))
-        }
-    }
-}
diff --git a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt b/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
deleted file mode 100644
index 150577a..0000000
--- a/startop/iorap/tests/src/com/google/android/startop/iorap/ParcelablesTest.kt
+++ /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.google.android.startop.iorap
-
-import android.net.Uri
-import android.os.Parcel
-import android.os.Parcelable
-import androidx.test.filters.SmallTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import com.google.common.truth.Truth.assertThat
-import org.junit.runners.Parameterized
-
-/**
- * Basic unit tests to ensure that all of the [Parcelable]s in [com.google.android.startop.iorap]
- * have a valid-conforming interface implementation.
- */
-@SmallTest
-@RunWith(Parameterized::class)
-class ParcelablesTest<T : Parcelable>(private val inputData: InputData<T>) {
-    companion object {
-        private val initialRequestId = RequestId.nextValueForSequence()!!
-
-        @JvmStatic
-        @Parameterized.Parameters
-        fun data() = listOf(
-                InputData(
-                        newActivityInfo(),
-                        newActivityInfo(),
-                        ActivityInfo("some package", "some other activity")),
-                InputData(
-                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
-                        ActivityHintEvent(ActivityHintEvent.TYPE_COMPLETED, newActivityInfo()),
-                        ActivityHintEvent(ActivityHintEvent.TYPE_POST_COMPLETED,
-                                newActivityInfo())),
-                InputData(
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
-                                newActivityInfoOther()),
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfo(),
-                                newActivityInfoOther()),
-                        AppIntentEvent.createDefaultIntentChanged(newActivityInfoOther(),
-                                newActivityInfo())),
-                InputData(
-                        PackageEvent.createReplaced(newUri(), "some package"),
-                        PackageEvent.createReplaced(newUri(), "some package"),
-                        PackageEvent.createReplaced(newUri(), "some other package")
-                ),
-                InputData(initialRequestId, cloneRequestId(initialRequestId),
-                        RequestId.nextValueForSequence()),
-                InputData(
-                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
-                        SystemServiceEvent(SystemServiceEvent.TYPE_BOOT_PHASE),
-                        SystemServiceEvent(SystemServiceEvent.TYPE_START)),
-                InputData(
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER, 12345),
-                        SystemServiceUserEvent(SystemServiceUserEvent.TYPE_CLEANUP_USER, 12345)),
-                InputData(
-                        TaskResult(TaskResult.STATE_COMPLETED),
-                        TaskResult(TaskResult.STATE_COMPLETED),
-                        TaskResult(TaskResult.STATE_ONGOING))
-        )
-
-        private fun newActivityInfo(): ActivityInfo {
-            return ActivityInfo("some package", "some activity")
-        }
-
-        private fun newActivityInfoOther(): ActivityInfo {
-            return ActivityInfo("some package 2", "some activity 2")
-        }
-
-        private fun newUri(): Uri {
-            return Uri.parse("https://www.google.com")
-        }
-
-        private fun cloneRequestId(requestId: RequestId): RequestId {
-            val constructor = requestId::class.java.declaredConstructors[0]
-            constructor.isAccessible = true
-            return constructor.newInstance(requestId.requestId) as RequestId
-        }
-    }
-
-    /**
-     * Test for [Object.equals] implementation.
-     */
-    @Test
-    fun testEquality() {
-        assertThat(inputData.valid).isEqualTo(inputData.valid)
-        assertThat(inputData.valid).isEqualTo(inputData.validCopy)
-        assertThat(inputData.valid).isNotEqualTo(inputData.validOther)
-    }
-
-    /**
-     * Test for [Parcelable] implementation.
-     */
-    @Test
-    fun testParcelRoundTrip() {
-        // calling writeToParcel and then T::CREATOR.createFromParcel would return the same data.
-        val assertParcels = { it: T, data: InputData<T> ->
-            val parcel = Parcel.obtain()
-            it.writeToParcel(parcel, 0)
-            parcel.setDataPosition(0) // future reads will see all previous writes.
-            assertThat(it).isEqualTo(data.createFromParcel(parcel))
-            parcel.recycle()
-        }
-
-        assertParcels(inputData.valid, inputData)
-        assertParcels(inputData.validCopy, inputData)
-        assertParcels(inputData.validOther, inputData)
-    }
-
-    data class InputData<T : Parcelable>(val valid: T, val validCopy: T, val validOther: T) {
-        val kls = valid.javaClass
-        init {
-            assertThat(valid).isNotSameInstanceAs(validCopy)
-            // Don't use isInstanceOf because of phantom warnings in intellij about Class!
-            assertThat(validCopy.javaClass).isEqualTo(valid.javaClass)
-            assertThat(validOther.javaClass).isEqualTo(valid.javaClass)
-        }
-
-        fun createFromParcel(parcel: Parcel): T {
-            val field = kls.getDeclaredField("CREATOR")
-            val creator = field.get(null) as Parcelable.Creator<T>
-
-            return creator.createFromParcel(parcel)
-        }
-    }
-}
