Add the skeleton for the client-side API

android.system.virtualmachine is added as the client-side API for the
controlling of virtual machines. This change doesn't add any new API.
It adds an empty library to the existing framework.

Bug: 183496040
Test: atest MicrodroidHostTestCases
Change-Id: I9c52dfaf7e33137e5e3d6c587b5cc3932f667025
diff --git a/apex/Android.bp b/apex/Android.bp
index bbd4aa5..f06ff7a 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -50,6 +50,9 @@
         "vm",
         "compos_key_cmd",
     ],
+    java_libs: [
+        "android.system.virtualmachine",
+    ],
     prebuilts: [
         "com.android.virt.init.rc",
         "microdroid.json",
diff --git a/javalib/Android.bp b/javalib/Android.bp
new file mode 100644
index 0000000..f920175
--- /dev/null
+++ b/javalib/Android.bp
@@ -0,0 +1,22 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_sdk_library {
+    name: "android.system.virtualmachine",
+    installable: true,
+    compile_dex: true,
+
+    srcs: ["src/**/*.java"],
+    static_libs: [
+        "android.system.virtualizationservice-java",
+    ],
+
+    apex_available: ["com.android.virt"],
+    permitted_packages: [
+        "android.system.virtualmachine",
+        "android.system.virtualizationservice",
+    ],
+    // TODO(jiyong): remove the below once this gets public
+    unsafe_ignore_missing_latest_api: true,
+}
diff --git a/javalib/api/current.txt b/javalib/api/current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/api/removed.txt b/javalib/api/removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/api/system-current.txt b/javalib/api/system-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/system-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/api/system-removed.txt b/javalib/api/system-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/system-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/api/test-current.txt b/javalib/api/test-current.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/test-current.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/api/test-removed.txt b/javalib/api/test-removed.txt
new file mode 100644
index 0000000..d802177
--- /dev/null
+++ b/javalib/api/test-removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
new file mode 100644
index 0000000..504bc03
--- /dev/null
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.system.virtualmachine;
+
+/** @hide */
+public class VirtualMachine {}
diff --git a/tests/hostside/AndroidTest.xml b/tests/hostside/AndroidTest.xml
index adad01d..eda733a 100644
--- a/tests/hostside/AndroidTest.xml
+++ b/tests/hostside/AndroidTest.xml
@@ -22,11 +22,6 @@
       a test-only permission, run it without selinux -->
     <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer"/>
 
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="MicrodroidTestApp.apk" />
-    </target_preparer>
-
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="MicrodroidHostTestCases.jar" />
     </test>
diff --git a/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java b/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
index dccdca8..5821309 100644
--- a/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
+++ b/tests/hostside/helper/java/android/virt/test/VirtualizationTestCaseBase.java
@@ -139,7 +139,7 @@
         return String.join(" ", Arrays.asList(strs));
     }
 
-    private File findTestFile(String name) throws Exception {
+    public File findTestFile(String name) throws Exception {
         return (new CompatibilityBuildHelper(getBuild())).getTestFile(name);
     }
 
diff --git a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
index 08492b3..0b82d43 100644
--- a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
@@ -30,13 +30,13 @@
 @RunWith(DeviceJUnit4ClassRunner.class)
 public class MicrodroidTestCase extends VirtualizationTestCaseBase {
     private static final long MICRODROID_ADB_CONNECT_TIMEOUT_MINUTES = 5;
+    private static final String APK_NAME = "MicrodroidTestApp.apk";
+    private static final String PACKAGE_NAME = "com.android.microdroid.test";
 
     @Test
     public void testMicrodroidBoots() throws Exception {
-        final String apkName = "MicrodroidTestApp.apk";
-        final String packageName = "com.android.microdroid.test";
         final String configPath = "assets/vm_config.json"; // path inside the APK
-        final String cid = startMicrodroid(apkName, packageName, configPath);
+        final String cid = startMicrodroid(APK_NAME, PACKAGE_NAME, configPath);
         adbConnectToMicrodroid(cid, MICRODROID_ADB_CONNECT_TIMEOUT_MINUTES);
 
         // Test writing to /data partition
@@ -83,6 +83,8 @@
 
         prepareVirtualizationTestSetup();
 
+        getDevice().installPackage(findTestFile(APK_NAME), /* reinstall */ false);
+
         // clear the log
         getDevice().executeShellV2Command("logcat -c");
     }
@@ -90,5 +92,7 @@
     @After
     public void shutdown() throws Exception {
         cleanUpVirtualizationTestSetup();
+
+        getDevice().uninstallPackage(PACKAGE_NAME);
     }
 }
diff --git a/tests/testapk/Android.bp b/tests/testapk/Android.bp
index fc5681e..f14fca8 100644
--- a/tests/testapk/Android.bp
+++ b/tests/testapk/Android.bp
@@ -5,6 +5,9 @@
 android_app {
     name: "MicrodroidTestApp",
     srcs: ["src/java/**/*.java"],
+    libs: [
+        "android.system.virtualmachine",
+    ],
     jni_libs: ["MicrodroidTestNativeLib"],
     platform_apis: true,
     use_embedded_native_libs: true,
diff --git a/tests/testapk/AndroidManifest.xml b/tests/testapk/AndroidManifest.xml
index 74ae206..94f49dd 100644
--- a/tests/testapk/AndroidManifest.xml
+++ b/tests/testapk/AndroidManifest.xml
@@ -15,6 +15,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.microdroid.test">
     <application android:label="Microdroid Test">
+        <uses-library android:name="android.system.virtualmachine" android:required="true" />
         <activity android:name="TestActivity" android:exported="true">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/virtualizationservice/aidl/Android.bp b/virtualizationservice/aidl/Android.bp
index 89cfdef..a3311f2 100644
--- a/virtualizationservice/aidl/Android.bp
+++ b/virtualizationservice/aidl/Android.bp
@@ -5,11 +5,13 @@
 aidl_interface {
     name: "android.system.virtualizationservice",
     srcs: ["**/*.aidl"],
-    // TODO(qwandor): Consider changing this to false, unless we have a Java wrapper.
+    // This is never accessed directly. Apps are expected to use this indirectly via the java wrapper
+    // android.system.virtualmachine.
     unstable: true,
     backend: {
         java: {
             sdk_version: "module_current",
+            apex_available: ["com.android.virt"],
         },
         cpp: {
             enabled: true,