[view compiler] Add test coverage for layouts compiled from APK

The existing LayoutCompilerTest only covered compiled layouts generated from
text XML files. It did not cover layouts that were extracted from the APK. This
is an important area to cover.

This test works by calling `pm compile --compile-layouts` on the test APK, and
then directly loads the `compiled_view.dex` file. From there, it pulls out the
compiled layouts and executes their inflater. This makes sure the generated DEX
files validate and execute without error.

Bug: 111895153
Merged-In: Ifc6719c2f438474b5474def02422ef68eee800b2
Change-Id: I7024069bb4d77a81871366f259fb34ae54a55aac
diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp
index 1214538..f783aa6 100644
--- a/startop/view_compiler/dex_builder_test/Android.bp
+++ b/startop/view_compiler/dex_builder_test/Android.bp
@@ -37,15 +37,21 @@
 android_test {
     name: "dex-builder-test",
     srcs: [
+        "src/android/startop/test/ApkLayoutCompilerTest.java",
         "src/android/startop/test/DexBuilderTest.java",
         "src/android/startop/test/LayoutCompilerTest.java",
         "src/android/startop/test/TestClass.java",
     ],
     sdk_version: "current",
-    data: [":generate_dex_testcases", ":generate_compiled_layout1", ":generate_compiled_layout2"],
+    data: [
+        ":generate_dex_testcases",
+        ":generate_compiled_layout1",
+        ":generate_compiled_layout2",
+    ],
     static_libs: [
-        "androidx.test.rules",
-        "guava",
+        "androidx.test.core",
+        "androidx.test.runner",
+        "junit",
     ],
     manifest: "AndroidManifest.xml",
     resource_dirs: ["res"],
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java
new file mode 100644
index 0000000..230e8df
--- /dev/null
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/ApkLayoutCompilerTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package android.startop.test;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import android.view.View;
+import dalvik.system.PathClassLoader;
+import java.lang.reflect.Method;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class ApkLayoutCompilerTest {
+    static ClassLoader loadDexFile() throws Exception {
+        Context context = InstrumentationRegistry.getTargetContext();
+        return new PathClassLoader(context.getCodeCacheDir() + "/compiled_view.dex",
+                ClassLoader.getSystemClassLoader());
+    }
+
+    @BeforeClass
+    public static void setup() throws Exception {
+        // ensure PackageManager has compiled the layouts.
+        Process pm = Runtime.getRuntime().exec("pm compile --compile-layouts android.startop.test");
+        pm.waitFor();
+    }
+
+    @Test
+    public void loadAndInflateLayout1() throws Exception {
+        ClassLoader dex_file = loadDexFile();
+        Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
+        Method layout1 = compiled_view.getMethod("layout1", Context.class, int.class);
+        Context context = InstrumentationRegistry.getTargetContext();
+        layout1.invoke(null, context, R.layout.layout1);
+    }
+
+    @Test
+    public void loadAndInflateLayout2() throws Exception {
+        ClassLoader dex_file = loadDexFile();
+        Class compiled_view = dex_file.loadClass("android.startop.test.CompiledView");
+        Method layout2 = compiled_view.getMethod("layout2", Context.class, int.class);
+        Context context = InstrumentationRegistry.getTargetContext();
+        layout2.invoke(null, context, R.layout.layout2);
+    }
+}
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index d1fe588..6af01f6f 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -14,8 +14,11 @@
 
 package android.startop.test;
 
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
 import dalvik.system.PathClassLoader;
-
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import org.junit.Assert;
 import org.junit.Test;
 
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
index 3dfb20c..b0cf91d 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/LayoutCompilerTest.java
@@ -15,11 +15,11 @@
 package android.startop.test;
 
 import android.content.Context;
-
 import androidx.test.InstrumentationRegistry;
-
+import android.view.View;
 import dalvik.system.PathClassLoader;
-
+import java.lang.reflect.Method;
+import org.junit.Assert;
 import org.junit.Test;
 
 import java.lang.reflect.Method;