summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/aapt2/Android.bp2
-rw-r--r--tools/aapt2/Debug.cpp10
-rw-r--r--tools/aapt2/LoadedApk.h14
-rw-r--r--tools/aapt2/ResourceParser.cpp2
-rw-r--r--tools/aapt2/ResourceTable.h7
-rw-r--r--tools/aapt2/ResourceUtils.cpp32
-rw-r--r--tools/aapt2/ResourceUtils.h4
-rw-r--r--tools/aapt2/ResourceUtils_test.cpp35
-rw-r--r--tools/aapt2/ResourceValues.cpp19
-rw-r--r--tools/aapt2/ResourceValues.h1
-rw-r--r--tools/aapt2/SdkConstants.cpp46
-rw-r--r--tools/aapt2/SdkConstants_test.cpp20
-rw-r--r--tools/aapt2/cmd/Compile.cpp16
-rw-r--r--tools/aapt2/cmd/Compile.h11
-rw-r--r--tools/aapt2/cmd/Compile_test.cpp21
-rw-r--r--tools/aapt2/cmd/Convert.cpp1
-rw-r--r--tools/aapt2/cmd/Convert.h5
-rw-r--r--tools/aapt2/cmd/Dump.cpp1
-rw-r--r--tools/aapt2/cmd/Link.cpp1
-rw-r--r--tools/aapt2/cmd/Link_test.cpp12
-rw-r--r--tools/aapt2/cmd/Optimize.cpp1
-rw-r--r--tools/aapt2/compile/IdAssigner.cpp39
-rw-r--r--tools/aapt2/compile/IdAssigner_test.cpp30
-rw-r--r--tools/aapt2/compile/PseudolocaleGenerator.cpp203
-rw-r--r--tools/aapt2/compile/PseudolocaleGenerator.h15
-rw-r--r--tools/aapt2/compile/PseudolocaleGenerator_test.cpp215
-rw-r--r--tools/aapt2/dump/DumpManifest.cpp4
-rw-r--r--tools/aapt2/format/Archive_test.cpp110
-rw-r--r--tools/aapt2/format/binary/TableFlattener.cpp14
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp2
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize_test.cpp5
-rw-r--r--tools/aapt2/integration-tests/AutoVersionTest/Android.bp1
-rw-r--r--tools/aapt2/integration-tests/BasicTest/Android.bp1
-rw-r--r--tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt2
-rw-r--r--tools/aapt2/integration-tests/DumpTest/components_expected.txt2
-rw-r--r--tools/aapt2/integration-tests/DumpTest/minimal_expected.txt2
-rw-r--r--tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt2
-rw-r--r--tools/aapt2/integration-tests/StaticLibTest/App/Android.bp2
-rw-r--r--tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp1
-rw-r--r--tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp1
-rw-r--r--tools/aapt2/integration-tests/SymlinkTest/Android.bp1
-rw-r--r--tools/aapt2/io/File.h9
-rw-r--r--tools/aapt2/io/FileSystem.cpp20
-rw-r--r--tools/aapt2/io/FileSystem.h1
-rw-r--r--tools/aapt2/io/ZipArchive.cpp8
-rw-r--r--tools/aapt2/io/ZipArchive.h1
-rw-r--r--tools/aapt2/link/ReferenceLinker.cpp4
-rw-r--r--tools/aapt2/link/XmlReferenceLinker.cpp3
-rw-r--r--tools/aapt2/optimize/Obfuscator.cpp42
-rw-r--r--tools/aapt2/optimize/Obfuscator.h7
-rw-r--r--tools/aapt2/optimize/Obfuscator_test.cpp114
-rw-r--r--tools/aapt2/test/Common.h4
-rw-r--r--tools/aapt2/trace/TraceBuffer.cpp140
-rw-r--r--tools/aapt2/trace/TraceBuffer.h37
-rw-r--r--tools/aapt2/util/Util.cpp30
-rw-r--r--tools/codegen/src/com/android/codegen/Generators.kt12
-rw-r--r--tools/hoststubgen/.gitignore3
-rw-r--r--tools/hoststubgen/OWNERS3
-rw-r--r--tools/hoststubgen/README.md76
-rw-r--r--tools/hoststubgen/TEST_MAPPING11
-rw-r--r--tools/hoststubgen/common.sh116
-rw-r--r--tools/hoststubgen/hoststubgen/.gitignore1
-rw-r--r--tools/hoststubgen/hoststubgen/Android.bp375
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestClassLoadHook.java38
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestKeep.java43
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestNativeSubstitutionClass.java35
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestRemove.java39
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStaticInitializerKeep.java36
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStub.java43
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestSubstitute.java40
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestThrow.java36
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassKeep.java34
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassStub.java35
-rw-r--r--tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/tests/HostSideTestSuppress.java31
-rw-r--r--tools/hoststubgen/hoststubgen/framework-policy-override.txt102
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/android/test/AndroidTestCase.java27
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/NonNull.java40
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/Nullable.java47
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/ext/junit/runners/AndroidJUnit4.java30
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/FlakyTest.java46
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/LargeTest.java44
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/MediumTest.java45
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/RequiresDevice.java30
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SdkSuppress.java47
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SmallTest.java46
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/Suppress.java36
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/runner/AndroidJUnit4.java24
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/EventLog_host.java69
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Log_host.java61
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Parcel_host.java424
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/SystemProperties_host.java56
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/runtimehelper/ClassLoadHook.java190
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/dalvik/system/VMRuntime.java45
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/EmptyArray.java54
-rw-r--r--tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/SneakyThrow.java33
-rw-r--r--tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedKeepClass.java32
-rw-r--r--tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedStubClass.java32
-rw-r--r--tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestException.java26
-rw-r--r--tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestSuite.java102
-rw-r--r--tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java256
-rw-r--r--tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt44
-rw-r--r--tools/hoststubgen/hoststubgen/invoketest/Android.bp20
-rwxr-xr-xtools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh234
-rw-r--r--tools/hoststubgen/hoststubgen/jarjar-rules.txt2
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Exceptions.kt48
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt437
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt24
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt198
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt342
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt55
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt86
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt285
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt149
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt446
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt80
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt72
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt53
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt80
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt139
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt66
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt178
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt139
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt30
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt92
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/StubIntersectingFilter.kt91
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt189
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt141
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt269
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt354
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt433
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt82
-rw-r--r--tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/StubGeneratingAdapter.kt85
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/Android.bp19
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp57
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/AndroidTest-host.xml29
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/README.md21
-rwxr-xr-xtools/hoststubgen/hoststubgen/test-framework/run-test-without-atest.sh85
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/ArrayMapTest.java472
-rw-r--r--tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/LogTest.java41
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp216
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/AndroidTest-host.xml29
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/README.md21
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt29
-rwxr-xr-xtools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh134
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt2567
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt1452
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt2673
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt1452
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt3469
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt17
-rwxr-xr-xtools/hoststubgen/hoststubgen/test-tiny-framework/run-test-manually.sh132
-rwxr-xr-xtools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py64
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.java57
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java89
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java74
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.java33
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.java32
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.java35
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.java51
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.java26
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.java29
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java66
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.java77
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.java47
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.java37
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java87
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.java31
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/supported/UnsupportedClass.java32
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/unsupported/UnsupportedClass.java30
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/LargeTest.java28
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkBenchmark.java71
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java288
-rw-r--r--tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java66
-rw-r--r--tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt87
-rw-r--r--tools/hoststubgen/scripts/Android.bp (renamed from tools/xmlpersistence/Android.bp)20
-rwxr-xr-xtools/hoststubgen/scripts/build-framework-hostside-jars-and-extract.sh35
-rwxr-xr-xtools/hoststubgen/scripts/build-framework-hostside-jars-without-genrules.sh76
-rwxr-xr-xtools/hoststubgen/scripts/dump-jar165
-rwxr-xr-xtools/hoststubgen/scripts/run-all-tests.sh56
-rw-r--r--tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt3
-rw-r--r--tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt7
-rw-r--r--tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt32
-rw-r--r--tools/streaming_proto/OWNERS1
-rw-r--r--tools/streaming_proto/cpp/main.cpp10
-rw-r--r--tools/xmlpersistence/OWNERS1
-rw-r--r--tools/xmlpersistence/manifest.txt1
-rw-r--r--tools/xmlpersistence/src/main/kotlin/Generator.kt577
-rw-r--r--tools/xmlpersistence/src/main/kotlin/Main.kt45
-rw-r--r--tools/xmlpersistence/src/main/kotlin/Parser.kt248
-rw-r--r--tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt44
190 files changed, 23761 insertions, 1139 deletions
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index 40cba3ed316f..412aa9bf88ab 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -47,6 +47,7 @@ cc_defaults {
"-Wno-missing-field-initializers",
"-fno-exceptions",
"-fno-rtti",
+ "-Wno-deprecated-declarations",
],
target: {
windows: {
@@ -220,6 +221,7 @@ genrule {
name: "aapt2-protos",
tools: [":soong_zip"],
srcs: [
+ "ApkInfo.proto",
"Configuration.proto",
"ResourcesInternal.proto",
"ResourceMetadata.proto",
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 9cfb85d7cd73..6a17ef85a755 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -265,6 +265,16 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
ValueHeadlinePrinter headline_printer(package.name, printer);
ValueBodyPrinter body_printer(package.name, printer);
+ auto& dynamicRefTable = table.GetReferencedPackages();
+ if (!dynamicRefTable.empty()) {
+ printer->Println(StringPrintf("DynamicRefTable entryCount=%d", int(dynamicRefTable.size())));
+ printer->Indent();
+ for (auto&& [id, name] : dynamicRefTable) {
+ printer->Println(StringPrintf("0x%02x -> %s", id, name.c_str()));
+ }
+ printer->Undent();
+ }
+
printer->Print("Package name=");
printer->Print(package.name);
if (package.id) {
diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h
index 4cd7eae0a5e2..27c354a7b08e 100644
--- a/tools/aapt2/LoadedApk.h
+++ b/tools/aapt2/LoadedApk.h
@@ -40,10 +40,8 @@ enum ApkFormat {
};
// Info about an APK loaded in memory.
-class LoadedApk {
+class LoadedApk final {
public:
- virtual ~LoadedApk() = default;
-
// Loads both binary and proto APKs from disk.
static std::unique_ptr<LoadedApk> LoadApkFromPath(android::StringPiece path,
android::IDiagnostics* diag);
@@ -96,8 +94,8 @@ class LoadedApk {
* Writes the APK on disk at the given path, while also removing the resource
* files that are not referenced in the resource table.
*/
- virtual bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
- IArchiveWriter* writer);
+ bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options,
+ IArchiveWriter* writer);
/**
* Writes the APK on disk at the given path, while also removing the resource files that are not
@@ -108,9 +106,9 @@ class LoadedApk {
* original manifest will be written. The manifest is only required if the contents of the new APK
* have been modified in a way that require the AndroidManifest.xml to also be modified.
*/
- virtual bool WriteToArchive(IAaptContext* context, ResourceTable* split_table,
- const TableFlattenerOptions& options, FilterChain* filters,
- IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
+ bool WriteToArchive(IAaptContext* context, ResourceTable* split_table,
+ const TableFlattenerOptions& options, FilterChain* filters,
+ IArchiveWriter* writer, xml::XmlResource* manifest = nullptr);
/** Loads the file as an xml document. */
std::unique_ptr<xml::XmlResource> LoadXml(const std::string& file_path,
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index fa9a98f136cb..6af39b739e9b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -800,7 +800,7 @@ std::unique_ptr<Item> ResourceParser::ParseXml(const FlattenedXmlSubTree& xmlsub
// Process the raw value.
std::unique_ptr<Item> processed_item = ResourceUtils::TryParseItemForAttribute(
- xmlsub_tree.raw_value, type_mask, on_create_reference);
+ &diag, xmlsub_tree.raw_value, type_mask, on_create_reference);
if (processed_item) {
// Fix up the reference.
if (auto ref = ValueCast<Reference>(processed_item.get())) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index bb286a8abdaa..61e399c7ab68 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -307,6 +307,11 @@ class ResourceTable {
// order.
ResourceTableView GetPartitionedView(const ResourceTableViewOptions& options = {}) const;
+ using ReferencedPackages = std::map<uint8_t, std::string>;
+ const ReferencedPackages& GetReferencedPackages() const {
+ return included_packages_;
+ }
+
struct SearchResult {
ResourceTablePackage* package;
ResourceTableType* type;
@@ -342,7 +347,7 @@ class ResourceTable {
// Set of dynamic packages that this table may reference. Their package names get encoded
// into the resources.arsc along with their compile-time assigned IDs.
- std::map<size_t, std::string> included_packages_;
+ ReferencedPackages included_packages_;
private:
DISALLOW_COPY_AND_ASSIGN(ResourceTable);
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 5a118a902963..d358df98ada6 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -619,7 +619,7 @@ uint32_t AndroidTypeToAttributeTypeMask(uint16_t type) {
}
std::unique_ptr<Item> TryParseItemForAttribute(
- StringPiece value, uint32_t type_mask,
+ android::IDiagnostics* diag, StringPiece value, uint32_t type_mask,
const std::function<bool(const ResourceName&)>& on_create_reference) {
using android::ResTable_map;
@@ -670,8 +670,32 @@ std::unique_ptr<Item> TryParseItemForAttribute(
// Try parsing this as a float.
auto floating_point = TryParseFloat(value);
if (floating_point) {
+ // Only check if the parsed result lost precision when the parsed item is
+ // android::Res_value::TYPE_FLOAT and there is other possible types saved in type_mask, like
+ // ResTable_map::TYPE_INTEGER.
if (type_mask & AndroidTypeToAttributeTypeMask(floating_point->value.dataType)) {
- return std::move(floating_point);
+ const bool mayOnlyBeFloat = (type_mask & ~float_mask) == 0;
+ const bool parsedAsFloat = floating_point->value.dataType == android::Res_value::TYPE_FLOAT;
+ if (!mayOnlyBeFloat && parsedAsFloat) {
+ float f = reinterpret_cast<float&>(floating_point->value.data);
+ std::u16string str16 = android::util::Utf8ToUtf16(util::TrimWhitespace(value));
+ double d;
+ if (android::ResTable::stringToDouble(str16.data(), str16.size(), d)) {
+ // Parse as a float only if the difference between float and double parsed from the
+ // same string is smaller than 1, otherwise return as raw string.
+ if (fabs(f - d) < 1) {
+ return std::move(floating_point);
+ } else {
+ if (diag->IsVerbose()) {
+ diag->Note(android::DiagMessage()
+ << "precision lost greater than 1 while parsing float " << value
+ << ", return a raw string");
+ }
+ }
+ }
+ } else {
+ return std::move(floating_point);
+ }
}
}
}
@@ -683,12 +707,12 @@ std::unique_ptr<Item> TryParseItemForAttribute(
* allows.
*/
std::unique_ptr<Item> TryParseItemForAttribute(
- StringPiece str, const Attribute* attr,
+ android::IDiagnostics* diag, StringPiece str, const Attribute* attr,
const std::function<bool(const ResourceName&)>& on_create_reference) {
using android::ResTable_map;
const uint32_t type_mask = attr->type_mask;
- auto value = TryParseItemForAttribute(str, type_mask, on_create_reference);
+ auto value = TryParseItemForAttribute(diag, str, type_mask, on_create_reference);
if (value) {
return value;
}
diff --git a/tools/aapt2/ResourceUtils.h b/tools/aapt2/ResourceUtils.h
index f30f4acfec7a..50fc87900162 100644
--- a/tools/aapt2/ResourceUtils.h
+++ b/tools/aapt2/ResourceUtils.h
@@ -200,11 +200,11 @@ std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* enum_attr,
* reference to an ID that must be created (@+id/foo).
*/
std::unique_ptr<Item> TryParseItemForAttribute(
- android::StringPiece value, const Attribute* attr,
+ android::IDiagnostics* diag, android::StringPiece value, const Attribute* attr,
const std::function<bool(const ResourceName&)>& on_create_reference = {});
std::unique_ptr<Item> TryParseItemForAttribute(
- android::StringPiece value, uint32_t type_mask,
+ android::IDiagnostics* diag, android::StringPiece value, uint32_t type_mask,
const std::function<bool(const ResourceName&)>& on_create_reference = {});
uint32_t AndroidTypeToAttributeTypeMask(uint16_t type);
diff --git a/tools/aapt2/ResourceUtils_test.cpp b/tools/aapt2/ResourceUtils_test.cpp
index 568871a4d66e..4cba04de72ee 100644
--- a/tools/aapt2/ResourceUtils_test.cpp
+++ b/tools/aapt2/ResourceUtils_test.cpp
@@ -217,17 +217,46 @@ TEST(ResourceUtilsTest, EmptyIsBinaryPrimitive) {
}
TEST(ResourceUtilsTest, ItemsWithWhitespaceAreParsedCorrectly) {
- EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12\n ", ResTable_map::TYPE_INTEGER),
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " 12\n ",
+ ResTable_map::TYPE_INTEGER),
Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_DEC, 12u))));
- EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" true\n ", ResTable_map::TYPE_BOOLEAN),
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " true\n ",
+ ResTable_map::TYPE_BOOLEAN),
Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_INT_BOOLEAN, 0xffffffffu))));
const float expected_float = 12.0f;
const uint32_t expected_float_flattened = *(uint32_t*)&expected_float;
- EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(" 12.0\n ", ResTable_map::TYPE_FLOAT),
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), " 12.0\n ",
+ ResTable_map::TYPE_FLOAT),
Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));
}
+TEST(ResourceUtilsTest, FloatAndBigIntegerParsedCorrectly) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ const float expected_float = 0.125f;
+ const uint32_t expected_float_flattened = *(uint32_t*)&expected_float;
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "0.125",
+ ResTable_map::TYPE_FLOAT),
+ Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, expected_float_flattened))));
+
+ const float special_float = 1.0f;
+ const uint32_t special_float_flattened = *(uint32_t*)&special_float;
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1.0",
+ ResTable_map::TYPE_FLOAT),
+ Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, special_float_flattened))));
+
+ EXPECT_EQ(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1099511627776",
+ ResTable_map::TYPE_INTEGER),
+ std::unique_ptr<Item>(nullptr));
+
+ const float big_float = 1099511627776.0f;
+ const uint32_t big_flattened = *(uint32_t*)&big_float;
+ EXPECT_THAT(ResourceUtils::TryParseItemForAttribute(context->GetDiagnostics(), "1099511627776",
+ ResTable_map::TYPE_FLOAT),
+ Pointee(ValueEq(BinaryPrimitive(Res_value::TYPE_FLOAT, big_flattened))));
+}
+
TEST(ResourceUtilsTest, ParseSdkVersionWithCodename) {
EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q"), Eq(std::optional<int>(10000)));
EXPECT_THAT(ResourceUtils::ParseSdkVersion("Q.fingerprint"), Eq(std::optional<int>(10000)));
diff --git a/tools/aapt2/ResourceValues.cpp b/tools/aapt2/ResourceValues.cpp
index a5754e0d168f..166b01bd9154 100644
--- a/tools/aapt2/ResourceValues.cpp
+++ b/tools/aapt2/ResourceValues.cpp
@@ -439,6 +439,21 @@ static std::string ComplexToString(uint32_t complex_value, bool fraction) {
return str;
}
+// This function is designed to using different specifier to print different floats,
+// which can print more accurate format rather than using %g only.
+const char* BinaryPrimitive::DecideFormat(float f) {
+ // if the float is either too big or too tiny, print it in scientific notation.
+ // eg: "10995116277760000000000" to 1.099512e+22, "0.00000000001" to 1.000000e-11
+ if (fabs(f) > std::numeric_limits<int64_t>::max() || fabs(f) < 1e-10) {
+ return "%e";
+ // Else if the number is an integer exactly, print it without trailing zeros.
+ // eg: "1099511627776" to 1099511627776
+ } else if (int64_t(f) == f) {
+ return "%.0f";
+ }
+ return "%g";
+}
+
void BinaryPrimitive::PrettyPrint(Printer* printer) const {
using ::android::Res_value;
switch (value.dataType) {
@@ -470,7 +485,9 @@ void BinaryPrimitive::PrettyPrint(Printer* printer) const {
break;
case Res_value::TYPE_FLOAT:
- printer->Print(StringPrintf("%g", *reinterpret_cast<const float*>(&value.data)));
+ float f;
+ f = *reinterpret_cast<const float*>(&value.data);
+ printer->Print(StringPrintf(DecideFormat(f), f));
break;
case Res_value::TYPE_DIMENSION:
diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h
index 6f9dccbd3bcc..5192c2be1f98 100644
--- a/tools/aapt2/ResourceValues.h
+++ b/tools/aapt2/ResourceValues.h
@@ -284,6 +284,7 @@ struct BinaryPrimitive : public TransformableItem<BinaryPrimitive, BaseItem<Bina
bool Equals(const Value* value) const override;
bool Flatten(android::Res_value* out_value) const override;
void Print(std::ostream* out) const override;
+ static const char* DecideFormat(float f);
void PrettyPrint(text::Printer* printer) const override;
};
diff --git a/tools/aapt2/SdkConstants.cpp b/tools/aapt2/SdkConstants.cpp
index a766bd437120..83f2eb31aa57 100644
--- a/tools/aapt2/SdkConstants.cpp
+++ b/tools/aapt2/SdkConstants.cpp
@@ -16,20 +16,24 @@
#include "SdkConstants.h"
+#include <stdint.h>
+
#include <algorithm>
#include <string>
-#include <unordered_set>
-#include <vector>
+#include <string_view>
using android::StringPiece;
+using namespace std::literals;
namespace aapt {
-static ApiVersion sDevelopmentSdkLevel = 10000;
-static const auto sDevelopmentSdkCodeNames = std::unordered_set<StringPiece>(
- {"Q", "R", "S", "Sv2", "Tiramisu", "UpsideDownCake", "VanillaIceCream"});
+static constexpr ApiVersion sDevelopmentSdkLevel = 10000;
+static constexpr StringPiece sDevelopmentSdkCodeNames[] = {
+ "Q"sv, "R"sv, "S"sv, "Sv2"sv, "Tiramisu"sv, "UpsideDownCake"sv, "VanillaIceCream"sv};
+
+static constexpr auto sPrivacySandboxSuffix = "PrivacySandbox"sv;
-static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
+static constexpr std::pair<uint16_t, ApiVersion> sAttrIdMap[] = {
{0x021c, 1},
{0x021d, 2},
{0x0269, SDK_CUPCAKE},
@@ -62,25 +66,37 @@ static const std::vector<std::pair<uint16_t, ApiVersion>> sAttrIdMap = {
{0x064c, SDK_S_V2},
};
-static bool less_entry_id(const std::pair<uint16_t, ApiVersion>& p, uint16_t entryId) {
- return p.first < entryId;
-}
+static_assert(std::is_sorted(std::begin(sAttrIdMap), std::end(sAttrIdMap),
+ [](auto&& l, auto&& r) { return l.first < r.first; }));
ApiVersion FindAttributeSdkLevel(const ResourceId& id) {
if (id.package_id() != 0x01 || id.type_id() != 0x01) {
return 0;
}
- auto iter = std::lower_bound(sAttrIdMap.begin(), sAttrIdMap.end(), id.entry_id(), less_entry_id);
- if (iter == sAttrIdMap.end()) {
+ const auto it =
+ std::lower_bound(std::begin(sAttrIdMap), std::end(sAttrIdMap), id.entry_id(),
+ [](const auto& pair, uint16_t entryId) { return pair.first < entryId; });
+ if (it == std::end(sAttrIdMap)) {
return SDK_LOLLIPOP_MR1;
}
- return iter->second;
+ return it->second;
}
std::optional<ApiVersion> GetDevelopmentSdkCodeNameVersion(StringPiece code_name) {
- return (sDevelopmentSdkCodeNames.find(code_name) == sDevelopmentSdkCodeNames.end())
- ? std::optional<ApiVersion>()
- : sDevelopmentSdkLevel;
+ const auto it =
+ std::find_if(std::begin(sDevelopmentSdkCodeNames), std::end(sDevelopmentSdkCodeNames),
+ [code_name](const auto& item) { return code_name.starts_with(item); });
+ if (it == std::end(sDevelopmentSdkCodeNames)) {
+ return {};
+ }
+ if (code_name.size() == it->size()) {
+ return sDevelopmentSdkLevel;
+ }
+ if (code_name.size() == it->size() + sPrivacySandboxSuffix.size() &&
+ code_name.ends_with(sPrivacySandboxSuffix)) {
+ return sDevelopmentSdkLevel;
+ }
+ return {};
}
} // namespace aapt
diff --git a/tools/aapt2/SdkConstants_test.cpp b/tools/aapt2/SdkConstants_test.cpp
index 61f4d71b7fb2..0f645ffc1e8b 100644
--- a/tools/aapt2/SdkConstants_test.cpp
+++ b/tools/aapt2/SdkConstants_test.cpp
@@ -28,4 +28,24 @@ TEST(SdkConstantsTest, NonFrameworkAttributeIsSdk0) {
EXPECT_EQ(0, FindAttributeSdkLevel(ResourceId(0x7f010345)));
}
+TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionValid) {
+ EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("Q"));
+ EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("VanillaIceCream"));
+}
+
+TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionPrivacySandbox) {
+ EXPECT_EQ(std::optional<ApiVersion>(10000), GetDevelopmentSdkCodeNameVersion("QPrivacySandbox"));
+ EXPECT_EQ(std::optional<ApiVersion>(10000),
+ GetDevelopmentSdkCodeNameVersion("VanillaIceCreamPrivacySandbox"));
+}
+
+TEST(SdkConstantsTest, GetDevelopmentSdkCodeNameVersionInvalid) {
+ EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("A"));
+ EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("Sv3"));
+ EXPECT_EQ(std::optional<ApiVersion>(),
+ GetDevelopmentSdkCodeNameVersion("VanillaIceCream_PrivacySandbox"));
+ EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("PrivacySandbox"));
+ EXPECT_EQ(std::optional<ApiVersion>(), GetDevelopmentSdkCodeNameVersion("QQQQQQQQQQQQQQQ"));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index bb7b13a71412..728ba8aa4fdd 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -196,7 +196,20 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
// These are created as weak symbols, and are only generated from default
// configuration
// strings and plurals.
- PseudolocaleGenerator pseudolocale_generator;
+ std::string grammatical_gender_values;
+ std::string grammatical_gender_ratio;
+ if (options.pseudo_localize_gender_values) {
+ grammatical_gender_values = options.pseudo_localize_gender_values.value();
+ } else {
+ grammatical_gender_values = "f,m,n";
+ }
+ if (options.pseudo_localize_gender_ratio) {
+ grammatical_gender_ratio = options.pseudo_localize_gender_ratio.value();
+ } else {
+ grammatical_gender_ratio = "1.0";
+ }
+ PseudolocaleGenerator pseudolocale_generator(grammatical_gender_values,
+ grammatical_gender_ratio);
if (!pseudolocale_generator.Consume(context, &table)) {
return false;
}
@@ -607,6 +620,7 @@ class CompileContext : public IAaptContext {
void SetVerbose(bool val) {
verbose_ = val;
+ diagnostics_->SetVerbose(val);
}
bool IsVerbose() override {
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 984d8901ac56..61c5b60adb76 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -35,6 +35,8 @@ struct CompileOptions {
std::optional<std::string> res_dir;
std::optional<std::string> res_zip;
std::optional<std::string> generate_text_symbols_path;
+ std::optional<std::string> pseudo_localize_gender_values;
+ std::optional<std::string> pseudo_localize_gender_ratio;
std::optional<Visibility::Level> visibility;
bool pseudolocalize = false;
bool no_png_crunch = false;
@@ -77,6 +79,15 @@ class CompileCommand : public Command {
AddOptionalFlag("--source-path",
"Sets the compiled resource file source file path to the given string.",
&options_.source_path);
+ AddOptionalFlag("--pseudo-localize-gender-values",
+ "Sets the gender values to pick up for generating grammatical gender strings, "
+ "gender values should be f, m, or n, which are shortcuts for feminine, "
+ "masculine and neuter, and split with comma.",
+ &options_.pseudo_localize_gender_values);
+ AddOptionalFlag("--pseudo-localize-gender-ratio",
+ "Sets the ratio of resources to generate grammatical gender strings for. The "
+ "ratio has to be a float number between 0 and 1.",
+ &options_.pseudo_localize_gender_ratio);
AddOptionalFlag("--filter-product",
"Leave only resources specific to the given product. All "
"other resources (including defaults) are removed.",
diff --git a/tools/aapt2/cmd/Compile_test.cpp b/tools/aapt2/cmd/Compile_test.cpp
index 3464a7662c60..8880089d0e20 100644
--- a/tools/aapt2/cmd/Compile_test.cpp
+++ b/tools/aapt2/cmd/Compile_test.cpp
@@ -236,9 +236,24 @@ TEST_F(CompilerTest, DoNotTranslateTest) {
// The first string (000) is translatable, the second is not
// ar-XB uses "\u200F\u202E...\u202C\u200F"
std::vector<std::string> expected_translatable = {
- "000", "111", // default locale
- "[000 one]", // en-XA
- "\xE2\x80\x8F\xE2\x80\xAE" "000" "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB
+ "(F)[000 one]", // en-XA-feminine
+ "(F)\xE2\x80\x8F\xE2\x80\xAE"
+ "000"
+ "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-feminine
+ "(M)[000 one]", // en-XA-masculine
+ "(M)\xE2\x80\x8F\xE2\x80\xAE"
+ "000"
+ "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-masculine
+ "(N)[000 one]", // en-XA-neuter
+ "(N)\xE2\x80\x8F\xE2\x80\xAE"
+ "000"
+ "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB-neuter
+ "000", // default locale
+ "111", // default locale
+ "[000 one]", // en-XA
+ "\xE2\x80\x8F\xE2\x80\xAE"
+ "000"
+ "\xE2\x80\xAC\xE2\x80\x8F", // ar-XB
};
AssertTranslations(this, "foo", expected_translatable);
AssertTranslations(this, "foo_donottranslate", expected_translatable);
diff --git a/tools/aapt2/cmd/Convert.cpp b/tools/aapt2/cmd/Convert.cpp
index 7381a85f4339..387dcfe2ddf3 100644
--- a/tools/aapt2/cmd/Convert.cpp
+++ b/tools/aapt2/cmd/Convert.cpp
@@ -425,6 +425,7 @@ int ConvertCommand::Action(const std::vector<std::string>& args) {
if (force_sparse_encoding_) {
table_flattener_options_.sparse_entries = SparseEntriesMode::Forced;
}
+ table_flattener_options_.use_compact_entries = enable_compact_entries_;
if (resources_config_path_) {
if (!ExtractResourceConfig(*resources_config_path_, &context, table_flattener_options_)) {
return 1;
diff --git a/tools/aapt2/cmd/Convert.h b/tools/aapt2/cmd/Convert.h
index 15fe11fd91cc..9452e588953e 100644
--- a/tools/aapt2/cmd/Convert.h
+++ b/tools/aapt2/cmd/Convert.h
@@ -46,6 +46,10 @@ class ConvertCommand : public Command {
"This decreases APK size at the cost of resource retrieval performance.\n"
"Applies sparse encoding to all resources regardless of minSdk.",
&force_sparse_encoding_);
+ AddOptionalSwitch(
+ "--enable-compact-entries",
+ "This decreases APK size by using compact resource entries for simple data types.",
+ &enable_compact_entries_);
AddOptionalSwitch("--keep-raw-values",
android::base::StringPrintf("Preserve raw attribute values in xml files when using the"
" '%s' output format", kOutputFormatBinary),
@@ -85,6 +89,7 @@ class ConvertCommand : public Command {
bool verbose_ = false;
bool enable_sparse_encoding_ = false;
bool force_sparse_encoding_ = false;
+ bool enable_compact_entries_ = false;
std::optional<std::string> resources_config_path_;
};
diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp
index 71b08022f688..864af06f187e 100644
--- a/tools/aapt2/cmd/Dump.cpp
+++ b/tools/aapt2/cmd/Dump.cpp
@@ -112,6 +112,7 @@ class DumpContext : public IAaptContext {
void SetVerbose(bool val) {
verbose_ = val;
+ diagnostics_.SetVerbose(val);
}
int GetMinSdkVersion() override {
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 1fb5cc0919a3..c638873873dc 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -149,6 +149,7 @@ class LinkContext : public IAaptContext {
void SetVerbose(bool val) {
verbose_ = val;
+ diagnostics_->SetVerbose(val);
}
int GetMinSdkVersion() override {
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 725a1b86f616..7096f5cc54e3 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -441,8 +441,8 @@ static void BuildNonFinalizedSDK(const std::string& apk_path, const std::string&
R"(<resources>
<public type="attr" name="finalized_res" id="0x01010001"/>
- <!-- S staged attributes (support staged resources in the same type id) -->
- <staging-public-group type="attr" first-id="0x01010050">
+ <!-- S staged attributes (Not support staged resources in the same type id) -->
+ <staging-public-group type="attr" first-id="0x01fc0050">
<public name="staged_s_res" />
</staging-public-group>
@@ -480,8 +480,8 @@ static void BuildFinalizedSDK(const std::string& apk_path, const std::string& ja
<public type="attr" name="staged_s2_res" id="0x01010003"/>
<public type="string" name="staged_s_string" id="0x01020000"/>
- <!-- S staged attributes (support staged resources in the same type id) -->
- <staging-public-group-final type="attr" first-id="0x01010050">
+ <!-- S staged attributes (Not support staged resources in the same type id) -->
+ <staging-public-group-final type="attr" first-id="0x01fc0050">
<public name="staged_s_res" />
</staging-public-group-final>
@@ -551,7 +551,7 @@ TEST_F(LinkTest, StagedAndroidApi) {
EXPECT_THAT(android_r_contents, HasSubstr("public static final int finalized_res=0x01010001;"));
EXPECT_THAT(
android_r_contents,
- HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01010050; }"));
+ HasSubstr("public static final int staged_s_res; static { staged_s_res=0x01fc0050; }"));
EXPECT_THAT(
android_r_contents,
HasSubstr("public static final int staged_s_string; static { staged_s_string=0x01fd0080; }"));
@@ -583,7 +583,7 @@ TEST_F(LinkTest, StagedAndroidApi) {
result = am.GetResourceId("android:attr/staged_s_res");
ASSERT_TRUE(result.has_value());
- EXPECT_THAT(*result, Eq(0x01010050));
+ EXPECT_THAT(*result, Eq(0x01fc0050));
result = am.GetResourceId("android:string/staged_s_string");
ASSERT_TRUE(result.has_value());
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index dbe79701bf5c..f045dad6d11a 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -101,6 +101,7 @@ class OptimizeContext : public IAaptContext {
void SetVerbose(bool val) {
verbose_ = val;
+ diagnostics_.SetVerbose(val);
}
void SetMinSdkVersion(int sdk_version) {
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index b3f98a9d3e30..5421abde3689 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -37,6 +37,7 @@ using Result = expected<T, std::string>;
template <typename Id, typename Key>
struct NextIdFinder {
+ std::map<Id, Key> pre_assigned_ids_;
explicit NextIdFinder(Id start_id = 0u) : next_id_(start_id){};
// Attempts to reserve an identifier for the specified key.
@@ -55,7 +56,6 @@ struct NextIdFinder {
Id next_id_;
bool next_id_called_ = false;
bool exhausted_ = false;
- std::map<Id, Key> pre_assigned_ids_;
typename std::map<Id, Key>::iterator next_preassigned_id_;
};
@@ -158,7 +158,7 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
}
if (assigned_id_map_) {
- // Reserve all the IDs mentioned in the stable ID map. That way we won't assig IDs that were
+ // Reserve all the IDs mentioned in the stable ID map. That way we won't assign IDs that were
// listed in the map if they don't exist in the table.
for (const auto& stable_id_entry : *assigned_id_map_) {
const ResourceName& pre_assigned_name = stable_id_entry.first;
@@ -191,6 +191,11 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
}
namespace {
+static const std::string_view staged_type_overlap_error =
+ "Staged public resource type IDs have conflict with non staged public resources type "
+ "IDs, please restart staged resource type ID assignment at 0xff in public-staging.xml "
+ "and also delete all the overlapping groups in public-final.xml";
+
template <typename Id, typename Key>
Result<Id> NextIdFinder<Id, Key>::ReserveId(Key key, Id id) {
CHECK(!next_id_called_) << "ReserveId cannot be called after NextId";
@@ -282,8 +287,20 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
// another type.
auto assign_result = type_id_finder_.ReserveId(key, id.type_id());
if (!assign_result.has_value()) {
- diag->Error(android::DiagMessage() << "can't assign ID " << id << " to resource " << name
- << " because type " << assign_result.error());
+ auto pre_assigned_type = type_id_finder_.pre_assigned_ids_[id.type_id()].type;
+ bool pre_assigned_type_staged =
+ non_staged_type_ids_.find(pre_assigned_type) == non_staged_type_ids_.end();
+ auto hex_type_id = fmt::format("{:#04x}", (int)id.type_id());
+ bool current_type_staged = visibility.staged_api;
+ diag->Error(android::DiagMessage()
+ << "can't assign type ID " << hex_type_id << " to "
+ << (current_type_staged ? "staged type " : "non staged type ") << name.type.type
+ << " because this type ID have been assigned to "
+ << (pre_assigned_type_staged ? "staged type " : "non staged type ")
+ << pre_assigned_type);
+ if (pre_assigned_type_staged || current_type_staged) {
+ diag->Error(android::DiagMessage() << staged_type_overlap_error);
+ }
return false;
}
type = types_.emplace(key, TypeGroup(package_id_, id.type_id())).first;
@@ -298,6 +315,20 @@ bool IdAssignerContext::ReserveId(const ResourceName& name, ResourceId id,
<< " because type already has ID " << std::hex << (int)id.type_id());
return false;
}
+ } else {
+ // Ensure that staged public resources cannot have the same type name and type id with
+ // non staged public resources.
+ auto non_staged_type = non_staged_type_ids_.find(name.type.type);
+ if (non_staged_type != non_staged_type_ids_.end() && non_staged_type->second == id.type_id()) {
+ diag->Error(
+ android::DiagMessage()
+ << "can`t assign type ID " << fmt::format("{:#04x}", (int)id.type_id())
+ << " to staged type " << name.type.type << " because type ID "
+ << fmt::format("{:#04x}", (int)id.type_id())
+ << " already has been assigned to a non staged resource type with the same type name");
+ diag->Error(android::DiagMessage() << staged_type_overlap_error);
+ return false;
+ }
}
auto assign_result = type->second.ReserveId(name, id);
diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp
index 8911dad39470..ce45b7c1df04 100644
--- a/tools/aapt2/compile/IdAssigner_test.cpp
+++ b/tools/aapt2/compile/IdAssigner_test.cpp
@@ -117,14 +117,28 @@ TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIds) {
}
TEST_F(IdAssignerTests, FailWhenTypeHasTwoNonStagedIdsRegardlessOfStagedId) {
- auto table = test::ResourceTableBuilder()
- .AddSimple("android:attr/foo", ResourceId(0x01050000))
- .AddSimple("android:attr/bar", ResourceId(0x01ff0006))
- .Add(NewResourceBuilder("android:attr/staged_baz")
- .SetId(0x01ff0000)
- .SetVisibility({.staged_api = true})
- .Build())
- .Build();
+ auto table =
+ test::ResourceTableBuilder()
+ .AddSimple("android:attr/foo", ResourceId(0x01050000))
+ .AddSimple("android:attr/bar", ResourceId(0x01ff0006))
+ .Add(NewResourceBuilder("android:attr/staged_baz")
+ .SetId(0x01ff0000)
+ .SetVisibility({.staged_api = true, .level = Visibility::Level::kPublic})
+ .Build())
+ .Build();
+ IdAssigner assigner;
+ ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
+}
+
+TEST_F(IdAssignerTests, FailWhenTypeHaveBothStagedAndNonStagedIds) {
+ auto table =
+ test::ResourceTableBuilder()
+ .AddSimple("android:attr/foo", ResourceId(0x01010000))
+ .Add(NewResourceBuilder("android:bool/staged_baz")
+ .SetId(0x01010001)
+ .SetVisibility({.staged_api = true, .level = Visibility::Level::kPublic})
+ .Build())
+ .Build();
IdAssigner assigner;
ASSERT_FALSE(assigner.Consume(context.get(), table.get()));
}
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.cpp b/tools/aapt2/compile/PseudolocaleGenerator.cpp
index 09a8560f984a..8143052f4376 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator.cpp
@@ -16,11 +16,15 @@
#include "compile/PseudolocaleGenerator.h"
+#include <stdint.h>
+
#include <algorithm>
+#include <random>
#include "ResourceTable.h"
#include "ResourceValues.h"
#include "ValueVisitor.h"
+#include "androidfw/ResourceTypes.h"
#include "androidfw/Util.h"
#include "compile/Pseudolocalizer.h"
#include "util/Util.h"
@@ -293,8 +297,85 @@ class Visitor : public ValueVisitor {
Pseudolocalizer localizer_;
};
+class GrammaticalGenderVisitor : public ValueVisitor {
+ public:
+ std::unique_ptr<Value> value;
+ std::unique_ptr<Item> item;
+
+ GrammaticalGenderVisitor(android::StringPool* pool, uint8_t grammaticalInflection)
+ : pool_(pool), grammaticalInflection_(grammaticalInflection) {
+ }
+
+ void Visit(Plural* plural) override {
+ CloningValueTransformer cloner(pool_);
+ std::unique_ptr<Plural> grammatical_gendered = util::make_unique<Plural>();
+ for (size_t i = 0; i < plural->values.size(); i++) {
+ if (plural->values[i]) {
+ GrammaticalGenderVisitor sub_visitor(pool_, grammaticalInflection_);
+ plural->values[i]->Accept(&sub_visitor);
+ if (sub_visitor.item) {
+ grammatical_gendered->values[i] = std::move(sub_visitor.item);
+ } else {
+ grammatical_gendered->values[i] = plural->values[i]->Transform(cloner);
+ }
+ }
+ }
+ grammatical_gendered->SetSource(plural->GetSource());
+ grammatical_gendered->SetWeak(true);
+ value = std::move(grammatical_gendered);
+ }
+
+ std::string AddGrammaticalGenderPrefix(const std::string_view& original_string) {
+ std::string result;
+ switch (grammaticalInflection_) {
+ case android::ResTable_config::GRAMMATICAL_GENDER_MASCULINE:
+ result = std::string("(M)") + std::string(original_string);
+ break;
+ case android::ResTable_config::GRAMMATICAL_GENDER_FEMININE:
+ result = std::string("(F)") + std::string(original_string);
+ break;
+ case android::ResTable_config::GRAMMATICAL_GENDER_NEUTER:
+ result = std::string("(N)") + std::string(original_string);
+ break;
+ default:
+ result = std::string(original_string);
+ break;
+ }
+ return result;
+ }
+
+ void Visit(String* string) override {
+ std::string prefixed_string = AddGrammaticalGenderPrefix(std::string(*string->value));
+ std::unique_ptr<String> grammatical_gendered =
+ util::make_unique<String>(pool_->MakeRef(prefixed_string));
+ grammatical_gendered->SetSource(string->GetSource());
+ grammatical_gendered->SetWeak(true);
+ item = std::move(grammatical_gendered);
+ }
+
+ void Visit(StyledString* string) override {
+ std::string prefixed_string = AddGrammaticalGenderPrefix(std::string(string->value->value));
+ android::StyleString new_string;
+ new_string.str = std::move(prefixed_string);
+ for (const android::StringPool::Span& span : string->value->spans) {
+ new_string.spans.emplace_back(android::Span{*span.name, span.first_char, span.last_char});
+ }
+ std::unique_ptr<StyledString> grammatical_gendered =
+ util::make_unique<StyledString>(pool_->MakeRef(new_string));
+ grammatical_gendered->SetSource(string->GetSource());
+ grammatical_gendered->SetWeak(true);
+ item = std::move(grammatical_gendered);
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(GrammaticalGenderVisitor);
+ android::StringPool* pool_;
+ uint8_t grammaticalInflection_;
+};
+
ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base,
- Pseudolocalizer::Method m) {
+ Pseudolocalizer::Method m,
+ uint8_t grammaticalInflection) {
ConfigDescription modified = base;
switch (m) {
case Pseudolocalizer::Method::kAccent:
@@ -313,12 +394,64 @@ ConfigDescription ModifyConfigForPseudoLocale(const ConfigDescription& base,
default:
break;
}
+ modified.grammaticalInflection = grammaticalInflection;
return modified;
}
+void GrammaticalGender(ResourceConfigValue* original_value,
+ ResourceConfigValue* localized_config_value, android::StringPool* pool,
+ ResourceEntry* entry, const Pseudolocalizer::Method method,
+ uint8_t grammaticalInflection) {
+ GrammaticalGenderVisitor visitor(pool, grammaticalInflection);
+ localized_config_value->value->Accept(&visitor);
+
+ std::unique_ptr<Value> grammatical_gendered_value;
+ if (visitor.value) {
+ grammatical_gendered_value = std::move(visitor.value);
+ } else if (visitor.item) {
+ grammatical_gendered_value = std::move(visitor.item);
+ }
+ if (!grammatical_gendered_value) {
+ return;
+ }
+
+ ConfigDescription config =
+ ModifyConfigForPseudoLocale(original_value->config, method, grammaticalInflection);
+
+ ResourceConfigValue* grammatical_gendered_config_value =
+ entry->FindOrCreateValue(config, original_value->product);
+ if (!grammatical_gendered_config_value->value) {
+ // Only use auto-generated pseudo-localization if none is defined.
+ grammatical_gendered_config_value->value = std::move(grammatical_gendered_value);
+ }
+}
+
+const uint32_t MASK_MASCULINE = 1; // Bit mask for masculine
+const uint32_t MASK_FEMININE = 2; // Bit mask for feminine
+const uint32_t MASK_NEUTER = 4; // Bit mask for neuter
+
+void GrammaticalGenderIfNeeded(ResourceConfigValue* original_value, ResourceConfigValue* new_value,
+ android::StringPool* pool, ResourceEntry* entry,
+ const Pseudolocalizer::Method method, uint32_t gender_state) {
+ if (gender_state & MASK_FEMININE) {
+ GrammaticalGender(original_value, new_value, pool, entry, method,
+ android::ResTable_config::GRAMMATICAL_GENDER_FEMININE);
+ }
+
+ if (gender_state & MASK_MASCULINE) {
+ GrammaticalGender(original_value, new_value, pool, entry, method,
+ android::ResTable_config::GRAMMATICAL_GENDER_MASCULINE);
+ }
+
+ if (gender_state & MASK_NEUTER) {
+ GrammaticalGender(original_value, new_value, pool, entry, method,
+ android::ResTable_config::GRAMMATICAL_GENDER_NEUTER);
+ }
+}
+
void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
ResourceConfigValue* original_value, android::StringPool* pool,
- ResourceEntry* entry) {
+ ResourceEntry* entry, uint32_t gender_state, bool gender_flag) {
Visitor visitor(pool, method);
original_value->value->Accept(&visitor);
@@ -333,8 +466,8 @@ void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
return;
}
- ConfigDescription config_with_accent =
- ModifyConfigForPseudoLocale(original_value->config, method);
+ ConfigDescription config_with_accent = ModifyConfigForPseudoLocale(
+ original_value->config, method, android::ResTable_config::GRAMMATICAL_GENDER_ANY);
ResourceConfigValue* new_config_value =
entry->FindOrCreateValue(config_with_accent, original_value->product);
@@ -342,6 +475,9 @@ void PseudolocalizeIfNeeded(const Pseudolocalizer::Method method,
// Only use auto-generated pseudo-localization if none is defined.
new_config_value->value = std::move(localized_value);
}
+ if (gender_flag) {
+ GrammaticalGenderIfNeeded(original_value, new_config_value, pool, entry, method, gender_state);
+ }
}
// A value is pseudolocalizable if it does not define a locale (or is the default locale) and is
@@ -356,16 +492,71 @@ static bool IsPseudolocalizable(ResourceConfigValue* config_value) {
} // namespace
+bool ParseGenderValuesAndSaveState(const std::string& grammatical_gender_values,
+ uint32_t* gender_state, android::IDiagnostics* diag) {
+ std::vector<std::string> values = util::SplitAndLowercase(grammatical_gender_values, ',');
+ for (size_t i = 0; i < values.size(); i++) {
+ if (values[i].length() != 0) {
+ if (values[i] == "f") {
+ *gender_state |= MASK_FEMININE;
+ } else if (values[i] == "m") {
+ *gender_state |= MASK_MASCULINE;
+ } else if (values[i] == "n") {
+ *gender_state |= MASK_NEUTER;
+ } else {
+ diag->Error(android::DiagMessage() << "Invalid grammatical gender value: " << values[i]);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool ParseGenderRatio(const std::string& grammatical_gender_ratio, float* gender_ratio,
+ android::IDiagnostics* diag) {
+ const char* input = grammatical_gender_ratio.c_str();
+ char* endPtr;
+ errno = 0;
+ *gender_ratio = strtof(input, &endPtr);
+ if (endPtr == input || *endPtr != '\0' || errno == ERANGE || *gender_ratio < 0 ||
+ *gender_ratio > 1) {
+ diag->Error(android::DiagMessage()
+ << "Invalid grammatical gender ratio: " << grammatical_gender_ratio
+ << ", must be a real number between 0 and 1");
+ return false;
+ }
+ return true;
+}
+
bool PseudolocaleGenerator::Consume(IAaptContext* context, ResourceTable* table) {
+ uint32_t gender_state = 0;
+ if (!ParseGenderValuesAndSaveState(grammatical_gender_values_, &gender_state,
+ context->GetDiagnostics())) {
+ return false;
+ }
+
+ float gender_ratio = 0;
+ if (!ParseGenderRatio(grammatical_gender_ratio_, &gender_ratio, context->GetDiagnostics())) {
+ return false;
+ }
+
+ std::random_device rd;
+ std::mt19937 gen(rd());
+ std::uniform_real_distribution<> distrib(0.0, 1.0);
+
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
+ bool gender_flag = false;
+ if (distrib(gen) < gender_ratio) {
+ gender_flag = true;
+ }
std::vector<ResourceConfigValue*> values = entry->FindValuesIf(IsPseudolocalizable);
for (ResourceConfigValue* value : values) {
PseudolocalizeIfNeeded(Pseudolocalizer::Method::kAccent, value, &table->string_pool,
- entry.get());
+ entry.get(), gender_state, gender_flag);
PseudolocalizeIfNeeded(Pseudolocalizer::Method::kBidi, value, &table->string_pool,
- entry.get());
+ entry.get(), gender_state, gender_flag);
}
}
}
diff --git a/tools/aapt2/compile/PseudolocaleGenerator.h b/tools/aapt2/compile/PseudolocaleGenerator.h
index 44e6e3e86f92..ce92008cdba1 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator.h
+++ b/tools/aapt2/compile/PseudolocaleGenerator.h
@@ -27,8 +27,19 @@ std::unique_ptr<StyledString> PseudolocalizeStyledString(StyledString* string,
Pseudolocalizer::Method method,
android::StringPool* pool);
-struct PseudolocaleGenerator : public IResourceTableConsumer {
- bool Consume(IAaptContext* context, ResourceTable* table) override;
+class PseudolocaleGenerator : public IResourceTableConsumer {
+ public:
+ explicit PseudolocaleGenerator(std::string grammatical_gender_values,
+ std::string grammatical_gender_ratio)
+ : grammatical_gender_values_(std::move(grammatical_gender_values)),
+ grammatical_gender_ratio_(std::move(grammatical_gender_ratio)) {
+ }
+
+ bool Consume(IAaptContext* context, ResourceTable* table);
+
+ private:
+ std::string grammatical_gender_values_;
+ std::string grammatical_gender_ratio_;
};
} // namespace aapt
diff --git a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
index 2f90cbf722c2..1477ebf8473d 100644
--- a/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
+++ b/tools/aapt2/compile/PseudolocaleGenerator_test.cpp
@@ -197,7 +197,7 @@ TEST(PseudolocaleGeneratorTest, PseudolocalizeOnlyDefaultConfigs) {
val->SetTranslatable(false);
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
- PseudolocaleGenerator generator;
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
ASSERT_TRUE(generator.Consume(context.get(), table.get()));
// Normal pseudolocalization should take place.
@@ -249,7 +249,7 @@ TEST(PseudolocaleGeneratorTest, PluralsArePseudolocalized) {
expected->values = {util::make_unique<String>(table->string_pool.MakeRef("[žéŕö one]")),
util::make_unique<String>(table->string_pool.MakeRef("[öñé one]"))};
- PseudolocaleGenerator generator;
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
ASSERT_TRUE(generator.Consume(context.get(), table.get()));
const auto* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo",
@@ -287,7 +287,7 @@ TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) {
context->GetDiagnostics()));
}
- PseudolocaleGenerator generator;
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
ASSERT_TRUE(generator.Consume(context.get(), table.get()));
StyledString* new_styled_string = test::GetValueForConfig<StyledString>(
@@ -305,4 +305,213 @@ TEST(PseudolocaleGeneratorTest, RespectUntranslateableSections) {
EXPECT_NE(std::string::npos, new_string->value->find("world"));
}
+TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForString) {
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build();
+
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
+ ASSERT_TRUE(generator.Consume(context.get(), table.get()));
+
+ String* locale = test::GetValueForConfig<String>(table.get(), "android:string/foo",
+ test::ParseConfigOrDie("en-rXA"));
+ ASSERT_NE(nullptr, locale);
+
+ // Grammatical gendered string
+ auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine");
+ config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* feminine =
+ test::GetValueForConfig<String>(table.get(), "android:string/foo", config_feminine);
+ ASSERT_NE(nullptr, feminine);
+ EXPECT_EQ(std::string("(F)") + *locale->value, *feminine->value);
+
+ auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine");
+ config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* masculine =
+ test::GetValueForConfig<String>(table.get(), "android:string/foo", config_masculine);
+ ASSERT_NE(nullptr, masculine);
+ EXPECT_EQ(std::string("(M)") + *locale->value, *masculine->value);
+
+ auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter");
+ config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* neuter =
+ test::GetValueForConfig<String>(table.get(), "android:string/foo", config_neuter);
+ ASSERT_NE(nullptr, neuter);
+ EXPECT_EQ(std::string("(N)") + *locale->value, *neuter->value);
+}
+
+TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForPlural) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder().Build();
+ std::unique_ptr<Plural> plural = util::make_unique<Plural>();
+ plural->values = {util::make_unique<String>(table->string_pool.MakeRef("zero")),
+ util::make_unique<String>(table->string_pool.MakeRef("one"))};
+ ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("com.pkg:plurals/foo"))
+ .SetValue(std::move(plural))
+ .Build(),
+ context->GetDiagnostics()));
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
+ ASSERT_TRUE(generator.Consume(context.get(), table.get()));
+
+ Plural* actual = test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo",
+ test::ParseConfigOrDie("en-rXA"));
+ ASSERT_NE(nullptr, actual);
+
+ // Grammatical gendered Plural
+ auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine");
+ config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ Plural* actual_feminine =
+ test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_feminine);
+ for (size_t i = 0; i < actual->values.size(); i++) {
+ if (actual->values[i]) {
+ String* locale = ValueCast<String>(actual->values[i].get());
+ String* feminine = ValueCast<String>(actual_feminine->values[i].get());
+ EXPECT_EQ(std::string("(F)") + *locale->value, *feminine->value);
+ }
+ }
+
+ auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine");
+ config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ Plural* actual_masculine =
+ test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_masculine);
+ ASSERT_NE(nullptr, actual_masculine);
+ for (size_t i = 0; i < actual->values.size(); i++) {
+ if (actual->values[i]) {
+ String* locale = ValueCast<String>(actual->values[i].get());
+ String* masculine = ValueCast<String>(actual_masculine->values[i].get());
+ EXPECT_EQ(std::string("(M)") + *locale->value, *masculine->value);
+ }
+ }
+
+ auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter");
+ config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ Plural* actual_neuter =
+ test::GetValueForConfig<Plural>(table.get(), "com.pkg:plurals/foo", config_neuter);
+ for (size_t i = 0; i < actual->values.size(); i++) {
+ if (actual->values[i]) {
+ String* locale = ValueCast<String>(actual->values[i].get());
+ String* neuter = ValueCast<String>(actual_neuter->values[i].get());
+ EXPECT_EQ(std::string("(N)") + *locale->value, *neuter->value);
+ }
+ }
+}
+
+TEST(PseudolocaleGeneratorTest, PseudolocalizeGrammaticalGenderForStyledString) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder().Build();
+ android::StyleString original_style;
+ original_style.str = "Hello world!";
+ original_style.spans = {android::Span{"i", 1, 10}};
+
+ std::unique_ptr<StyledString> original =
+ util::make_unique<StyledString>(table->string_pool.MakeRef(original_style));
+ ASSERT_TRUE(table->AddResource(NewResourceBuilder(test::ParseNameOrDie("android:string/foo"))
+ .SetValue(std::move(original))
+ .Build(),
+ context->GetDiagnostics()));
+ PseudolocaleGenerator generator(std::string("f,m,n"), std::string("1.0"));
+ ASSERT_TRUE(generator.Consume(context.get(), table.get()));
+
+ StyledString* locale = test::GetValueForConfig<StyledString>(table.get(), "android:string/foo",
+ test::ParseConfigOrDie("en-rXA"));
+ ASSERT_NE(nullptr, locale);
+ EXPECT_EQ(1, locale->value->spans.size());
+ EXPECT_EQ(std::string("i"), *locale->value->spans[0].name);
+
+ // Grammatical gendered StyledString
+ auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine");
+ config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ StyledString* feminine =
+ test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_feminine);
+ ASSERT_NE(nullptr, feminine);
+ EXPECT_EQ(1, feminine->value->spans.size());
+ EXPECT_EQ(std::string("i"), *feminine->value->spans[0].name);
+ EXPECT_EQ(std::string("(F)") + locale->value->value, feminine->value->value);
+
+ auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine");
+ config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ StyledString* masculine =
+ test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_masculine);
+ ASSERT_NE(nullptr, masculine);
+ EXPECT_EQ(1, masculine->value->spans.size());
+ EXPECT_EQ(std::string("i"), *masculine->value->spans[0].name);
+ EXPECT_EQ(std::string("(M)") + locale->value->value, masculine->value->value);
+
+ auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter");
+ config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ StyledString* neuter =
+ test::GetValueForConfig<StyledString>(table.get(), "android:string/foo", config_neuter);
+ ASSERT_NE(nullptr, neuter);
+ EXPECT_EQ(1, neuter->value->spans.size());
+ EXPECT_EQ(std::string("i"), *neuter->value->spans[0].name);
+ EXPECT_EQ(std::string("(N)") + locale->value->value, neuter->value->value);
+}
+
+TEST(PseudolocaleGeneratorTest, GrammaticalGenderForCertainValues) {
+ // single gender value
+ std::unique_ptr<ResourceTable> table_0 =
+ test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build();
+
+ std::unique_ptr<IAaptContext> context_0 = test::ContextBuilder().Build();
+ PseudolocaleGenerator generator_0(std::string("f"), std::string("1.0"));
+ ASSERT_TRUE(generator_0.Consume(context_0.get(), table_0.get()));
+
+ String* locale_0 = test::GetValueForConfig<String>(table_0.get(), "android:string/foo",
+ test::ParseConfigOrDie("en-rXA"));
+ ASSERT_NE(nullptr, locale_0);
+
+ auto config_feminine = test::ParseConfigOrDie("en-rXA-feminine");
+ config_feminine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* feminine_0 =
+ test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_feminine);
+ ASSERT_NE(nullptr, feminine_0);
+ EXPECT_EQ(std::string("(F)") + *locale_0->value, *feminine_0->value);
+
+ auto config_masculine = test::ParseConfigOrDie("en-rXA-masculine");
+ config_masculine.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* masculine_0 =
+ test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_masculine);
+ EXPECT_EQ(nullptr, masculine_0);
+
+ auto config_neuter = test::ParseConfigOrDie("en-rXA-neuter");
+ config_neuter.sdkVersion = android::ResTable_config::SDKVERSION_ANY;
+ String* neuter_0 =
+ test::GetValueForConfig<String>(table_0.get(), "android:string/foo", config_neuter);
+ EXPECT_EQ(nullptr, neuter_0);
+
+ // multiple gender values
+ std::unique_ptr<ResourceTable> table_1 =
+ test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build();
+
+ std::unique_ptr<IAaptContext> context_1 = test::ContextBuilder().Build();
+ PseudolocaleGenerator generator_1(std::string("f,n"), std::string("1.0"));
+ ASSERT_TRUE(generator_1.Consume(context_1.get(), table_1.get()));
+
+ String* locale_1 = test::GetValueForConfig<String>(table_1.get(), "android:string/foo",
+ test::ParseConfigOrDie("en-rXA"));
+ ASSERT_NE(nullptr, locale_1);
+
+ String* feminine_1 =
+ test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_feminine);
+ ASSERT_NE(nullptr, feminine_1);
+ EXPECT_EQ(std::string("(F)") + *locale_1->value, *feminine_1->value);
+
+ String* masculine_1 =
+ test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_masculine);
+ EXPECT_EQ(nullptr, masculine_1);
+
+ String* neuter_1 =
+ test::GetValueForConfig<String>(table_1.get(), "android:string/foo", config_neuter);
+ ASSERT_NE(nullptr, neuter_1);
+ EXPECT_EQ(std::string("(N)") + *locale_1->value, *neuter_1->value);
+
+ // invalid gender value
+ std::unique_ptr<ResourceTable> table_2 =
+ test::ResourceTableBuilder().AddString("android:string/foo", "foo").Build();
+
+ std::unique_ptr<IAaptContext> context_2 = test::ContextBuilder().Build();
+ PseudolocaleGenerator generator_2(std::string("invald,"), std::string("1.0"));
+ ASSERT_FALSE(generator_2.Consume(context_2.get(), table_2.get()));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index adb682730f5a..a2b48187c24f 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -835,9 +835,9 @@ class UsesSdkBadging : public ManifestExtractor::Element {
void Print(text::Printer* printer) override {
if (min_sdk) {
- printer->Print(StringPrintf("sdkVersion:'%d'\n", *min_sdk));
+ printer->Print(StringPrintf("minSdkVersion:'%d'\n", *min_sdk));
} else if (min_sdk_name) {
- printer->Print(StringPrintf("sdkVersion:'%s'\n", min_sdk_name->data()));
+ printer->Print(StringPrintf("minSdkVersion:'%s'\n", min_sdk_name->data()));
}
if (max_sdk) {
printer->Print(StringPrintf("maxSdkVersion:'%d'\n", *max_sdk));
diff --git a/tools/aapt2/format/Archive_test.cpp b/tools/aapt2/format/Archive_test.cpp
index 3c44da710d94..fd50af92ceee 100644
--- a/tools/aapt2/format/Archive_test.cpp
+++ b/tools/aapt2/format/Archive_test.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <stdlib.h>
+
#include "test/Test.h"
namespace aapt {
@@ -34,6 +36,29 @@ class TestData : public io::MallocData {
std::string error_;
};
+class TzSetter {
+ public:
+ explicit TzSetter(const std::string& new_tz) {
+ old_tz_ = getenv("TZ");
+ new_tz_ = "TZ=" + new_tz;
+ putenv(const_cast<char*>(new_tz_.c_str()));
+ tzset();
+ }
+
+ ~TzSetter() {
+ if (old_tz_) {
+ putenv(old_tz_);
+ } else {
+ putenv(const_cast<char*>("TZ"));
+ }
+ tzset();
+ }
+
+ private:
+ char* old_tz_;
+ std::string new_tz_;
+};
+
std::unique_ptr<uint8_t[]> MakeTestArray() {
auto array = std::make_unique<uint8_t[]>(kTestDataLength);
for (int index = 0; index < kTestDataLength; ++index) {
@@ -86,6 +111,22 @@ void VerifyZipFile(const std::string& output_path, const std::string& file, cons
}
}
+void VerifyZipFileTimestamps(const std::string& output_path) {
+ std::unique_ptr<io::ZipFileCollection> zip = io::ZipFileCollection::Create(output_path, nullptr);
+ auto it = zip->Iterator();
+ while (it->HasNext()) {
+ auto file = it->Next();
+ struct tm modification_time;
+ ASSERT_TRUE(file->GetModificationTime(&modification_time));
+ EXPECT_EQ(modification_time.tm_year, 80);
+ EXPECT_EQ(modification_time.tm_mon, 0);
+ EXPECT_EQ(modification_time.tm_mday, 1);
+ EXPECT_EQ(modification_time.tm_hour, 0);
+ EXPECT_EQ(modification_time.tm_min, 0);
+ EXPECT_EQ(modification_time.tm_sec, 0);
+ }
+}
+
TEST_F(ArchiveTest, DirectoryWriteEntrySuccess) {
std::string output_path = GetTestPath("output");
std::unique_ptr<IArchiveWriter> writer = MakeDirectoryWriter(output_path);
@@ -206,4 +247,73 @@ TEST_F(ArchiveTest, ZipFileWriteFileError) {
ASSERT_EQ("ZipFileWriteFileError", writer->GetError());
}
+TEST_F(ArchiveTest, ZipFileTimeZoneUTC) {
+ TzSetter tz("UTC0");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
+TEST_F(ArchiveTest, ZipFileTimeZoneWestOfUTC) {
+ TzSetter tz("PST8");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
+TEST_F(ArchiveTest, ZipFileTimeZoneEastOfUTC) {
+ TzSetter tz("EET-2");
+ std::string output_path = GetTestPath("output.apk");
+ std::unique_ptr<IArchiveWriter> writer = MakeZipFileWriter(output_path);
+ std::unique_ptr<uint8_t[]> data1 = MakeTestArray();
+ std::unique_ptr<uint8_t[]> data2 = MakeTestArray();
+
+ ASSERT_TRUE(writer->StartEntry("test1", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data1.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ ASSERT_TRUE(writer->StartEntry("test2", 0));
+ ASSERT_TRUE(writer->Write(static_cast<const void*>(data2.get()), kTestDataLength));
+ ASSERT_TRUE(writer->FinishEntry());
+ ASSERT_FALSE(writer->HadError());
+
+ writer.reset();
+
+ // All zip file entries must have the same timestamp, regardless of time zone. See: b/277978832
+ VerifyZipFileTimestamps(output_path);
+}
+
} // namespace aapt
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 8c594ba553a0..f05611048caa 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -68,9 +68,8 @@ struct OverlayableChunk {
class PackageFlattener {
public:
PackageFlattener(IAaptContext* context, const ResourceTablePackageView& package,
- const std::map<size_t, std::string>* shared_libs,
- SparseEntriesMode sparse_entries,
- bool compact_entries,
+ const ResourceTable::ReferencedPackages* shared_libs,
+ SparseEntriesMode sparse_entries, bool compact_entries,
bool collapse_key_stringpool,
const std::set<ResourceName>& name_collapse_exemptions,
bool deduplicate_entry_values)
@@ -145,10 +144,9 @@ class PackageFlattener {
// 2) the entries will be accessed on platforms U+, and
// 3) all entry keys can be encoded in 16 bits
bool UseCompactEntries(const ConfigDescription& config, std::vector<FlatEntry>* entries) const {
- return compact_entries_ &&
- (context_->GetMinSdkVersion() > SDK_TIRAMISU || config.sdkVersion > SDK_TIRAMISU) &&
- std::none_of(entries->cbegin(), entries->cend(),
- [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); });
+ return compact_entries_ && context_->GetMinSdkVersion() > SDK_TIRAMISU &&
+ std::none_of(entries->cbegin(), entries->cend(),
+ [](const auto& e) { return e.entry_key >= std::numeric_limits<uint16_t>::max(); });
}
std::unique_ptr<ResEntryWriter> GetResEntryWriter(bool dedup, bool compact, BigBuffer* buffer) {
@@ -548,7 +546,7 @@ class PackageFlattener {
IAaptContext* context_;
android::IDiagnostics* diag_;
const ResourceTablePackageView package_;
- const std::map<size_t, std::string>* shared_libs_;
+ const ResourceTable::ReferencedPackages* shared_libs_;
SparseEntriesMode sparse_entries_;
bool compact_entries_;
android::StringPool type_pool_;
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 09ef9bddd3bd..e1a3013c07bb 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -916,7 +916,7 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item,
} break;
case pb::Primitive::kIntDecimalValue: {
val.dataType = android::Res_value::TYPE_INT_DEC;
- val.data = static_cast<uint32_t>(pb_prim.int_decimal_value());
+ val.data = static_cast<int32_t>(pb_prim.int_decimal_value());
} break;
case pb::Primitive::kIntHexadecimalValue: {
val.dataType = android::Res_value::TYPE_INT_HEX;
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index afb83562b129..fa8860ff69eb 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -250,6 +250,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
}
TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
xml::Element element;
element.line_number = 22;
element.column_number = 23;
@@ -269,8 +270,8 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
attr.namespace_uri = xml::kSchemaAndroid;
attr.value = "23dp";
attr.compiled_attribute = xml::AaptAttribute(Attribute{}, ResourceId(0x01010000));
- attr.compiled_value =
- ResourceUtils::TryParseItemForAttribute(attr.value, android::ResTable_map::TYPE_DIMENSION);
+ attr.compiled_value = ResourceUtils::TryParseItemForAttribute(
+ context->GetDiagnostics(), attr.value, android::ResTable_map::TYPE_DIMENSION);
attr.compiled_value->SetSource(android::Source().WithLine(25));
element.attributes.push_back(std::move(attr));
diff --git a/tools/aapt2/integration-tests/AutoVersionTest/Android.bp b/tools/aapt2/integration-tests/AutoVersionTest/Android.bp
index bfd35083366e..c901efa707f4 100644
--- a/tools/aapt2/integration-tests/AutoVersionTest/Android.bp
+++ b/tools/aapt2/integration-tests/AutoVersionTest/Android.bp
@@ -26,4 +26,5 @@ package {
android_test {
name: "AaptAutoVersionTest",
sdk_version: "current",
+ use_resource_processor: false,
}
diff --git a/tools/aapt2/integration-tests/BasicTest/Android.bp b/tools/aapt2/integration-tests/BasicTest/Android.bp
index 7db9d2698cc7..d0649ea4ef9c 100644
--- a/tools/aapt2/integration-tests/BasicTest/Android.bp
+++ b/tools/aapt2/integration-tests/BasicTest/Android.bp
@@ -26,4 +26,5 @@ package {
android_test {
name: "AaptBasicTest",
sdk_version: "current",
+ use_resource_processor: false,
}
diff --git a/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt
index cc0b3bf5d2fb..d14e5fb5c477 100644
--- a/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt
+++ b/tools/aapt2/integration-tests/DumpTest/built_with_aapt_expected.txt
@@ -1,5 +1,5 @@
package: name='com.aapt.app' versionCode='222' versionName='222' platformBuildVersionName='12' platformBuildVersionCode='32' compileSdkVersion='32' compileSdkVersionCodename='12'
-sdkVersion:'22'
+minSdkVersion:'22'
targetSdkVersion:'32'
application: label='App' icon=''
feature-group: label=''
diff --git a/tools/aapt2/integration-tests/DumpTest/components_expected.txt b/tools/aapt2/integration-tests/DumpTest/components_expected.txt
index 9c81fb83ca15..93cce0a29024 100644
--- a/tools/aapt2/integration-tests/DumpTest/components_expected.txt
+++ b/tools/aapt2/integration-tests/DumpTest/components_expected.txt
@@ -1,5 +1,5 @@
package: name='com.example.bundletool.minimal' versionCode='1' versionName='1.0' platformBuildVersionName='12' platformBuildVersionCode='31' compileSdkVersion='31' compileSdkVersionCodename='12'
-sdkVersion:'21'
+minSdkVersion:'21'
targetSdkVersion:'31'
uses-configuration: reqTouchScreen='3' reqKeyboardType='2' reqHardKeyboard='-1' reqNavigation='3' reqFiveWayNav='-1'
supports-gl-texture:'GL_OES_compressed_paletted_texture'
diff --git a/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt
index 85ab5d80cd39..aafca68443a9 100644
--- a/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt
+++ b/tools/aapt2/integration-tests/DumpTest/minimal_expected.txt
@@ -1,5 +1,5 @@
package: name='com.lato.bubblegirl' versionCode='33' versionName='1.0.0' platformBuildVersionName='8.1.0' platformBuildVersionCode='27'
-sdkVersion:'19'
+minSdkVersion:'19'
targetSdkVersion:'26'
application-label:'Bubble Girl'
application-label-ar:'Bubble Girl'
diff --git a/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt b/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt
index 85e8d0a3cbba..f48f381e3012 100644
--- a/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt
+++ b/tools/aapt2/integration-tests/DumpTest/multiple_uses_sdk_expected.txt
@@ -1,5 +1,5 @@
package: name='com.test.e17wmultiapknexus' versionCode='107' versionName='14' platformBuildVersionName='2.3.3' platformBuildVersionCode='10'
-sdkVersion:'1'
+minSdkVersion:'1'
application-label:'w45wmultiapknexus_10'
application-icon-120:'res/drawable-ldpi-v4/icon.png'
application-icon-160:'res/drawable-mdpi-v4/icon.png'
diff --git a/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp
index 80404eeb8d8e..ebb4e9f479d6 100644
--- a/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp
+++ b/tools/aapt2/integration-tests/StaticLibTest/App/Android.bp
@@ -24,9 +24,9 @@ package {
}
android_test {
-
name: "AaptTestStaticLib_App",
sdk_version: "current",
+ use_resource_processor: false,
srcs: ["src/**/*.java"],
asset_dirs: [
"assets",
diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp
index a84da43c70c8..ee12a92906a8 100644
--- a/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp
+++ b/tools/aapt2/integration-tests/StaticLibTest/LibOne/Android.bp
@@ -26,6 +26,7 @@ package {
android_library {
name: "AaptTestStaticLib_LibOne",
sdk_version: "current",
+ use_resource_processor: false,
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
}
diff --git a/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp b/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp
index d386c3a35d20..83b2362496fc 100644
--- a/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp
+++ b/tools/aapt2/integration-tests/StaticLibTest/LibTwo/Android.bp
@@ -26,6 +26,7 @@ package {
android_library {
name: "AaptTestStaticLib_LibTwo",
sdk_version: "current",
+ use_resource_processor: false,
srcs: ["src/**/*.java"],
resource_dirs: ["res"],
libs: ["AaptTestStaticLib_LibOne"],
diff --git a/tools/aapt2/integration-tests/SymlinkTest/Android.bp b/tools/aapt2/integration-tests/SymlinkTest/Android.bp
index 1e8cf86ed811..15a6a207d6d1 100644
--- a/tools/aapt2/integration-tests/SymlinkTest/Android.bp
+++ b/tools/aapt2/integration-tests/SymlinkTest/Android.bp
@@ -26,4 +26,5 @@ package {
android_test {
name: "AaptSymlinkTest",
sdk_version: "current",
+ use_resource_processor: false,
}
diff --git a/tools/aapt2/io/File.h b/tools/aapt2/io/File.h
index 08d497def8a4..673d1b75e660 100644
--- a/tools/aapt2/io/File.h
+++ b/tools/aapt2/io/File.h
@@ -57,6 +57,11 @@ class IFile {
return false;
}
+ // Fills in buf with the last modification time of the file. Returns true if successful,
+ // otherwise false (i.e., the operation is not supported or the file system is unable to provide
+ // a last modification time).
+ virtual bool GetModificationTime(struct tm* buf) const = 0;
+
private:
// Any segments created from this IFile need to be owned by this IFile, so
// keep them
@@ -79,6 +84,10 @@ class FileSegment : public IFile {
return file_->GetSource();
}
+ bool GetModificationTime(struct tm* buf) const override {
+ return file_->GetModificationTime(buf);
+ };
+
private:
DISALLOW_COPY_AND_ASSIGN(FileSegment);
diff --git a/tools/aapt2/io/FileSystem.cpp b/tools/aapt2/io/FileSystem.cpp
index a64982a7fa5c..6a692e497816 100644
--- a/tools/aapt2/io/FileSystem.cpp
+++ b/tools/aapt2/io/FileSystem.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+#define _POSIX_THREAD_SAFE_FUNCTIONS // For mingw localtime_r().
+
#include "io/FileSystem.h"
#include <dirent.h>
+#include <sys/stat.h>
#include "android-base/errors.h"
#include "androidfw/Source.h"
@@ -54,6 +57,23 @@ const android::Source& RegularFile::GetSource() const {
return source_;
}
+bool RegularFile::GetModificationTime(struct tm* buf) const {
+ if (buf == nullptr) {
+ return false;
+ }
+ struct stat stat_buf;
+ if (stat(source_.path.c_str(), &stat_buf) != 0) {
+ return false;
+ }
+
+ struct tm* ptm;
+ struct tm tm_result;
+ ptm = localtime_r(&stat_buf.st_mtime, &tm_result);
+
+ *buf = *ptm;
+ return true;
+}
+
FileCollectionIterator::FileCollectionIterator(FileCollection* collection)
: current_(collection->files_.begin()), end_(collection->files_.end()) {}
diff --git a/tools/aapt2/io/FileSystem.h b/tools/aapt2/io/FileSystem.h
index 0e798fc1b975..f975196b9cfa 100644
--- a/tools/aapt2/io/FileSystem.h
+++ b/tools/aapt2/io/FileSystem.h
@@ -32,6 +32,7 @@ class RegularFile : public IFile {
std::unique_ptr<IData> OpenAsData() override;
std::unique_ptr<io::InputStream> OpenInputStream() override;
const android::Source& GetSource() const override;
+ bool GetModificationTime(struct tm* buf) const override;
private:
DISALLOW_COPY_AND_ASSIGN(RegularFile);
diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp
index 4a5385d90d3b..cb5bbe96b8b7 100644
--- a/tools/aapt2/io/ZipArchive.cpp
+++ b/tools/aapt2/io/ZipArchive.cpp
@@ -75,6 +75,14 @@ bool ZipFile::WasCompressed() {
return zip_entry_.method != kCompressStored;
}
+bool ZipFile::GetModificationTime(struct tm* buf) const {
+ if (buf == nullptr) {
+ return false;
+ }
+ *buf = zip_entry_.GetModificationTime();
+ return true;
+}
+
ZipFileCollectionIterator::ZipFileCollectionIterator(
ZipFileCollection* collection)
: current_(collection->files_.begin()), end_(collection->files_.end()) {}
diff --git a/tools/aapt2/io/ZipArchive.h b/tools/aapt2/io/ZipArchive.h
index c263aa490d22..ac125d097983 100644
--- a/tools/aapt2/io/ZipArchive.h
+++ b/tools/aapt2/io/ZipArchive.h
@@ -38,6 +38,7 @@ class ZipFile : public IFile {
std::unique_ptr<io::InputStream> OpenInputStream() override;
const android::Source& GetSource() const override;
bool WasCompressed() override;
+ bool GetModificationTime(struct tm* buf) const override;
private:
::ZipArchiveHandle zip_handle_;
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 9dadfb26a3f8..c69b32513167 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -164,8 +164,8 @@ std::unique_ptr<Item> ReferenceLinkerTransformer::TransformItem(const Reference*
std::unique_ptr<Item> ReferenceLinkerTransformer::ParseValueWithAttribute(
std::unique_ptr<Item> value, const Attribute* attr) {
if (RawString* raw_string = ValueCast<RawString>(value.get())) {
- std::unique_ptr<Item> transformed =
- ResourceUtils::TryParseItemForAttribute(*raw_string->value, attr);
+ std::unique_ptr<Item> transformed = ResourceUtils::TryParseItemForAttribute(
+ context_->GetDiagnostics(), *raw_string->value, attr);
// If we could not parse as any specific type, try a basic STRING.
if (!transformed && (attr->type_mask & android::ResTable_map::TYPE_STRING)) {
diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp
index d2e9bd770a31..aec7ceb82c0f 100644
--- a/tools/aapt2/link/XmlReferenceLinker.cpp
+++ b/tools/aapt2/link/XmlReferenceLinker.cpp
@@ -90,7 +90,8 @@ class XmlVisitor : public xml::PackageAwareVisitor {
attribute = &attr.compiled_attribute.value().attribute;
}
- attr.compiled_value = ResourceUtils::TryParseItemForAttribute(attr.value, attribute);
+ attr.compiled_value = ResourceUtils::TryParseItemForAttribute(context_->GetDiagnostics(),
+ attr.value, attribute);
if (attr.compiled_value) {
// With a compiledValue, we must resolve the reference and assign it an ID.
attr.compiled_value->SetSource(source);
diff --git a/tools/aapt2/optimize/Obfuscator.cpp b/tools/aapt2/optimize/Obfuscator.cpp
index 8f12f735736e..903cdf852566 100644
--- a/tools/aapt2/optimize/Obfuscator.cpp
+++ b/tools/aapt2/optimize/Obfuscator.cpp
@@ -40,9 +40,9 @@ Obfuscator::Obfuscator(OptimizeOptions& optimizeOptions)
collapse_key_stringpool_(optimizeOptions.table_flattener_options.collapse_key_stringpool) {
}
-std::string ShortenFileName(android::StringPiece file_path, int output_length) {
+std::string Obfuscator::ShortenFileName(android::StringPiece file_path, int output_length) {
std::size_t hash_num = std::hash<android::StringPiece>{}(file_path);
- std::string result = "";
+ std::string result;
// Convert to (modified) base64 so that it is a proper file path.
for (int i = 0; i < output_length; i++) {
uint8_t sextet = hash_num & 0x3f;
@@ -52,10 +52,33 @@ std::string ShortenFileName(android::StringPiece file_path, int output_length) {
return result;
}
+static std::string RenameDisallowedFileNames(const std::string& file_name) {
+ // We are renaming shortened file names to make sure they not a reserved file name in Windows.
+ // See: https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file. We are renaming
+ // "COM" and "LPT" too because we are appending a number in case of hash collisions; "COM1",
+ // "COM2", etc. are reserved names.
+ static const char* const reserved_windows_names[] = {"CON", "PRN", "AUX", "NUL", "COM", "LPT"};
+ if (file_name.length() == 3) {
+ // Need to convert the file name to uppercase as Windows is case insensitive. E.g., "NuL",
+ // "nul", and "NUl" are also reserved.
+ std::string result_upper_cased(3, 0);
+ std::transform(file_name.begin(), file_name.end(), result_upper_cased.begin(),
+ [](unsigned char c) { return std::toupper(c); });
+ for (auto reserved_windows_name : reserved_windows_names) {
+ if (result_upper_cased == reserved_windows_name) {
+ // Simple solution to make it a non-reserved name is to add an underscore
+ return "_" + file_name;
+ }
+ }
+ }
+
+ return file_name;
+}
+
// Return the optimal hash length such that at most 10% of resources collide in
// their shortened path.
// Reference: http://matt.might.net/articles/counting-hash-collisions/
-int OptimalShortenedLength(int num_resources) {
+static int OptimalShortenedLength(int num_resources) {
if (num_resources > 4000) {
return 3;
} else {
@@ -63,8 +86,8 @@ int OptimalShortenedLength(int num_resources) {
}
}
-std::string GetShortenedPath(android::StringPiece shortened_filename,
- android::StringPiece extension, int collision_count) {
+static std::string GetShortenedPath(android::StringPiece shortened_filename,
+ android::StringPiece extension, int collision_count) {
std::string shortened_path = std::string("res/") += shortened_filename;
if (collision_count > 0) {
shortened_path += std::to_string(collision_count);
@@ -82,9 +105,9 @@ struct PathComparator {
}
};
-static bool HandleShortenFilePaths(ResourceTable* table,
- std::map<std::string, std::string>& shortened_path_map,
- const std::set<ResourceName>& path_shorten_exemptions) {
+bool Obfuscator::HandleShortenFilePaths(ResourceTable* table,
+ std::map<std::string, std::string>& shortened_path_map,
+ const std::set<ResourceName>& path_shorten_exemptions) {
// used to detect collisions
std::unordered_set<std::string> shortened_paths;
std::set<FileReference*, PathComparator> file_refs;
@@ -112,7 +135,8 @@ static bool HandleShortenFilePaths(ResourceTable* table,
// Android detects ColorStateLists via pathname, skip res/color*
if (util::StartsWith(res_subdir, "res/color")) continue;
- std::string shortened_filename = ShortenFileName(*file_ref->path, num_chars);
+ std::string shortened_filename =
+ RenameDisallowedFileNames(ShortenFileName(*file_ref->path, num_chars));
int collision_count = 0;
std::string shortened_path = GetShortenedPath(shortened_filename, extension, collision_count);
while (shortened_paths.find(shortened_path) != shortened_paths.end()) {
diff --git a/tools/aapt2/optimize/Obfuscator.h b/tools/aapt2/optimize/Obfuscator.h
index 5ccf54383aae..79d7e088d1cc 100644
--- a/tools/aapt2/optimize/Obfuscator.h
+++ b/tools/aapt2/optimize/Obfuscator.h
@@ -53,7 +53,14 @@ class Obfuscator : public IResourceTableConsumer {
const ResourceNamedType& type_name, const ResourceTableEntryView& entry,
const android::base::function_ref<void(Result, const ResourceName&)> onObfuscate);
+ protected:
+ virtual std::string ShortenFileName(android::StringPiece file_path, int output_length);
+
private:
+ bool HandleShortenFilePaths(ResourceTable* table,
+ std::map<std::string, std::string>& shortened_path_map,
+ const std::set<ResourceName>& path_shorten_exemptions);
+
TableFlattenerOptions& options_;
const bool shorten_resource_paths_;
const bool collapse_key_stringpool_;
diff --git a/tools/aapt2/optimize/Obfuscator_test.cpp b/tools/aapt2/optimize/Obfuscator_test.cpp
index 940cf1096f92..c3429e0fc1d6 100644
--- a/tools/aapt2/optimize/Obfuscator_test.cpp
+++ b/tools/aapt2/optimize/Obfuscator_test.cpp
@@ -19,6 +19,7 @@
#include <map>
#include <memory>
#include <string>
+#include <utility>
#include "ResourceTable.h"
#include "android-base/file.h"
@@ -26,6 +27,7 @@
using ::aapt::test::GetValue;
using ::testing::AnyOf;
+using ::testing::Contains;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::IsFalse;
@@ -33,6 +35,10 @@ using ::testing::IsTrue;
using ::testing::Not;
using ::testing::NotNull;
+namespace aapt {
+
+namespace {
+
android::StringPiece GetExtension(android::StringPiece path) {
auto iter = std::find(path.begin(), path.end(), '.');
return android::StringPiece(iter, path.end() - iter);
@@ -45,7 +51,22 @@ void FillTable(aapt::test::ResourceTableBuilder& builder, int start, int end) {
}
}
-namespace aapt {
+class FakeObfuscator : public Obfuscator {
+ public:
+ explicit FakeObfuscator(OptimizeOptions& optimize_options,
+ const std::unordered_map<std::string, std::string>& shortened_name_map)
+ : Obfuscator(optimize_options), shortened_name_map_(shortened_name_map) {
+ }
+
+ protected:
+ std::string ShortenFileName(android::StringPiece file_path, int output_length) override {
+ return shortened_name_map_[std::string(file_path)];
+ }
+
+ private:
+ std::unordered_map<std::string, std::string> shortened_name_map_;
+ DISALLOW_COPY_AND_ASSIGN(FakeObfuscator);
+};
TEST(ObfuscatorTest, FileRefPathsChangedInResourceTable) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
@@ -127,7 +148,7 @@ TEST(ObfuscatorTest, SkipPathShortenExemptions) {
EXPECT_THAT(path_map.find("res/drawables/xmlfile2.xml"), Not(Eq(path_map.end())));
FileReference* ref = GetValue<FileReference>(table.get(), "android:drawable/xmlfile");
- EXPECT_THAT(ref, NotNull());
+ ASSERT_THAT(ref, NotNull());
ASSERT_THAT(HasFailure(), IsFalse());
// The path of first drawable in exemption was not changed
EXPECT_THAT("res/drawables/xmlfile.xml", Eq(*ref->path));
@@ -161,13 +182,78 @@ TEST(ObfuscatorTest, KeepExtensions) {
ASSERT_THAT(path_map.find("res/drawable/xmlfile.xml"), Not(Eq(path_map.end())));
ASSERT_THAT(path_map.find("res/drawable/pngfile.png"), Not(Eq(path_map.end())));
- auto shortend_xml_path = path_map[original_xml_path];
- auto shortend_png_path = path_map[original_png_path];
-
EXPECT_THAT(GetExtension(path_map[original_xml_path]), Eq(android::StringPiece(".xml")));
EXPECT_THAT(GetExtension(path_map[original_png_path]), Eq(android::StringPiece(".png")));
}
+TEST(ObfuscatorTest, ShortenedToReservedWindowsNames) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+
+ std::string original_path_1 = "res/drawable/pngfile_1.png";
+ std::string original_path_2 = "res/drawable/pngfile_2.png";
+ std::string original_path_3 = "res/drawable/pngfile_3.png";
+ std::string original_path_4 = "res/drawable/pngfile_4.png";
+ std::string original_path_5 = "res/drawable/pngfile_5.png";
+ std::string original_path_6 = "res/drawable/pngfile_6.png";
+ std::string original_path_7 = "res/drawable/pngfile_7.png";
+ std::string original_path_8 = "res/drawable/pngfile_8.png";
+ std::string original_path_9 = "res/drawable/pngfile_9.png";
+
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddFileReference("android:drawable/pngfile_1", original_path_1)
+ .AddFileReference("android:drawable/pngfile_2", original_path_2)
+ .AddFileReference("android:drawable/pngfile_3", original_path_3)
+ .AddFileReference("android:drawable/pngfile_4", original_path_4)
+ .AddFileReference("android:drawable/pngfile_5", original_path_5)
+ .AddFileReference("android:drawable/pngfile_6", original_path_6)
+ .AddFileReference("android:drawable/pngfile_7", original_path_7)
+ .AddFileReference("android:drawable/pngfile_8", original_path_8)
+ .AddFileReference("android:drawable/pngfile_9", original_path_9)
+ .Build();
+
+ OptimizeOptions options{.shorten_resource_paths = true};
+ std::map<std::string, std::string>& path_map = options.table_flattener_options.shortened_path_map;
+ auto obfuscator = FakeObfuscator(
+ options,
+ {
+ {original_path_1, "CON"},
+ {original_path_2, "Prn"},
+ {original_path_3, "AuX"},
+ {original_path_4, "nul"},
+ {original_path_5, "cOM"},
+ {original_path_6, "lPt"},
+ {original_path_7, "lPt"},
+ {original_path_8, "lPt"}, // 6, 7, and 8 will be appended with a number to disambiguate
+ {original_path_9, "F0o"}, // This one is not reserved
+ });
+ ASSERT_TRUE(obfuscator.Consume(context.get(), table.get()));
+
+ // Expect that the path map is populated
+ ASSERT_THAT(path_map.find(original_path_1), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_2), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_3), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_4), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_5), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_6), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_7), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_8), Not(Eq(path_map.end())));
+ ASSERT_THAT(path_map.find(original_path_9), Not(Eq(path_map.end())));
+
+ EXPECT_THAT(path_map[original_path_1], Eq("res/_CON.png"));
+ EXPECT_THAT(path_map[original_path_2], Eq("res/_Prn.png"));
+ EXPECT_THAT(path_map[original_path_3], Eq("res/_AuX.png"));
+ EXPECT_THAT(path_map[original_path_4], Eq("res/_nul.png"));
+ EXPECT_THAT(path_map[original_path_5], Eq("res/_cOM.png"));
+ EXPECT_THAT(path_map[original_path_9], Eq("res/F0o.png"));
+
+ std::set<std::string> lpt_shortened_names{path_map[original_path_6], path_map[original_path_7],
+ path_map[original_path_8]};
+ EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt.png"));
+ EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt1.png"));
+ EXPECT_THAT(lpt_shortened_names, Contains("res/_lPt2.png"));
+}
+
TEST(ObfuscatorTest, DeterministicallyHandleCollisions) {
std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
@@ -247,7 +333,9 @@ TEST(ObfuscatorTest, DumpIdResourceMap) {
ASSERT_TRUE(Obfuscator(options).Consume(context.get(), table.get()));
// Expect that the id resource name map is populated
+ ASSERT_THAT(id_resource_map.find(0x7f020000), Not(Eq(id_resource_map.end())));
EXPECT_THAT(id_resource_map.at(0x7f020000), Eq("mycolor"));
+ ASSERT_THAT(id_resource_map.find(0x7f030000), Not(Eq(id_resource_map.end())));
EXPECT_THAT(id_resource_map.at(0x7f030000), Eq("mystring"));
EXPECT_THAT(id_resource_map.find(0x7f030001), Eq(id_resource_map.end()));
EXPECT_THAT(id_resource_map.find(0x7f030002), Eq(id_resource_map.end()));
@@ -300,17 +388,18 @@ TEST(ObfuscatorTest, WriteObfuscationMapInProtocolBufferFormat) {
ASSERT_TRUE(obfuscator.Consume(test::ContextBuilder().Build().get(),
getProtocolBufferTableUnderTest().get()));
- obfuscator.WriteObfuscationMap("obfuscated_map.pb");
+ const auto map_path = testing::TempDir() + "/obfuscated_map.pb";
+ ASSERT_TRUE(obfuscator.WriteObfuscationMap(map_path));
std::string pbOut;
- android::base::ReadFileToString("obfuscated_map.pb", &pbOut, false /* follow_symlinks */);
+ ASSERT_TRUE(android::base::ReadFileToString(map_path, &pbOut, false /* follow_symlinks */));
EXPECT_THAT(pbOut, HasSubstr("drawable/xmlfile.xml"));
EXPECT_THAT(pbOut, HasSubstr("drawable/pngfile.png"));
EXPECT_THAT(pbOut, HasSubstr("mycolor"));
EXPECT_THAT(pbOut, HasSubstr("mystring"));
pb::ResourceMappings resourceMappings;
- EXPECT_THAT(resourceMappings.ParseFromString(pbOut), IsTrue());
- EXPECT_THAT(resourceMappings.collapsed_names().resource_names_size(), Eq(2));
+ ASSERT_THAT(resourceMappings.ParseFromString(pbOut), IsTrue());
+ ASSERT_THAT(resourceMappings.collapsed_names().resource_names_size(), Eq(2));
auto& resource_names = resourceMappings.collapsed_names().resource_names();
EXPECT_THAT(resource_names.at(0).name(), AnyOf(Eq("mycolor"), Eq("mystring")));
EXPECT_THAT(resource_names.at(1).name(), AnyOf(Eq("mycolor"), Eq("mystring")));
@@ -328,11 +417,14 @@ TEST(ObfuscatorTest, WriteObfuscatingMapWithNonEnabledOption) {
ASSERT_TRUE(obfuscator.Consume(test::ContextBuilder().Build().get(),
getProtocolBufferTableUnderTest().get()));
- obfuscator.WriteObfuscationMap("obfuscated_map.pb");
+ const auto map_path = testing::TempDir() + "/obfuscated_map.pb";
+ ASSERT_TRUE(obfuscator.WriteObfuscationMap(map_path));
std::string pbOut;
- android::base::ReadFileToString("obfuscated_map.pb", &pbOut, false /* follow_symlinks */);
+ ASSERT_TRUE(android::base::ReadFileToString(map_path, &pbOut, false /* follow_symlinks */));
ASSERT_THAT(pbOut, Eq(""));
}
+} // namespace
+
} // namespace aapt
diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h
index 83a0f3f3f652..e48668cf96a3 100644
--- a/tools/aapt2/test/Common.h
+++ b/tools/aapt2/test/Common.h
@@ -98,6 +98,10 @@ class TestFile : public io::IFile {
return source_;
}
+ bool GetModificationTime(struct tm* buf) const override {
+ return false;
+ };
+
private:
DISALLOW_COPY_AND_ASSIGN(TestFile);
diff --git a/tools/aapt2/trace/TraceBuffer.cpp b/tools/aapt2/trace/TraceBuffer.cpp
index da5373936306..0988c313b65b 100644
--- a/tools/aapt2/trace/TraceBuffer.cpp
+++ b/tools/aapt2/trace/TraceBuffer.cpp
@@ -36,116 +36,142 @@ constexpr char kBegin = 'B';
constexpr char kEnd = 'E';
struct TracePoint {
+ char type;
pid_t tid;
int64_t time;
std::string tag;
- char type;
};
std::vector<TracePoint> traces;
+bool enabled = true;
+constinit std::chrono::steady_clock::time_point startTime = {};
int64_t GetTime() noexcept {
auto now = std::chrono::steady_clock::now();
- return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count();
+ if (startTime == decltype(tracebuffer::startTime){}) {
+ startTime = now;
+ }
+ return std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count();
}
-} // namespace anonymous
-
-void AddWithTime(const std::string& tag, char type, int64_t time) noexcept {
- TracePoint t = {getpid(), time, tag, type};
- traces.emplace_back(t);
+void AddWithTime(std::string tag, char type, int64_t time) noexcept {
+ TracePoint t = {type, getpid(), time, std::move(tag)};
+ traces.emplace_back(std::move(t));
}
-void Add(const std::string& tag, char type) noexcept {
- AddWithTime(tag, type, GetTime());
+void Add(std::string tag, char type) noexcept {
+ AddWithTime(std::move(tag), type, GetTime());
}
-
-
-
void Flush(const std::string& basePath) {
- TRACE_CALL();
if (basePath.empty()) {
return;
}
+ BeginTrace(__func__); // We can't do much here, only record that it happened.
- std::stringstream s;
+ std::ostringstream s;
s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json";
FILE* f = android::base::utf8::fopen(s.str().c_str(), "a");
if (f == nullptr) {
return;
}
- for(const TracePoint& trace : traces) {
- fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", "
- "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
+ // Wrap the trace in a JSON array [] to make Chrome/Perfetto UI handle it.
+ char delimiter = '[';
+ for (const TracePoint& trace : traces) {
+ fprintf(f,
+ "%c{\"ts\" : \"%" PRIu64
+ "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", \"name\" : \"%s\" }\n",
+ delimiter, trace.time, trace.type, 0, trace.tid, trace.tag.c_str());
+ delimiter = ',';
+ }
+ if (!traces.empty()) {
+ fprintf(f, "]");
}
fclose(f);
traces.clear();
}
+} // namespace
+
} // namespace tracebuffer
-void BeginTrace(const std::string& tag) {
- tracebuffer::Add(tag, tracebuffer::kBegin);
+void BeginTrace(std::string tag) {
+ if (!tracebuffer::enabled) return;
+ tracebuffer::Add(std::move(tag), tracebuffer::kBegin);
+}
+
+void EndTrace(std::string tag) {
+ if (!tracebuffer::enabled) return;
+ tracebuffer::Add(std::move(tag), tracebuffer::kEnd);
+}
+
+bool Trace::enable(bool value) {
+ return tracebuffer::enabled = value;
}
-void EndTrace() {
- tracebuffer::Add("", tracebuffer::kEnd);
+Trace::Trace(const char* tag) {
+ if (!tracebuffer::enabled) return;
+ tag_.assign(tag);
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
-Trace::Trace(const std::string& tag) {
- tracebuffer::Add(tag, tracebuffer::kBegin);
+Trace::Trace(std::string tag) : tag_(std::move(tag)) {
+ if (!tracebuffer::enabled) return;
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
-Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) {
- std::stringstream s;
+template <class SpanOfStrings>
+std::string makeTag(std::string_view tag, const SpanOfStrings& args) {
+ std::ostringstream s;
s << tag;
- s << " ";
- for (auto& arg : args) {
- s << arg;
- s << " ";
+ if (!args.empty()) {
+ for (const auto& arg : args) {
+ s << ' ';
+ s << arg;
+ }
}
- tracebuffer::Add(s.str(), tracebuffer::kBegin);
+ return std::move(s).str();
+}
+
+Trace::Trace(std::string_view tag, const std::vector<android::StringPiece>& args) {
+ if (!tracebuffer::enabled) return;
+ tag_ = makeTag(tag, args);
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
Trace::~Trace() {
- tracebuffer::Add("", tracebuffer::kEnd);
+ if (!tracebuffer::enabled) return;
+ tracebuffer::Add(std::move(tag_), tracebuffer::kEnd);
}
-FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag)
- : basepath_(basepath) {
- tracebuffer::Add(tag, tracebuffer::kBegin);
+FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag) {
+ if (!Trace::enable(!basepath.empty())) return;
+ basepath_.assign(basepath);
+ tag_.assign(tag);
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
-FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
- const std::vector<android::StringPiece>& args) : basepath_(basepath) {
- std::stringstream s;
- s << tag;
- s << " ";
- for (auto& arg : args) {
- s << arg;
- s << " ";
- }
- tracebuffer::Add(s.str(), tracebuffer::kBegin);
+FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag,
+ const std::vector<android::StringPiece>& args) {
+ if (!Trace::enable(!basepath.empty())) return;
+ basepath_.assign(basepath);
+ tag_ = makeTag(tag, args);
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
-FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag,
- const std::vector<std::string>& args) : basepath_(basepath){
- std::stringstream s;
- s << tag;
- s << " ";
- for (auto& arg : args) {
- s << arg;
- s << " ";
- }
- tracebuffer::Add(s.str(), tracebuffer::kBegin);
+FlushTrace::FlushTrace(std::string_view basepath, std::string_view tag,
+ const std::vector<std::string>& args) {
+ if (!Trace::enable(!basepath.empty())) return;
+ basepath_.assign(basepath);
+ tag_ = makeTag(tag, args);
+ tracebuffer::Add(tag_, tracebuffer::kBegin);
}
FlushTrace::~FlushTrace() {
- tracebuffer::Add("", tracebuffer::kEnd);
+ if (!tracebuffer::enabled) return;
+ tracebuffer::Add(std::move(tag_), tracebuffer::kEnd);
tracebuffer::Flush(basepath_);
}
-} // namespace aapt
-
+} // namespace aapt
diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h
index ba751dd72f41..f0333d1fe071 100644
--- a/tools/aapt2/trace/TraceBuffer.h
+++ b/tools/aapt2/trace/TraceBuffer.h
@@ -17,41 +17,50 @@
#ifndef AAPT_TRACEBUFFER_H
#define AAPT_TRACEBUFFER_H
+#include <androidfw/StringPiece.h>
+
#include <string>
+#include <string_view>
#include <vector>
-#include <androidfw/StringPiece.h>
-
namespace aapt {
// Record timestamps for beginning and end of a task and generate systrace json fragments.
// This is an in-process ftrace which has the advantage of being platform independent.
// These methods are NOT thread-safe since aapt2 is not multi-threaded.
-// Convenience RIAA object to automatically finish an event when object goes out of scope.
+// Convenience RAII object to automatically finish an event when object goes out of scope.
class Trace {
public:
- Trace(const std::string& tag);
- Trace(const std::string& tag, const std::vector<android::StringPiece>& args);
- ~Trace();
+ Trace(const char* tag);
+ Trace(std::string tag);
+ Trace(std::string_view tag, const std::vector<android::StringPiece>& args);
+ ~Trace();
+
+ static bool enable(bool value = true);
+
+private:
+ std::string tag_;
};
// Manual markers.
-void BeginTrace(const std::string& tag);
-void EndTrace();
+void BeginTrace(std::string tag);
+void EndTrace(std::string tag);
// A main trace is required to flush events to disk. Events are formatted in systrace
// json format.
class FlushTrace {
public:
- explicit FlushTrace(const std::string& basepath, const std::string& tag);
- explicit FlushTrace(const std::string& basepath, const std::string& tag,
- const std::vector<android::StringPiece>& args);
- explicit FlushTrace(const std::string& basepath, const std::string& tag,
- const std::vector<std::string>& args);
- ~FlushTrace();
+ explicit FlushTrace(std::string_view basepath, std::string_view tag);
+ explicit FlushTrace(std::string_view basepath, std::string_view tag,
+ const std::vector<android::StringPiece>& args);
+ explicit FlushTrace(std::string_view basepath, std::string_view tag,
+ const std::vector<std::string>& args);
+ ~FlushTrace();
+
private:
std::string basepath_;
+ std::string tag_;
};
#define TRACE_CALL() Trace __t(__func__)
diff --git a/tools/aapt2/util/Util.cpp b/tools/aapt2/util/Util.cpp
index be877660ef72..3d83caf29bba 100644
--- a/tools/aapt2/util/Util.cpp
+++ b/tools/aapt2/util/Util.cpp
@@ -21,6 +21,7 @@
#include <string>
#include <vector>
+#include "android-base/parseint.h"
#include "android-base/stringprintf.h"
#include "android-base/strings.h"
#include "androidfw/BigBuffer.h"
@@ -229,14 +230,29 @@ std::string GetToolFingerprint() {
static const char* const sMinorVersion = "19";
// The build id of aapt2 binary.
- static std::string sBuildId = android::build::GetBuildNumber();
-
- if (android::base::StartsWith(sBuildId, "eng.")) {
- time_t now = time(0);
- tm* ltm = localtime(&now);
+ static const std::string sBuildId = [] {
+ std::string buildNumber = android::build::GetBuildNumber();
+
+ if (android::base::StartsWith(buildNumber, "eng.")) {
+ // android::build::GetBuildNumber() returns something like "eng.user.20230725.214219" where
+ // the latter two parts are "yyyyMMdd.HHmmss" at build time. Use "yyyyMM" in the fingerprint.
+ std::vector<std::string> parts = util::Split(buildNumber, '.');
+ int buildYear;
+ int buildMonth;
+ if (parts.size() < 3 || parts[2].length() < 6 ||
+ !android::base::ParseInt(parts[2].substr(0, 4), &buildYear) ||
+ !android::base::ParseInt(parts[2].substr(4, 2), &buildMonth)) {
+ // Fallback to localtime() if GetBuildNumber() returns an unexpected output.
+ time_t now = time(0);
+ tm* ltm = localtime(&now);
+ buildYear = 1900 + ltm->tm_year;
+ buildMonth = 1 + ltm->tm_mon;
+ }
- sBuildId = android::base::StringPrintf("eng.%d%d", 1900 + ltm->tm_year, 1 + ltm->tm_mon);
- }
+ buildNumber = android::base::StringPrintf("eng.%04d%02d", buildYear, buildMonth);
+ }
+ return buildNumber;
+ }();
return android::base::StringPrintf("%s.%s-%s", sMajorVersion, sMinorVersion, sBuildId.c_str());
}
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index 685733386cae..d3a8b033dfff 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -327,7 +327,8 @@ private fun ClassPrinter.generateBuilderSetters(visibility: String) {
+"return$maybeCast this;"
}
- val javadocSeeSetter = "/** @see #$setterName */"
+ val javadocSeeSetter =
+ if (isHidden()) "/** @see #$setterName @hide */" else "/** @see #$setterName */"
val adderName = "add$SingularName"
val singularNameCustomizationHint = if (SingularNameOrNull == null) {
@@ -750,6 +751,15 @@ fun ClassPrinter.generateGetters() {
}
}
+fun FieldInfo.isHidden(): Boolean {
+ if (javadocFull != null) {
+ (javadocFull ?: "/**\n */").lines().forEach {
+ if (it.contains("@hide")) return true
+ }
+ }
+ return false
+}
+
fun FieldInfo.generateFieldJavadoc(forceHide: Boolean = false) = classPrinter {
if (javadocFull != null || forceHide) {
var hidden = false
diff --git a/tools/hoststubgen/.gitignore b/tools/hoststubgen/.gitignore
new file mode 100644
index 000000000000..6453bdef8cee
--- /dev/null
+++ b/tools/hoststubgen/.gitignore
@@ -0,0 +1,3 @@
+out/
+*-out/
+*.log
diff --git a/tools/hoststubgen/OWNERS b/tools/hoststubgen/OWNERS
new file mode 100644
index 000000000000..a8c5321307d1
--- /dev/null
+++ b/tools/hoststubgen/OWNERS
@@ -0,0 +1,3 @@
+omakoto@google.com
+jsharkey@google.com
+jaggies@google.com
diff --git a/tools/hoststubgen/README.md b/tools/hoststubgen/README.md
new file mode 100644
index 000000000000..b0a126292063
--- /dev/null
+++ b/tools/hoststubgen/README.md
@@ -0,0 +1,76 @@
+# HostStubGen
+
+## Overview
+
+This directory contains tools / sample code / investigation for host side test support.
+
+
+## Directories and files
+
+- `hoststubgen/`
+ Contains source code of the "hoststubgen" tool and relevant code
+
+ - `framework-policy-override.txt`
+ This file contains "policy overrides", which allows to control what goes to stub/impl without
+ having to touch the target java files. This allows quicker iteration, because you can skip
+ having to rebuild framework.jar.
+
+ - `src/`
+
+ HostStubGen tool source code.
+
+ - `annotations-src/` See `Android.bp`.
+ - `helper-framework-buildtime-src/` See `Android.bp`.
+ - `helper-framework-runtime-src/` See `Android.bp`.
+ - `helper-runtime-src/` See `Android.bp`.
+
+ - `test-tiny-framework/` See `README.md` in it.
+
+ - `test-framework` See `README.md` in it.
+
+- `scripts`
+ - `run-host-test.sh`
+
+ Run a host side test. Use it instead of `atest` for now. (`atest` works "mostly" but it has
+ problems.)
+
+ - `dump-jar.sh`
+
+ A script to dump the content of `*.class` and `*.jar` files.
+
+ - `run-all-tests.sh`
+
+ Run all tests. Many tests may fail, but at least this should run til the end.
+ (It should print `run-all-tests.sh finished` at the end)
+
+## Build and run
+
+### Building `HostStubGen` binary
+
+```
+m hoststubgen
+```
+
+### Run the tests
+
+- Run all relevant tests and test scripts. Some of thests are still expected to fail,
+ but this should print "finished, with no unexpected failures" at the end.
+
+ However, because some of the script it executes depend on internal file paths to Soong's
+ intermediate directory, some of it might fail when something changes in the build system.
+
+ We need proper build system integration to fix them.
+```
+$ ./scripts/run-all-tests.sh
+```
+
+- See also `README.md` in `test-*` directories.
+
+## TODOs, etc
+
+ - Make sure the parent's visibility is not smaller than the member's.
+
+- @HostSideTestNativeSubstitutionClass should automatically add class-keep to the substitute class.
+ (or at least check it.)
+
+ - The `HostStubGenTest-framework-test-host-test-lib` jar somehow contain all ASM classes? Figure out where the dependency is coming from.
diff --git a/tools/hoststubgen/TEST_MAPPING b/tools/hoststubgen/TEST_MAPPING
new file mode 100644
index 000000000000..192b6f2b5e25
--- /dev/null
+++ b/tools/hoststubgen/TEST_MAPPING
@@ -0,0 +1,11 @@
+{
+ "presubmit": [
+ { "name": "tiny-framework-dump-test" },
+ { "name": "hoststubgentest" },
+ { "name": "hoststubgen-invoke-test" }
+
+ // As a smoke test.
+ // TODO: Enable it once the infra knows how to run it.
+ // { "name": "CtsUtilTestCasesRavenwood" }
+ ]
+}
diff --git a/tools/hoststubgen/common.sh b/tools/hoststubgen/common.sh
new file mode 100644
index 000000000000..b49ee39a3142
--- /dev/null
+++ b/tools/hoststubgen/common.sh
@@ -0,0 +1,116 @@
+# Copyright (C) 2023 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.
+
+set -e # Exit at failure
+shopt -s globstar # Enable double-star wildcards (**)
+
+cd "${0%/*}" # Move to the script dir
+
+fail() {
+ echo "Error: $*" 1>&2
+ exit 1
+}
+
+# Print the arguments and then execute.
+run() {
+ echo "Running: $*" 1>&2
+ "$@"
+}
+
+# Concatenate the second and subsequent args with the first arg as a separator.
+# e.g. `join : a b c` -> prints `a:b:c`
+join() {
+ local IFS="$1"
+ shift
+ echo "$*"
+}
+
+abspath() {
+ for name in "${@}"; do
+ readlink -f $name
+ done
+}
+
+m() {
+ if (( $SKIP_BUILD )) ; then
+ echo "Skipping build: $*" 1>&2
+ return 0
+ fi
+ run ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode "$@"
+}
+
+# Extract given jar files
+extract() {
+ for f in "${@}"; do
+ local out=$f.ext
+ run rm -fr $out
+ run mkdir -p $out
+
+ # It's too noisy, so only show the first few lines.
+ {
+ # Hmm unzipping kotlin jar files may produce a warning? Let's just add `|| true`...
+ run unzip $f -d $out || true
+ } |& sed -e '5,$d'
+ echo ' (omitting remaining output)'
+
+ done
+}
+
+# Find all *.java files in $1, and print them as Java class names.
+# For example, if there's a file `src/com/android/test/Test.java`, and you run
+# `list_all_classes_under_dir src`, then it'll print `com.android.test.Test`.
+list_all_classes_under_dir() {
+ local dir="$1"
+ ( # Use a subshell, so we won't change the current directory on the caller side.
+ cd "$dir"
+
+ # List the java files, but replace the slashes with dots, and remove the `.java` suffix.
+ ls **/*.java | sed -e 's!/!.!g' -e 's!.java$!!'
+ )
+}
+
+checkenv() {
+ # Make sure $ANDROID_BUILD_TOP is set.
+ : ${ANDROID_BUILD_TOP:?}
+
+ # Make sure ANDROID_BUILD_TOP doesn't contain whitespace.
+ set ${ANDROID_BUILD_TOP}
+ if [[ $# != 1 ]] ; then
+ fail "\$ANDROID_BUILD_TOP cannot contain whitespace."
+ fi
+}
+
+checkenv
+
+JAVAC=${JAVAC:-javac}
+JAVA=${JAVA:-java}
+JAR=${JAR:-jar}
+
+JAVAC_OPTS=${JAVAC_OPTS:--Xmaxerrs 99999 -Xlint:none}
+
+SOONG_INT=$ANDROID_BUILD_TOP/out/soong/.intermediates
+
+JUNIT_TEST_MAIN_CLASS=com.android.hoststubgen.hosthelper.HostTestSuite
+
+run_junit_test_jar() {
+ local jar="$1"
+ echo "Starting test: $jar ..."
+ run cd "${jar%/*}"
+
+ run $JAVA $JAVA_OPTS \
+ -cp $jar \
+ org.junit.runner.JUnitCore \
+ $main_class || return 1
+ return 0
+}
diff --git a/tools/hoststubgen/hoststubgen/.gitignore b/tools/hoststubgen/hoststubgen/.gitignore
new file mode 100644
index 000000000000..0f384074ed7f
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/.gitignore
@@ -0,0 +1 @@
+framework-all-stub-out \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/Android.bp b/tools/hoststubgen/hoststubgen/Android.bp
new file mode 100644
index 000000000000..5949bca2f9a3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/Android.bp
@@ -0,0 +1,375 @@
+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"],
+}
+
+// Visibility only for ravenwood prototype uses.
+genrule_defaults {
+ name: "hoststubgen-for-prototype-only-genrule",
+ visibility: [
+ ":__subpackages__",
+ "//frameworks/base",
+ "//frameworks/base/ravenwood:__subpackages__",
+ ],
+}
+
+// Visibility only for ravenwood prototype uses.
+java_defaults {
+ name: "hoststubgen-for-prototype-only-java",
+ visibility: [
+ ":__subpackages__",
+ "//frameworks/base",
+ "//frameworks/base/ravenwood:__subpackages__",
+ ],
+}
+
+// Visibility only for ravenwood prototype uses.
+filegroup_defaults {
+ name: "hoststubgen-for-prototype-only-filegroup",
+ visibility: [
+ ":__subpackages__",
+ "//frameworks/base",
+ "//frameworks/base/ravenwood:__subpackages__",
+ ],
+}
+
+// This library contains the standard hoststubgen annotations.
+// This is only for the prototype. The productionized version is "ravenwood-annotations".
+java_library {
+ name: "hoststubgen-annotations",
+ defaults: ["hoststubgen-for-prototype-only-java"],
+ srcs: [
+ "annotations-src/**/*.java",
+ ],
+ host_supported: true,
+
+ sdk_version: "core_current",
+}
+
+// This library contains helper classes used in the host side test environment at runtime.
+// This library is _not_ specific to Android APIs.
+java_library_host {
+ name: "hoststubgen-helper-runtime",
+ srcs: [
+ "helper-runtime-src/**/*.java",
+ ],
+ libs: [
+ "junit",
+ ],
+ static_libs: [
+ "guava",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
+ visibility: ["//visibility:public"],
+}
+
+java_library {
+ name: "hoststubgen-helper-runtime.ravenwood",
+ srcs: [
+ "helper-runtime-src/**/*.java",
+ ],
+ libs: [
+ "junit",
+ ],
+ static_libs: [
+ "guava",
+ ],
+ jarjar_rules: "jarjar-rules.txt",
+ visibility: ["//visibility:public"],
+}
+
+// Host-side stub generator tool.
+java_binary_host {
+ name: "hoststubgen",
+ main_class: "com.android.hoststubgen.Main",
+ srcs: ["src/**/*.kt"],
+ static_libs: [
+ "hoststubgen-helper-runtime",
+ "junit",
+ "ow2-asm",
+ "ow2-asm-analysis",
+ "ow2-asm-commons",
+ "ow2-asm-tree",
+ "ow2-asm-util",
+ ],
+ visibility: ["//visibility:public"],
+}
+
+java_test_host {
+ name: "hoststubgentest",
+ // main_class: "com.android.hoststubgen.Main",
+ srcs: ["test/**/*.kt"],
+ static_libs: [
+ "hoststubgen",
+ "truth",
+ ],
+ test_suites: ["general-tests"],
+ visibility: ["//visibility:private"],
+}
+
+// File that contains the standard command line argumetns to hoststubgen.
+// This is only for the prototype. The productionized version is "ravenwood-standard-options".
+filegroup {
+ name: "hoststubgen-standard-options",
+ defaults: ["hoststubgen-for-prototype-only-filegroup"],
+ srcs: [
+ "hoststubgen-standard-options.txt",
+ ],
+}
+
+hoststubgen_common_options = "$(location hoststubgen) " +
+ // "--in-jar $(location :framework-all) " +
+ // "--policy-override-file $(location framework-policy-override.txt) " +
+ "@$(location :hoststubgen-standard-options) " +
+
+ "--out-stub-jar $(location host_stub.jar) " +
+ "--out-impl-jar $(location host_impl.jar) " +
+
+ // "--keep-all-classes " + // Used it for an experiment. See KeepAllClassesFilter.
+ "--gen-keep-all-file $(location hoststubgen_keep_all.txt) " +
+ "--gen-input-dump-file $(location hoststubgen_dump.txt) " +
+ ""
+
+// Common defaults for stub generation.
+// This one is not specific to Android APIs.
+genrule_defaults {
+ name: "hoststubgen-command-defaults",
+ tools: ["hoststubgen"],
+ srcs: [
+ ":hoststubgen-standard-options",
+ ],
+ // Create two jar files.
+ out: [
+ "host_stub.jar",
+ "host_impl.jar",
+
+ // Following files are created just as FYI.
+ "hoststubgen_keep_all.txt",
+ "hoststubgen_dump.txt",
+ ],
+}
+
+// Generate the stub/impl from framework-all, with hidden APIs.
+java_genrule_host {
+ name: "framework-all-hidden-api-host",
+ defaults: ["hoststubgen-command-defaults"],
+ cmd: hoststubgen_common_options +
+ "--in-jar $(location :framework-all) " +
+ "--policy-override-file $(location framework-policy-override.txt) ",
+ srcs: [
+ ":framework-all",
+ "framework-policy-override.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Extract the stub jar from "framework-all-host" for subsequent build rules.
+// This is only for the prototype. Do not use it in "productionized" build rules.
+java_genrule_host {
+ name: "framework-all-hidden-api-host-stub",
+ defaults: ["hoststubgen-for-prototype-only-genrule"],
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":framework-all-hidden-api-host{host_stub.jar}",
+ ],
+ out: [
+ "host_stub.jar",
+ ],
+}
+
+// Extract the impl jar from "framework-all-host" for subsequent build rules.
+// This is only for the prototype. Do not use it in "productionized" build rules.
+java_genrule_host {
+ name: "framework-all-hidden-api-host-impl",
+ defaults: ["hoststubgen-for-prototype-only-genrule"],
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":framework-all-hidden-api-host{host_impl.jar}",
+ ],
+ out: [
+ "host_impl.jar",
+ ],
+}
+
+// Generate the stub/impl from framework-all, with only public/system/test APIs, without
+// hidden APIs.
+// This is only for the prototype. Do not use it in "productionized" build rules.
+java_genrule_host {
+ name: "framework-all-test-api-host",
+ defaults: ["hoststubgen-command-defaults"],
+ cmd: hoststubgen_common_options +
+ "--intersect-stub-jar $(location :android_test_stubs_current{.jar}) " +
+ "--in-jar $(location :framework-all) " +
+ "--policy-override-file $(location framework-policy-override.txt) ",
+ srcs: [
+ ":framework-all",
+ ":android_test_stubs_current{.jar}",
+ "framework-policy-override.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Extract the stub jar from "framework-all-test-api-host" for subsequent build rules.
+// This is only for the prototype. Do not use it in "productionized" build rules.
+java_genrule_host {
+ name: "framework-all-test-api-host-stub",
+ defaults: ["hoststubgen-for-prototype-only-genrule"],
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":framework-all-test-api-host{host_stub.jar}",
+ ],
+ out: [
+ "host_stub.jar",
+ ],
+}
+
+// Extract the impl jar from "framework-all-test-api-host" for subsequent build rules.
+// This is only for the prototype. Do not use it in "productionized" build rules.
+java_genrule_host {
+ name: "framework-all-test-api-host-impl",
+ defaults: ["hoststubgen-for-prototype-only-genrule"],
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":framework-all-test-api-host{host_impl.jar}",
+ ],
+ out: [
+ "host_impl.jar",
+ ],
+}
+
+// This library contains helper classes to build hostside tests/targets.
+// This essentially contains dependencies from tests that we can't actually use the real ones.
+// For example, the actual AndroidTestCase and AndroidJUnit4 don't run on the host side (yet),
+// so we pup "fake" implementations here.
+// Ideally this library should be empty.
+java_library_host {
+ name: "hoststubgen-helper-framework-buildtime",
+ defaults: ["hoststubgen-for-prototype-only-java"],
+ srcs: [
+ "helper-framework-buildtime-src/**/*.java",
+ ],
+ libs: [
+ // We need it to pull in some of the framework classes used in this library,
+ // such as Context.java.
+ "framework-all-hidden-api-host-impl",
+ "junit",
+ ],
+}
+
+// This module contains "fake" libcore/dalvik classes, framework native substitution, etc,
+// that are needed at runtime.
+java_library_host {
+ name: "hoststubgen-helper-framework-runtime",
+ defaults: ["hoststubgen-for-prototype-only-java"],
+ srcs: [
+ "helper-framework-runtime-src/**/*.java",
+ ],
+ libs: [
+ "hoststubgen-helper-runtime",
+ "framework-all-hidden-api-host-impl",
+ ],
+}
+
+java_library {
+ name: "hoststubgen-helper-framework-runtime.ravenwood",
+ defaults: ["hoststubgen-for-prototype-only-java"],
+ srcs: [
+ "helper-framework-runtime-src/framework/**/*.java",
+ ],
+ libs: [
+ "hoststubgen-helper-runtime.ravenwood",
+ "framework-minus-apex.ravenwood",
+ ],
+ static_libs: [
+ "core-xml-for-device",
+ ],
+}
+
+// Defaults for host side test modules.
+// We need two rules for each test.
+// 1. A "-test-lib" jar, which compiles the test against the stub jar.
+// This one is only used by the second rule, so it should be "private.
+// 2. A "-test" jar, which includes 1 + the runtime (impl) jars.
+
+// This and next ones are for tests using framework-app, with hidden APIs.
+java_defaults {
+ name: "hosttest-with-framework-all-hidden-api-test-lib-defaults",
+ installable: false,
+ libs: [
+ "framework-all-hidden-api-host-stub",
+ ],
+ static_libs: [
+ "hoststubgen-helper-framework-buildtime",
+ "framework-annotations-lib",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Default rules to include `libandroid_runtime`. For now, it's empty, but we'll use it
+// once we start using JNI.
+java_defaults {
+ name: "hosttest-with-libandroid_runtime",
+ jni_libs: [
+ // "libandroid_runtime",
+
+ // TODO: Figure out how to build them automatically.
+ // Following ones are depended by libandroid_runtime.
+ // Without listing them here, not only we won't get them under
+ // $ANDROID_HOST_OUT/testcases/*/lib64, but also not under
+ // $ANDROID_HOST_OUT/lib64, so we'd fail to load them at runtime.
+ // ($ANDROID_HOST_OUT/lib/ gets all of them though.)
+ // "libcutils",
+ // "libharfbuzz_ng",
+ // "libminikin",
+ // "libz",
+ // "libbinder",
+ // "libhidlbase",
+ // "libvintf",
+ // "libicu",
+ // "libutils",
+ // "libtinyxml2",
+ ],
+}
+
+java_defaults {
+ name: "hosttest-with-framework-all-hidden-api-test-defaults",
+ defaults: ["hosttest-with-libandroid_runtime"],
+ installable: false,
+ test_config: "AndroidTest-host.xml",
+ static_libs: [
+ "hoststubgen-helper-runtime",
+ "hoststubgen-helper-framework-runtime",
+ "framework-all-hidden-api-host-impl",
+ ],
+}
+
+// This and next ones are for tests using framework-app, with public/system/test APIs,
+// without hidden APIs.
+java_defaults {
+ name: "hosttest-with-framework-all-test-api-test-lib-defaults",
+ installable: false,
+ libs: [
+ "framework-all-test-api-host-stub",
+ ],
+ static_libs: [
+ "hoststubgen-helper-framework-buildtime",
+ "framework-annotations-lib",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_defaults {
+ name: "hosttest-with-framework-all-test-api-test-defaults",
+ defaults: ["hosttest-with-libandroid_runtime"],
+ installable: false,
+ test_config: "AndroidTest-host.xml",
+ static_libs: [
+ "hoststubgen-helper-runtime",
+ "hoststubgen-helper-framework-runtime",
+ "framework-all-test-api-host-impl",
+ ],
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestClassLoadHook.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestClassLoadHook.java
new file mode 100644
index 000000000000..a774336a897c
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestClassLoadHook.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Add this with a fully-specified method name (e.g. {@code "com.package.Class.methodName"})
+ * of a callback to get a callback at the class load time.
+ *
+ * The method must be {@code public static} with a single argument that takes
+ * {@link java.lang.Class}.
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestClassLoadHook {
+ String value();
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestKeep.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestKeep.java
new file mode 100644
index 000000000000..06ad1c266a14
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestKeep.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Mark a class, field or a method as "Stub", meaning tests can _not_ see the APIs, but they
+ * can indirectly be used on the host side.
+ * When applied to a class, it will _not_ affect the visibility of its members. They need to be
+ * individually marked.
+ *
+ * <p>In order to expose a class and all its members, use {@link HostSideTestWholeClassStub}
+ * instead.
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestKeep {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestNativeSubstitutionClass.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestNativeSubstitutionClass.java
new file mode 100644
index 000000000000..9c8138351eb5
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestNativeSubstitutionClass.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * If a class has this annotation, all its native methods will be delegated to another class.
+ * (See {@link android.os.Parcel} as an example.)
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestNativeSubstitutionClass {
+ String value();
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestRemove.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestRemove.java
new file mode 100644
index 000000000000..46e5078fb05d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestRemove.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Mark an item as "remove", so this cannot be used on the host side even indirectly.
+ * This is the default behavior.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestRemove {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStaticInitializerKeep.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStaticInitializerKeep.java
new file mode 100644
index 000000000000..eec72269e0d3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStaticInitializerKeep.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestStaticInitializerKeep {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStub.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStub.java
new file mode 100644
index 000000000000..cabdfe0eeb77
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestStub.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Mark a class, field or a method as "Stub", meaning tests can see the APIs.
+ * When applied to a class, it will _not_ affect the visibility of its members. They need to be
+ * individually marked.
+ *
+ * <p>In order to expose a class and all its members, use {@link HostSideTestWholeClassStub}
+ * instead.
+ *
+ * @hide
+ */
+@Target({TYPE, FIELD, METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestStub {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestSubstitute.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestSubstitute.java
new file mode 100644
index 000000000000..510a67e0aaed
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestSubstitute.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * If a method has this annotation, we'll replace it with another method on the host side.
+ *
+ * See {@link android.util.LruCache#getEldest()} and its substitution.
+ *
+ * @hide
+ */
+@Target({METHOD})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestSubstitute {
+ // TODO We should add "_host" as default. We're not doing it yet, because extractign the default
+ // value with ASM doesn't seem trivial. (? not sure.)
+ String suffix();
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestThrow.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestThrow.java
new file mode 100644
index 000000000000..cd1bef4be505
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestThrow.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.CONSTRUCTOR;
+import static java.lang.annotation.ElementType.METHOD;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * If a method has this annotation, it will throw on the host side.
+ *
+ * @hide
+ */
+@Target({METHOD, CONSTRUCTOR})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestThrow {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassKeep.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassKeep.java
new file mode 100644
index 000000000000..3d1ddea2cbb7
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassKeep.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Same as {@link HostSideTestKeep} but it'll change the visibility of all its members too.
+ * @hide
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestWholeClassKeep {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassStub.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassStub.java
new file mode 100644
index 000000000000..1824f6f01516
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/HostSideTestWholeClassStub.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * THIS ANNOTATION IS EXPERIMENTAL. REACH OUT TO g/ravenwood BEFORE USING IT, OR YOU HAVE ANY
+ * QUESTIONS ABOUT IT.
+ *
+ * Same as {@link HostSideTestStub} but it'll change the visibility of all its members too.
+ *
+ * @hide
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.CLASS)
+public @interface HostSideTestWholeClassStub {
+}
diff --git a/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/tests/HostSideTestSuppress.java b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/tests/HostSideTestSuppress.java
new file mode 100644
index 000000000000..b10f0ff1a4b1
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/annotations-src/android/hosttest/annotation/tests/HostSideTestSuppress.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 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.hosttest.annotation.tests;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation to skip certain tests for host side tests.
+ *
+ * TODO: Actually use it in the test runner.
+ */
+@Target({TYPE, FIELD, METHOD})
+public @interface HostSideTestSuppress {
+}
diff --git a/tools/hoststubgen/hoststubgen/framework-policy-override.txt b/tools/hoststubgen/hoststubgen/framework-policy-override.txt
new file mode 100644
index 000000000000..493ad56a5cbb
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/framework-policy-override.txt
@@ -0,0 +1,102 @@
+# --------------------------------------------------------------------------------------------------
+# This file contains rules to process `framework-all.jar` to generate the host side test "stub" and
+# "impl" jars, without using Java annotations.
+#
+# Useful when:
+# - The class is auto-generated and annotations can't be added.
+# (We need to figure out what to do on auto-generated classes.)
+# - Want to quickly change filter rules without having to rebuild framework.jar.
+#
+# Using this file, one can control the visibility of APIs on a per-class, per-field and per-method
+# basis, but in most cases, per-class directives would be sufficient. That is:
+#
+# - To put the entire class, including its members and nested classes, in the "stub" jar,
+# so that the test / target code can use the API, use `stubclass`.
+#
+# class package.class stubclass
+#
+# - To put the entire class, including its members and nested classes, in the "impl" jar,
+# but not in the "stub" jar, use `keepclass`. Use this when you don't want to expose an API to
+# tests/target directly, but it's still needed at runtime, because it's used by other "stub" APIs
+# directly or indirectly.
+#
+# class package.class keepclass
+#
+# All other classes will be removed from both the stub jar and impl jar.
+#
+# --------------------------------------------------------------------------------------------------
+
+# --------------------------------------------------------------------------------------------------
+# Directions on auto-generated classes, where we can't use Java annotations (yet).
+# --------------------------------------------------------------------------------------------------
+class android.Manifest stubclass
+class android.R stubclass
+class android.os.PersistableBundleProto keepclass
+
+# This is in module-utils, where using a HostStubGen annotation would be complicated, so we
+# add a direction here rather than using a java annotation.
+# The build file says it's deprecated, anyway...? Figure out what to do with it.
+class com.android.internal.util.Preconditions keepclass
+
+# --------------------------------------------------------------------------------------------------
+# Actual framework classes
+# --------------------------------------------------------------------------------------------------
+
+# Put basic exception classes in the "impl" jar.
+# We don't put them in stub yet (until something actually needs them).
+class android.os.DeadObjectException keepclass
+class android.os.DeadSystemRuntimeException keepclass
+class android.os.NetworkOnMainThreadException keepclass
+class android.os.RemoteException keepclass
+class android.os.ServiceSpecificException keepclass
+class android.util.AndroidException keepclass
+class android.util.AndroidRuntimeException keepclass
+class android.os.DeadSystemException keepclass
+
+
+# For now, we only want to expose ArrayMap and Log, but they and their tests depend on
+# more classes.
+
+class android.util.ArrayMap stubclass
+
+# Used by ArrayMap. No need to put them in the stub, but we need them in impl.
+class android.util.MapCollections keepclass
+class android.util.ContainerHelpers keepclass
+class android.util.EmptyArray stubclass
+class com.android.internal.util.XmlUtils keepclass
+class com.android.internal.util.FastMath keepclass
+class android.util.MathUtils keepclass
+
+
+class android.util.Log stubclass
+class android.util.Slog stubclass
+# We don't use Log's native code, yet. Instead, the following line enables the Java substitution.
+# Comment it out to disable Java substitution of Log's native methods.
+class android.util.Log !com.android.hoststubgen.nativesubstitution.Log_host
+
+# Used by log
+class com.android.internal.util.FastPrintWriter keepclass
+class com.android.internal.util.LineBreakBufferedWriter keepclass
+
+class android.util.EventLog stubclass
+class android.util.EventLog !com.android.hoststubgen.nativesubstitution.EventLog_host
+class android.util.EventLog$Event stubclass
+
+# Expose Context because it's referred to by AndroidTestCase, but don't need to expose any of
+# its members.
+class android.content.Context keep
+
+# Expose Parcel, Parcel and there relevant classes, which are used by ArrayMapTets.
+class android.os.Parcelable StubClass
+class android.os.Parcel StubClass
+class android.os.Parcel !com.android.hoststubgen.nativesubstitution.Parcel_host
+
+class android.os.IBinder stubClass
+class android.os.IInterface stubclass
+
+class android.os.BadParcelableException stubclass
+class android.os.BadTypeParcelableException stubclass
+
+class android.os.BaseBundle stubclass
+class android.os.Bundle stubclass
+class android.os.PersistableBundle stubclass
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/android/test/AndroidTestCase.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/android/test/AndroidTestCase.java
new file mode 100644
index 000000000000..e6d38668335a
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/android/test/AndroidTestCase.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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.test;
+
+import android.content.Context;
+
+import junit.framework.TestCase;
+
+public class AndroidTestCase extends TestCase {
+ protected Context mContext;
+ public Context getContext() {
+ throw new RuntimeException("[ravenwood] Class Context is not supported yet.");
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/NonNull.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/NonNull.java
new file mode 100644
index 000000000000..51c5d9a05e52
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/NonNull.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2013 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 androidx.annotation;
+
+// [ravenwood] TODO: Find the actual androidx jar containing it.s
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that a parameter, field or method return value can never be null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value cannot be {@code null}.
+ * @returnDoc This value cannot be {@code null}.
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface NonNull {
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/Nullable.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/Nullable.java
new file mode 100644
index 000000000000..f1f0e8b43f16
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/annotation/Nullable.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2013 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 androidx.annotation;
+
+// [ravenwood] TODO: Find the actual androidx jar containing it.s
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Denotes that a parameter, field or method return value can be null.
+ * <p>
+ * When decorating a method call parameter, this denotes that the parameter can
+ * legitimately be null and the method will gracefully deal with it. Typically
+ * used on optional parameters.
+ * <p>
+ * When decorating a method, this denotes the method might legitimately return
+ * null.
+ * <p>
+ * This is a marker annotation and it has no specific attributes.
+ *
+ * @paramDoc This value may be {@code null}.
+ * @returnDoc This value may be {@code null}.
+ * @hide
+ */
+@Retention(SOURCE)
+@Target({METHOD, PARAMETER, FIELD})
+public @interface Nullable {
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/ext/junit/runners/AndroidJUnit4.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/ext/junit/runners/AndroidJUnit4.java
new file mode 100644
index 000000000000..0c82e4e268d3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/ext/junit/runners/AndroidJUnit4.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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 androidx.test.ext.junit.runners;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+// TODO: We need to simulate the androidx test runner.
+// https://source.corp.google.com/piper///depot/google3/third_party/android/androidx_test/ext/junit/java/androidx/test/ext/junit/runners/AndroidJUnit4.java
+// https://source.corp.google.com/piper///depot/google3/third_party/android/androidx_test/runner/android_junit_runner/java/androidx/test/internal/runner/junit4/AndroidJUnit4ClassRunner.java
+
+public class AndroidJUnit4 extends BlockJUnit4ClassRunner {
+ public AndroidJUnit4(Class<?> testClass) throws InitializationError {
+ super(testClass);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/FlakyTest.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/FlakyTest.java
new file mode 100644
index 000000000000..2470d8390f5d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/FlakyTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Designates a test as being flaky (non-deterministic).
+ *
+ * <p>Can then be used to filter tests on execution using -e annotation or -e notAnnotation as
+ * desired.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface FlakyTest {
+ /**
+ * An optional bug number associated with the test. -1 Means that no bug number is associated with
+ * the flaky annotation.
+ *
+ * @return int
+ */
+ int bugId() default -1;
+
+ /**
+ * Details, such as the reason of why the test is flaky.
+ *
+ * @return String
+ */
+ String detail() default "";
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/LargeTest.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/LargeTest.java
new file mode 100644
index 000000000000..578d7dc73647
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/LargeTest.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to assign a large test size qualifier to a test. This annotation can be used at a
+ * method or class level.
+ *
+ * <p>Test size qualifiers are a great way to structure test code and are used to assign a test to a
+ * test suite of similar run time.
+ *
+ * <p>Execution time: &gt;1000ms
+ *
+ * <p>Large tests should be focused on testing integration of all application components. These
+ * tests fully participate in the system and may make use of all resources such as databases, file
+ * systems and network. As a rule of thumb most functional UI tests are large tests.
+ *
+ * <p>Note: This class replaces the deprecated Android platform size qualifier <a
+ * href="{@docRoot}reference/android/test/suitebuilder/annotation/LargeTest.html"><code>
+ * android.test.suitebuilder.annotation.LargeTest</code></a> and is the recommended way to annotate
+ * tests written with the AndroidX Test Library.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface LargeTest {}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/MediumTest.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/MediumTest.java
new file mode 100644
index 000000000000..dfdaa53ee6ac
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/MediumTest.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2016 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to assign a medium test size qualifier to a test. This annotation can be used at a
+ * method or class level.
+ *
+ * <p>Test size qualifiers are a great way to structure test code and are used to assign a test to a
+ * test suite of similar run time.
+ *
+ * <p>Execution time: &lt;1000ms
+ *
+ * <p>Medium tests should be focused on a very limited subset of components or a single component.
+ * Resource access to the file system through well defined interfaces like databases,
+ * ContentProviders, or Context is permitted. Network access should be restricted, (long-running)
+ * blocking operations should be avoided and use mock objects instead.
+ *
+ * <p>Note: This class replaces the deprecated Android platform size qualifier <a
+ * href="{@docRoot}reference/android/test/suitebuilder/annotation/MediumTest.html"><code>
+ * android.test.suitebuilder.annotation.MediumTest</code></a> and is the recommended way to annotate
+ * tests written with the AndroidX Test Library.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface MediumTest {}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/RequiresDevice.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/RequiresDevice.java
new file mode 100644
index 000000000000..3d3ee3318bfa
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/RequiresDevice.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2014 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a specific test should not be run on emulator.
+ *
+ * <p>It will be executed only if the test is running on the physical android device.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface RequiresDevice {}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SdkSuppress.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SdkSuppress.java
new file mode 100644
index 000000000000..dd65ddb382dc
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SdkSuppress.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Indicates that a specific test or class requires a minimum or maximum API Level to execute.
+ *
+ * <p>Test(s) will be skipped when executed on android platforms less/more than specified level
+ * (inclusive).
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE, ElementType.METHOD})
+public @interface SdkSuppress {
+ /** The minimum API level to execute (inclusive) */
+ int minSdkVersion() default 1;
+ /** The maximum API level to execute (inclusive) */
+ int maxSdkVersion() default Integer.MAX_VALUE;
+ /**
+ * The {@link android.os.Build.VERSION.CODENAME} to execute on. This is intended to be used to run
+ * on a pre-release SDK, where the {@link android.os.Build.VERSION.SDK_INT} has not yet been
+ * finalized. This is treated as an OR operation with respect to the minSdkVersion and
+ * maxSdkVersion attributes.
+ *
+ * <p>For example, to filter a test so it runs on only the prerelease R SDK: <code>
+ * {@literal @}SdkSuppress(minSdkVersion = Build.VERSION_CODES.R, codeName = "R")
+ * </code>
+ */
+ String codeName() default "unset";
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SmallTest.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SmallTest.java
new file mode 100644
index 000000000000..dd32df44effe
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/SmallTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2016 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to assign a small test size qualifier to a test. This annotation can be used at a
+ * method or class level.
+ *
+ * <p>Test size qualifiers are a great way to structure test code and are used to assign a test to a
+ * test suite of similar run time.
+ *
+ * <p>Execution time: &lt;200ms
+ *
+ * <p>Small tests should be run very frequently. Focused on units of code to verify specific logical
+ * conditions. These tests should runs in an isolated environment and use mock objects for external
+ * dependencies. Resource access (such as file system, network, or databases) are not permitted.
+ * Tests that interact with hardware, make binder calls, or that facilitate android instrumentation
+ * should not use this annotation.
+ *
+ * <p>Note: This class replaces the deprecated Android platform size qualifier <a
+ * href="http://developer.android.com/reference/android/test/suitebuilder/annotation/SmallTest.html">
+ * android.test.suitebuilder.annotation.SmallTest</a> and is the recommended way to annotate tests
+ * written with the AndroidX Test Library.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface SmallTest {}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/Suppress.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/Suppress.java
new file mode 100644
index 000000000000..88e636c2dd77
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/filters/Suppress.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2016 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 androidx.test.filters;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Use this annotation on test classes or test methods that should not be included in a test suite.
+ * If the annotation appears on the class then no tests in that class will be included. If the
+ * annotation appears only on a test method then only that method will be excluded.
+ *
+ * <p>Note: This class replaces the deprecated Android platform annotation <a
+ * href="http://developer.android.com/reference/android/test/suitebuilder/annotation/Suppress.html">
+ * android.test.suitebuilder.annotation.Suppress</a> and is the recommended way to suppress tests
+ * written with the AndroidX Test Library.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface Suppress {}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/runner/AndroidJUnit4.java b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/runner/AndroidJUnit4.java
new file mode 100644
index 000000000000..e1379390f98b
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-buildtime-src/androidx/test/runner/AndroidJUnit4.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 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 androidx.test.runner;
+
+import org.junit.runners.model.InitializationError;
+
+public class AndroidJUnit4 extends androidx.test.ext.junit.runners.AndroidJUnit4 {
+ public AndroidJUnit4(Class<?> testClass) throws InitializationError {
+ super(testClass);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/EventLog_host.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/EventLog_host.java
new file mode 100644
index 000000000000..292e8da0de10
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/EventLog_host.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.nativesubstitution;
+
+import android.util.Log;
+import android.util.Log.Level;
+
+import java.util.Collection;
+
+public class EventLog_host {
+ public static int writeEvent(int tag, int value) {
+ return writeEvent(tag, (Object) value);
+ }
+
+ public static int writeEvent(int tag, long value) {
+ return writeEvent(tag, (Object) value);
+ }
+
+ public static int writeEvent(int tag, float value) {
+ return writeEvent(tag, (Object) value);
+ }
+
+ public static int writeEvent(int tag, String str) {
+ return writeEvent(tag, (Object) str);
+ }
+
+ public static int writeEvent(int tag, Object... list) {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("logd: [event] ");
+ final String tagName = android.util.EventLog.getTagName(tag);
+ if (tagName != null) {
+ sb.append(tagName);
+ } else {
+ sb.append(tag);
+ }
+ sb.append(": [");
+ for (int i = 0; i < list.length; i++) {
+ sb.append(String.valueOf(list[i]));
+ if (i < list.length - 1) {
+ sb.append(',');
+ }
+ }
+ sb.append(']');
+ System.out.println(sb.toString());
+ return sb.length();
+ }
+
+ public static void readEvents(int[] tags, Collection<android.util.EventLog.Event> output) {
+ throw new UnsupportedOperationException();
+ }
+
+ public static void readEventsOnWrapping(int[] tags, long timestamp,
+ Collection<android.util.EventLog.Event> output) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Log_host.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Log_host.java
new file mode 100644
index 000000000000..ee55c7ac6ae2
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Log_host.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.nativesubstitution;
+
+import android.util.Log;
+import android.util.Log.Level;
+
+import java.io.PrintStream;
+
+public class Log_host {
+
+ public static boolean isLoggable(String tag, @Level int level) {
+ return true;
+ }
+
+ public static int println_native(int bufID, int priority, String tag, String msg) {
+ final PrintStream out = System.out;
+ final String buffer;
+ switch (bufID) {
+ case Log.LOG_ID_MAIN: buffer = "main"; break;
+ case Log.LOG_ID_RADIO: buffer = "radio"; break;
+ case Log.LOG_ID_EVENTS: buffer = "event"; break;
+ case Log.LOG_ID_SYSTEM: buffer = "system"; break;
+ case Log.LOG_ID_CRASH: buffer = "crash"; break;
+ default: buffer = "buf:" + bufID; break;
+ };
+
+ final String prio;
+ switch (priority) {
+ case Log.VERBOSE: prio = "V"; break;
+ case Log.DEBUG: prio = "D"; break;
+ case Log.INFO: prio = "I"; break;
+ case Log.WARN: prio = "W"; break;
+ case Log.ERROR: prio = "E"; break;
+ case Log.ASSERT: prio = "A"; break;
+ default: prio = "prio:" + priority; break;
+ };
+
+ for (String s : msg.split("\\n")) {
+ out.println(String.format("logd: [%s] %s %s: %s", buffer, prio, tag, s));
+ }
+ return msg.length();
+ }
+
+ public static int logger_entry_max_payload_native() {
+ return 4068; // [ravenwood] This is what people use in various places.
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Parcel_host.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Parcel_host.java
new file mode 100644
index 000000000000..668c94c0f91c
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/Parcel_host.java
@@ -0,0 +1,424 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.nativesubstitution;
+
+import android.os.IBinder;
+
+import java.io.FileDescriptor;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Tentative, partial implementation of the Parcel native methods, using Java's
+ * {@code byte[]}.
+ * (We don't use a {@link ByteBuffer} because there's enough semantics differences between Parcel
+ * and {@link ByteBuffer}, and it didn't work out.
+ * e.g. Parcel seems to allow moving the data position to be beyond its size? Which
+ * {@link ByteBuffer} wouldn't allow...)
+ */
+public class Parcel_host {
+ private Parcel_host() {
+ }
+
+ private static final AtomicLong sNextId = new AtomicLong(0);
+
+ private static final Map<Long, Parcel_host> sInstances = new ConcurrentHashMap<>();
+
+ private boolean mDeleted = false;
+
+ private byte[] mBuffer;
+ private int mSize;
+ private int mPos;
+
+ private boolean mSensitive;
+ private boolean mAllowFds;
+
+ // TODO Use the actual value from Parcel.java.
+ private static final int OK = 0;
+
+ private void validate() {
+ if (mDeleted) {
+ // TODO: Put more info
+ throw new RuntimeException("Parcel already destroyed");
+ }
+ }
+
+ private static Parcel_host getInstance(long id) {
+ Parcel_host p = sInstances.get(id);
+ if (p == null) {
+ // TODO: Put more info
+ throw new RuntimeException("Parcel doesn't exist with id=" + id);
+ }
+ p.validate();
+ return p;
+ }
+
+ public static long nativeCreate() {
+ final long id = sNextId.getAndIncrement();
+ final Parcel_host p = new Parcel_host();
+ sInstances.put(id, p);
+ p.init();
+ return id;
+ }
+
+ private void init() {
+ mBuffer = new byte[0];
+ mSize = 0;
+ mPos = 0;
+ mSensitive = false;
+ mAllowFds = false;
+ }
+
+ private void updateSize() {
+ if (mSize < mPos) {
+ mSize = mPos;
+ }
+ }
+
+ public static void nativeDestroy(long nativePtr) {
+ getInstance(nativePtr).mDeleted = true;
+ sInstances.remove(nativePtr);
+ }
+
+ public static void nativeFreeBuffer(long nativePtr) {
+ getInstance(nativePtr).freeBuffer();
+ }
+
+ public void freeBuffer() {
+ init();
+ }
+
+ private int getCapacity() {
+ return mBuffer.length;
+ }
+
+ private void ensureMoreCapacity(int size) {
+ ensureCapacity(mPos + size);
+ }
+
+ private void ensureCapacity(int targetSize) {
+ if (targetSize <= getCapacity()) {
+ return;
+ }
+ var newSize = getCapacity() * 2;
+ if (newSize < targetSize) {
+ newSize = targetSize;
+ }
+ forceSetCapacity(newSize);
+ }
+
+ private void forceSetCapacity(int newSize) {
+ var newBuf = new byte[newSize];
+
+ // Copy
+ System.arraycopy(mBuffer, 0, newBuf, 0, Math.min(newSize, getCapacity()));
+
+ this.mBuffer = newBuf;
+ }
+
+ private void ensureDataAvailable(int requestSize) {
+ if (mSize - mPos < requestSize) {
+ throw new RuntimeException(String.format(
+ "Pacel data underflow. size=%d, pos=%d, request=%d", mSize, mPos, requestSize));
+ }
+ }
+
+ public static void nativeMarkSensitive(long nativePtr) {
+ getInstance(nativePtr).mSensitive = true;
+ }
+ public static void nativeMarkForBinder(long nativePtr, IBinder binder) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static boolean nativeIsForRpc(long nativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static int nativeDataSize(long nativePtr) {
+ return getInstance(nativePtr).mSize;
+ }
+ public static int nativeDataAvail(long nativePtr) {
+ var p = getInstance(nativePtr);
+ return p.mSize - p.mPos;
+ }
+ public static int nativeDataPosition(long nativePtr) {
+ return getInstance(nativePtr).mPos;
+ }
+ public static int nativeDataCapacity(long nativePtr) {
+ return getInstance(nativePtr).mBuffer.length;
+ }
+ public static void nativeSetDataSize(long nativePtr, int size) {
+ var p = getInstance(nativePtr);
+ p.ensureCapacity(size);
+ getInstance(nativePtr).mSize = size;
+ }
+ public static void nativeSetDataPosition(long nativePtr, int pos) {
+ var p = getInstance(nativePtr);
+ // TODO: Should this change the size or the capacity??
+ p.mPos = pos;
+ }
+ public static void nativeSetDataCapacity(long nativePtr, int size) {
+ var p = getInstance(nativePtr);
+ if (p.getCapacity() < size) {
+ p.forceSetCapacity(size);
+ }
+ }
+
+ public static boolean nativePushAllowFds(long nativePtr, boolean allowFds) {
+ var p = getInstance(nativePtr);
+ var prev = p.mAllowFds;
+ p.mAllowFds = allowFds;
+ return prev;
+ }
+ public static void nativeRestoreAllowFds(long nativePtr, boolean lastValue) {
+ getInstance(nativePtr).mAllowFds = lastValue;
+ }
+
+ public static void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len) {
+ nativeWriteBlob(nativePtr, b, offset, len);
+ }
+
+ public static void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len) {
+ var p = getInstance(nativePtr);
+
+ if (b == null) {
+ nativeWriteInt(nativePtr, -1);
+ } else {
+ final var alignedSize = align4(len);
+
+ nativeWriteInt(nativePtr, len);
+
+ p.ensureMoreCapacity(alignedSize);
+
+ System.arraycopy(b, offset, p.mBuffer, p.mPos, len);
+ p.mPos += alignedSize;
+ p.updateSize();
+ }
+ }
+
+ public static int nativeWriteInt(long nativePtr, int value) {
+ var p = getInstance(nativePtr);
+ p.ensureMoreCapacity(Integer.BYTES);
+
+ p.mBuffer[p.mPos++] = (byte) ((value >> 24) & 0xff);
+ p.mBuffer[p.mPos++] = (byte) ((value >> 16) & 0xff);
+ p.mBuffer[p.mPos++] = (byte) ((value >> 8) & 0xff);
+ p.mBuffer[p.mPos++] = (byte) ((value >> 0) & 0xff);
+
+ p.updateSize();
+
+ return OK;
+ }
+
+ public static int nativeWriteLong(long nativePtr, long value) {
+ nativeWriteInt(nativePtr, (int) (value >>> 32));
+ nativeWriteInt(nativePtr, (int) (value));
+ return OK;
+ }
+ public static int nativeWriteFloat(long nativePtr, float val) {
+ return nativeWriteInt(nativePtr, Float.floatToIntBits(val));
+ }
+ public static int nativeWriteDouble(long nativePtr, double val) {
+ return nativeWriteLong(nativePtr, Double.doubleToLongBits(val));
+ }
+ public static void nativeSignalExceptionForError(int error) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ private static int align4(int val) {
+ return ((val + 3) / 4) * 4;
+ }
+
+ public static void nativeWriteString8(long nativePtr, String val) {
+ if (val == null) {
+ nativeWriteBlob(nativePtr, null, 0, 0);
+ } else {
+ var bytes = val.getBytes(StandardCharsets.UTF_8);
+ nativeWriteBlob(nativePtr, bytes, 0, bytes.length);
+ }
+ }
+ public static void nativeWriteString16(long nativePtr, String val) {
+ // Just reuse String8
+ nativeWriteString8(nativePtr, val);
+ }
+ public static void nativeWriteStrongBinder(long nativePtr, IBinder val) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ public static byte[] nativeCreateByteArray(long nativePtr) {
+ return nativeReadBlob(nativePtr);
+ }
+
+ public static boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen) {
+ if (dest == null) {
+ return false;
+ }
+ var data = nativeReadBlob(nativePtr);
+ if (data == null) {
+ System.err.println("Percel has NULL, which is unexpected."); // TODO: Is this correct?
+ return false;
+ }
+ // TODO: Make sure the check logic is correct.
+ if (data.length != destLen) {
+ System.err.println("Byte array size mismatch: expected="
+ + data.length + " given=" + destLen);
+ return false;
+ }
+ System.arraycopy(data, 0, dest, 0, data.length);
+ return true;
+ }
+
+ public static byte[] nativeReadBlob(long nativePtr) {
+ var p = getInstance(nativePtr);
+ if (p.mSize - p.mPos < 4) {
+ // Match native impl that returns "null" when not enough data
+ return null;
+ }
+ final var size = nativeReadInt(nativePtr);
+ if (size == -1) {
+ return null;
+ }
+ try {
+ p.ensureDataAvailable(align4(size));
+ } catch (Exception e) {
+ System.err.println(e.toString());
+ return null;
+ }
+
+ var bytes = new byte[size];
+ System.arraycopy(p.mBuffer, p.mPos, bytes, 0, size);
+
+ p.mPos += align4(size);
+
+ return bytes;
+ }
+ public static int nativeReadInt(long nativePtr) {
+ var p = getInstance(nativePtr);
+
+ if (p.mSize - p.mPos < 4) {
+ // Match native impl that returns "0" when not enough data
+ return 0;
+ }
+
+ var ret = (((p.mBuffer[p.mPos++] & 0xff) << 24)
+ | ((p.mBuffer[p.mPos++] & 0xff) << 16)
+ | ((p.mBuffer[p.mPos++] & 0xff) << 8)
+ | ((p.mBuffer[p.mPos++] & 0xff) << 0));
+
+ return ret;
+ }
+ public static long nativeReadLong(long nativePtr) {
+ return (((long) nativeReadInt(nativePtr)) << 32)
+ | (((long) nativeReadInt(nativePtr)) & 0xffff_ffffL);
+ }
+
+ public static float nativeReadFloat(long nativePtr) {
+ return Float.intBitsToFloat(nativeReadInt(nativePtr));
+ }
+
+ public static double nativeReadDouble(long nativePtr) {
+ return Double.longBitsToDouble(nativeReadLong(nativePtr));
+ }
+
+ public static String nativeReadString8(long nativePtr) {
+ final var bytes = nativeReadBlob(nativePtr);
+ if (bytes == null) {
+ return null;
+ }
+ return new String(bytes, StandardCharsets.UTF_8);
+ }
+ public static String nativeReadString16(long nativePtr) {
+ return nativeReadString8(nativePtr);
+ }
+ public static IBinder nativeReadStrongBinder(long nativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static FileDescriptor nativeReadFileDescriptor(long nativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ public static byte[] nativeMarshall(long nativePtr) {
+ var p = getInstance(nativePtr);
+ return Arrays.copyOf(p.mBuffer, p.mSize);
+ }
+ public static void nativeUnmarshall(
+ long nativePtr, byte[] data, int offset, int length) {
+ var p = getInstance(nativePtr);
+ p.ensureMoreCapacity(length);
+ System.arraycopy(data, offset, p.mBuffer, p.mPos, length);
+ p.mPos += length;
+ p.updateSize();
+ }
+ public static int nativeCompareData(long thisNativePtr, long otherNativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static boolean nativeCompareDataInRange(
+ long ptrA, int offsetA, long ptrB, int offsetB, int length) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void nativeAppendFrom(
+ long thisNativePtr, long otherNativePtr, int srcOffset, int length) {
+ var dst = getInstance(thisNativePtr);
+ var src = getInstance(otherNativePtr);
+
+ dst.ensureMoreCapacity(length);
+
+ System.arraycopy(src.mBuffer, srcOffset, dst.mBuffer, dst.mPos, length);
+ dst.mPos += length; // TODO: 4 byte align?
+ dst.updateSize();
+
+ // TODO: Update the other's position?
+ }
+
+ public static boolean nativeHasFileDescriptors(long nativePtr) {
+ // Assume false for now, because we don't support writing FDs yet.
+ return false;
+ }
+ public static boolean nativeHasFileDescriptorsInRange(
+ long nativePtr, int offset, int length) {
+ // Assume false for now, because we don't support writing FDs yet.
+ return false;
+ }
+ public static void nativeWriteInterfaceToken(long nativePtr, String interfaceName) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void nativeEnforceInterface(long nativePtr, String interfaceName) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ public static boolean nativeReplaceCallingWorkSourceUid(
+ long nativePtr, int workSourceUid) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static int nativeReadCallingWorkSourceUid(long nativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ public static long nativeGetOpenAshmemSize(long nativePtr) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static long getGlobalAllocSize() {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static long getGlobalAllocCount() {
+ throw new RuntimeException("Not implemented yet");
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/SystemProperties_host.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/SystemProperties_host.java
new file mode 100644
index 000000000000..1ec1d5f307e1
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/nativesubstitution/SystemProperties_host.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.nativesubstitution;
+
+public class SystemProperties_host {
+ public static String native_get(String key, String def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static int native_get_int(String key, int def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static long native_get_long(String key, long def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static boolean native_get_boolean(String key, boolean def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+
+ public static long native_find(String name) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static String native_get(long handle) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static int native_get_int(long handle, int def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static long native_get_long(long handle, long def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static boolean native_get_boolean(long handle, boolean def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void native_set(String key, String def) {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void native_add_change_callback() {
+ throw new RuntimeException("Not implemented yet");
+ }
+ public static void native_report_sysprop_change() {
+ throw new RuntimeException("Not implemented yet");
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/runtimehelper/ClassLoadHook.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/runtimehelper/ClassLoadHook.java
new file mode 100644
index 000000000000..fbcc64892798
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/framework/com/android/hoststubgen/runtimehelper/ClassLoadHook.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.runtimehelper;
+
+import com.android.hoststubgen.hosthelper.HostTestException;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+/**
+ * Standard class loader hook.
+ *
+ * Currently, we use this class to load libandroid_runtime (if needed). In the future, we may
+ * load other JNI or do other set up here.
+ */
+public class ClassLoadHook {
+ private static PrintStream sOut = System.out;
+
+ /**
+ * If true, we won't load `libandroid_runtime`
+ *
+ * <p>Looks like there's some complexity in running a host test with JNI with `atest`,
+ * so we need a way to remove the dependency.
+ */
+ private static final boolean SKIP_LOADING_LIBANDROID = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_LOADING_LIBANDROID"));
+
+ public static final String CORE_NATIVE_CLASSES = "core_native_classes";
+ public static final String ICU_DATA_PATH = "icu.data.path";
+ public static final String KEYBOARD_PATHS = "keyboard_paths";
+ public static final String GRAPHICS_NATIVE_CLASSES = "graphics_native_classes";
+
+ public static final String VALUE_N_A = "**n/a**";
+ public static final String LIBANDROID_RUNTIME_NAME = "libandroid_runtime";
+
+ private static String sInitialDir = new File("").getAbsolutePath();
+
+ static {
+ log("Initialized. Current dir=" + sInitialDir);
+ }
+
+ private ClassLoadHook() {
+ }
+
+ /**
+ * Called when classes with
+ * {@code @HostSideTestClassLoadHook(
+ * "com.android.hoststubgen.runtimehelper.LibandroidLoadingHook.onClassLoaded") }
+ * are loaded.
+ */
+ public static void onClassLoaded(Class<?> clazz) {
+ System.out.println("Framework class loaded: " + clazz.getCanonicalName());
+
+ loadFrameworkNativeCode();
+ }
+
+ private static void log(String message) {
+ sOut.println("ClassLoadHook: " + message);
+ }
+
+ private static void log(String fmt, Object... args) {
+ log(String.format(fmt, args));
+ }
+
+ private static void ensurePropertyNotSet(String key) {
+ if (System.getProperty(key) != null) {
+ throw new HostTestException("System property \"" + key + "\" is set unexpectedly");
+ }
+ }
+
+ private static void setProperty(String key, String value) {
+ System.setProperty(key, value);
+ log("Property set: %s=\"%s\"", key, value);
+ }
+
+ private static void dumpSystemProperties() {
+ for (var prop : System.getProperties().entrySet()) {
+ log(" %s=\"%s\"", prop.getKey(), prop.getValue());
+ }
+ }
+
+ private static void loadJniLibrary(String name) {
+ final String path = sInitialDir + "/lib64/" + name + ".so";
+ System.out.println("Loading " + path + " ...");
+ System.load(path);
+ System.out.println("Done loading " + path);
+ }
+
+ private static boolean sLoadFrameworkNativeCodeCalled = false;
+
+ /**
+ * Load `libandroid_runtime` if needed.
+ */
+ private static void loadFrameworkNativeCode() {
+ // This is called from class-initializers, so no synchronization is needed.
+ if (sLoadFrameworkNativeCodeCalled) {
+ // This method has already been called before.s
+ return;
+ }
+ sLoadFrameworkNativeCodeCalled = true;
+
+ // libandroid_runtime uses Java's system properties to decide what JNI methods to set up.
+ // Set up these properties for host-side tests.
+
+ if ("1".equals(System.getenv("HOSTTEST_DUMP_PROPERTIES"))) {
+ log("Java system properties:");
+ dumpSystemProperties();
+ }
+
+ if (SKIP_LOADING_LIBANDROID) {
+ log("Skip loading " + LIBANDROID_RUNTIME_NAME);
+ }
+
+ // Make sure these properties are not set.
+ ensurePropertyNotSet(CORE_NATIVE_CLASSES);
+ ensurePropertyNotSet(ICU_DATA_PATH);
+ ensurePropertyNotSet(KEYBOARD_PATHS);
+ ensurePropertyNotSet(GRAPHICS_NATIVE_CLASSES);
+
+ // Tell libandroid what JNI to use.
+ final var jniClasses = getCoreNativeClassesToUse();
+ if (jniClasses.isEmpty()) {
+ log("No classes require JNI methods, skip loading " + LIBANDROID_RUNTIME_NAME);
+ return;
+ }
+ setProperty(CORE_NATIVE_CLASSES, jniClasses);
+ setProperty(GRAPHICS_NATIVE_CLASSES, "");
+ setProperty(ICU_DATA_PATH, VALUE_N_A);
+ setProperty(KEYBOARD_PATHS, VALUE_N_A);
+
+ loadJniLibrary(LIBANDROID_RUNTIME_NAME);
+ }
+
+ /**
+ * Classes with native methods that are backed by `libandroid_runtime`.
+ *
+ * At runtime, we check if these classes have any methods, and if so, we'll have
+ * `libandroid_runtime` register the native functions.
+ */
+ private static final Class<?>[] sClassesWithLibandroidNativeMethods = {
+ android.util.Log.class,
+ android.os.Parcel.class,
+ };
+
+ /**
+ * @return if a given method is a native method or not.
+ */
+ private static boolean hasNativeMethod(Class<?> clazz) {
+ for (var method : clazz.getDeclaredMethods()) {
+ if (Modifier.isNative(method.getModifiers())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Create a list of classes as comma-separated that require JNI methods to be set up.
+ *
+ * <p>This list is used by frameworks/base/core/jni/LayoutlibLoader.cpp to decide
+ * what JNI methods to set up.
+ */
+ private static String getCoreNativeClassesToUse() {
+ final var coreNativeClassesToLoad = new ArrayList<String>();
+
+ for (var clazz : sClassesWithLibandroidNativeMethods) {
+ if (hasNativeMethod(clazz)) {
+ log("Class %s has native methods", clazz);
+ coreNativeClassesToLoad.add(clazz.getName());
+ }
+ }
+
+ return String.join(",", coreNativeClassesToLoad);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/dalvik/system/VMRuntime.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/dalvik/system/VMRuntime.java
new file mode 100644
index 000000000000..7d2b00d9420d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/dalvik/system/VMRuntime.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 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 dalvik.system;
+
+// [ravenwood] It's in libart, so until we get ART to work, we need to use a fake.
+// The original is here:
+// $ANDROID_BUILD_TOP/libcore/libart/src/main/java/dalvik/system/VMRuntime.java
+
+import java.lang.reflect.Array;
+
+public class VMRuntime {
+ private static final VMRuntime THE_ONE = new VMRuntime();
+
+ private VMRuntime() {
+ }
+
+ public static VMRuntime getRuntime() {
+ return THE_ONE;
+ }
+
+ public boolean is64Bit() {
+ return true;
+ }
+
+ public static boolean is64BitAbi(String abi) {
+ return true;
+ }
+
+ public Object newUnpaddedArray(Class<?> componentType, int minLength) {
+ return Array.newInstance(componentType, minLength);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/EmptyArray.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/EmptyArray.java
new file mode 100644
index 000000000000..a1ae35a88656
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/EmptyArray.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2023 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 libcore.util;
+
+import java.lang.annotation.Annotation;
+
+// [ravenwood] Copied from libcore. TODO: Figure out what to do with libcore.
+public class EmptyArray {
+ private EmptyArray() {}
+
+ public static final boolean[] BOOLEAN = new boolean[0];
+
+ public static final byte[] BYTE = new byte[0];
+
+ public static final char[] CHAR = new char[0];
+
+ public static final double[] DOUBLE = new double[0];
+
+ public static final float[] FLOAT = new float[0];
+
+ public static final int[] INT = new int[0];
+
+ public static final long[] LONG = new long[0];
+
+ public static final Class<?>[] CLASS = new Class[0];
+
+ public static final Object[] OBJECT = new Object[0];
+
+ public static final String[] STRING = new String[0];
+
+ public static final Throwable[] THROWABLE = new Throwable[0];
+
+ public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
+
+ public static final java.lang.reflect.Type[] TYPE = new java.lang.reflect.Type[0];
+
+ public static final java.lang.reflect.TypeVariable[] TYPE_VARIABLE =
+ new java.lang.reflect.TypeVariable[0];
+ public static final Annotation[] ANNOTATION = new Annotation[0];
+
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/SneakyThrow.java b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/SneakyThrow.java
new file mode 100644
index 000000000000..e142c46bc311
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-framework-runtime-src/libcore-fake/libcore/util/SneakyThrow.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 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 libcore.util;
+
+// [ravenwood] Copied from libcore. TODO: Figure out what to do with libcore.
+
+public class SneakyThrow {
+
+ private SneakyThrow() {
+ }
+
+ public static void sneakyThrow(Throwable t) {
+ SneakyThrow.<RuntimeException>sneakyThrow_(t);
+ }
+
+ private static <T extends Throwable> void sneakyThrow_(Throwable t) throws T {
+ throw (T) t;
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedKeepClass.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedKeepClass.java
new file mode 100644
index 000000000000..7ada961d710f
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedKeepClass.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.hosthelper;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation added to all "stub" classes generated by HostStubGen.
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HostStubGenProcessedKeepClass {
+ String CLASS_INTERNAL_NAME = HostTestUtils.getInternalName(HostStubGenProcessedKeepClass.class);
+ String CLASS_DESCRIPTOR = "L" + CLASS_INTERNAL_NAME + ";";
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedStubClass.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedStubClass.java
new file mode 100644
index 000000000000..e598da0a3cb9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostStubGenProcessedStubClass.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.hosthelper;
+
+import static java.lang.annotation.ElementType.TYPE;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation added to all "stub" classes generated by HostStubGen.
+ */
+@Target({TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface HostStubGenProcessedStubClass {
+ String CLASS_INTERNAL_NAME = HostTestUtils.getInternalName(HostStubGenProcessedStubClass.class);
+ String CLASS_DESCRIPTOR = "L" + CLASS_INTERNAL_NAME + ";";
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestException.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestException.java
new file mode 100644
index 000000000000..c54c2c111229
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.hosthelper;
+
+public class HostTestException extends RuntimeException {
+ public HostTestException(String message) {
+ super(message);
+ }
+
+ public HostTestException(String message, Throwable inner) {
+ super(message, inner);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestSuite.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestSuite.java
new file mode 100644
index 000000000000..29f7be008eef
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestSuite.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.hosthelper;
+
+import com.google.common.reflect.ClassPath;
+import com.google.common.reflect.ClassPath.ClassInfo;
+
+import junit.framework.JUnit4TestAdapter;
+import junit.framework.TestSuite;
+
+import java.util.regex.Pattern;
+
+/**
+ * A very simple Junit {@link TestSuite} builder that finds all classes that look like test classes.
+ *
+ * We use it to run ravenwood test jars from the command line.
+ */
+public class HostTestSuite {
+ private static final String CLASS_NAME_REGEX_ENV = "HOST_TEST_CLASS_NAME_REGEX";
+
+ /**
+ * Called by junit, and return all test-looking classes as a suite.
+ */
+ public static TestSuite suite() {
+ TestSuite suite = new TestSuite();
+
+ final Pattern classNamePattern;
+ final var filterRegex = System.getenv(CLASS_NAME_REGEX_ENV);
+ if (filterRegex == null) {
+ classNamePattern = Pattern.compile("");
+ } else {
+ classNamePattern = Pattern.compile(filterRegex);
+ }
+ try {
+ // We use guava to list all classes.
+ ClassPath cp = ClassPath.from(HostTestSuite.class.getClassLoader());
+
+ for (var classInfo : cp.getAllClasses()) {
+ Class<?> clazz = asTestClass(classInfo);
+ if (clazz != null) {
+ if (classNamePattern.matcher(clazz.getSimpleName()).find()) {
+ System.out.println("Test class found " + clazz.getName());
+ } else {
+ System.out.println("Skipping test class (for $"
+ + CLASS_NAME_REGEX_ENV + "): " + clazz.getName());
+ }
+ suite.addTest(new JUnit4TestAdapter(clazz));
+ }
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return suite;
+ }
+
+ /**
+ * Decide whether a class looks like a test class or not, and if so, return it as a Class
+ * instance.
+ */
+ private static Class<?> asTestClass(ClassInfo classInfo) {
+ try {
+ final Class<?> clazz = classInfo.load();
+
+ // Does it extend junit.framework.TestCase?
+ if (junit.framework.TestCase.class.isAssignableFrom(clazz)) {
+ // Ignore classes in JUnit itself, or the android(x) test lib.
+ if (classInfo.getName().startsWith("junit.")
+ || classInfo.getName().startsWith("org.junit.")
+ || classInfo.getName().startsWith("android.test.")
+ || classInfo.getName().startsWith("androidx.test.")) {
+ return null; // Ignore junit classes.
+ }
+ return clazz;
+ }
+ // Does it have any "@Test" method?
+ for (var method : clazz.getMethods()) {
+ for (var an : method.getAnnotations()) {
+ if (an.annotationType() == org.junit.Test.class) {
+ return clazz;
+ }
+ }
+ }
+ return null;
+ } catch (java.lang.NoClassDefFoundError e) {
+ // Ignore unloadable classes.
+ return null;
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
new file mode 100644
index 000000000000..c770b9ccc800
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/helper-runtime-src/com/android/hoststubgen/hosthelper/HostTestUtils.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.hosthelper;
+
+import java.io.PrintStream;
+import java.lang.StackWalker.Option;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+
+import javax.annotation.concurrent.GuardedBy;
+
+import org.junit.AssumptionViolatedException;
+
+/**
+ * Utilities used in the host side test environment.
+ */
+public class HostTestUtils {
+ private HostTestUtils() {
+ }
+
+ /**
+ * Same as ASM's Type.getInternalName(). Copied here, to avoid having a reference to ASM
+ * in this JAR.
+ */
+ public static String getInternalName(final Class<?> clazz) {
+ return clazz.getName().replace('.', '/');
+ }
+
+ public static final String CLASS_INTERNAL_NAME = getInternalName(HostTestUtils.class);
+
+ /** If true, we won't print method call log. */
+ private static final boolean SKIP_METHOD_LOG = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_METHOD_LOG"));
+
+ /** If true, we won't print class load log. */
+ private static final boolean SKIP_CLASS_LOG = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_CLASS_LOG"));
+
+ /** If true, we won't perform non-stub method direct call check. */
+ private static final boolean SKIP_NON_STUB_METHOD_CHECK = "1".equals(System.getenv(
+ "HOSTTEST_SKIP_NON_STUB_METHOD_CHECK"));
+
+
+ /**
+ * Method call log will be printed to it.
+ */
+ public static PrintStream logPrintStream = System.out;
+
+ /**
+ * Called from methods with FilterPolicy.Throw.
+ */
+ public static void onThrowMethodCalled() {
+ // TODO: Maybe add call tracking?
+ throw new RuntimeException("This method is not supported on the host side");
+ }
+
+ /**
+ * Trampoline method for method-call-hook.
+ */
+ public static void callMethodCallHook(
+ Class<?> methodClass,
+ String methodName,
+ String methodDescriptor,
+ String callbackMethod
+ ) {
+ callStaticMethodByName(callbackMethod, "method call hook", methodClass,
+ methodName, methodDescriptor);
+ }
+
+ /**
+ * I can be used as
+ * {@code --default-method-call-hook
+ * com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall}.
+ *
+ * It logs every single methods called.
+ */
+ public static void logMethodCall(
+ Class<?> methodClass,
+ String methodName,
+ String methodDescriptor
+ ) {
+ if (SKIP_METHOD_LOG) {
+ return;
+ }
+ logPrintStream.println("# method called: " + methodClass.getCanonicalName() + "."
+ + methodName + methodDescriptor);
+ }
+
+ private static final StackWalker sStackWalker =
+ StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
+
+ /**
+ * Return a {@link StackWalker} that supports {@link StackWalker#getCallerClass()}.
+ */
+ public static StackWalker getStackWalker() {
+ return sStackWalker;
+ }
+
+ /**
+ * Cache used by {@link #isClassAllowedToCallNonStubMethods}.
+ */
+ @GuardedBy("sAllowedClasses")
+ private static final HashMap<Class, Boolean> sAllowedClasses = new HashMap();
+
+ /**
+ * Return true if a given class is allowed to access non-stub methods -- that is, if the class
+ * is in the hoststubgen generated JARs. (not in the test jar.)
+ */
+ private static boolean isClassAllowedToCallNonStubMethods(Class<?> clazz) {
+ synchronized (sAllowedClasses) {
+ var cached = sAllowedClasses.get(clazz);
+ if (cached != null) {
+ return cached;
+ }
+ }
+ // All processed classes have this annotation.
+ var allowed = clazz.getAnnotation(HostStubGenProcessedKeepClass.class) != null;
+
+ // Java classes should be able to access any methods. (via callbacks, etc.)
+ if (!allowed) {
+ if (clazz.getPackageName().startsWith("java.")
+ || clazz.getPackageName().startsWith("javax.")) {
+ allowed = true;
+ }
+ }
+ synchronized (sAllowedClasses) {
+ sAllowedClasses.put(clazz, allowed);
+ }
+ return allowed;
+ }
+
+ /**
+ * Called when non-stub methods are called. We do a host-unsupported method direct call check
+ * in here.
+ */
+ public static void onNonStubMethodCalled(
+ String methodClass,
+ String methodName,
+ String methodDescriptor,
+ Class<?> callerClass) {
+ if (SKIP_NON_STUB_METHOD_CHECK) {
+ return;
+ }
+ if (isClassAllowedToCallNonStubMethods(callerClass)) {
+ return; // Generated class is allowed to call framework class.
+ }
+ logPrintStream.println("! " + methodClass + "." + methodName + methodDescriptor
+ + " called by " + callerClass.getCanonicalName());
+ }
+
+ /**
+ * Called when any top level class (not nested classes) in the impl jar is loaded.
+ *
+ * When HostStubGen inject a class-load hook, it's always a call to this method, with the
+ * actual method name as the second argument.
+ *
+ * This method discovers the hook method with reflections and call it.
+ *
+ * TODO: Add a unit test.
+ */
+ public static void onClassLoaded(Class<?> loadedClass, String callbackMethod) {
+ logPrintStream.println("! Class loaded: " + loadedClass.getCanonicalName()
+ + " calling hook " + callbackMethod);
+
+ callStaticMethodByName(callbackMethod, "class load hook", loadedClass);
+ }
+
+ private static void callStaticMethodByName(String classAndMethodName,
+ String description, Object... args) {
+ // Forward the call to callbackMethod.
+ final int lastPeriod = classAndMethodName.lastIndexOf(".");
+
+ if ((lastPeriod) < 0 || (lastPeriod == classAndMethodName.length() - 1)) {
+ throw new HostTestException(String.format(
+ "Unable to find %s: malformed method name \"%s\"",
+ description,
+ classAndMethodName));
+ }
+
+ final String className = classAndMethodName.substring(0, lastPeriod);
+ final String methodName = classAndMethodName.substring(lastPeriod + 1);
+
+ Class<?> clazz = null;
+ try {
+ clazz = Class.forName(className);
+ } catch (Exception e) {
+ throw new HostTestException(String.format(
+ "Unable to find %s: Class %s not found",
+ description,
+ className), e);
+ }
+ if (!Modifier.isPublic(clazz.getModifiers())) {
+ throw new HostTestException(String.format(
+ "Unable to find %s: Class %s must be public",
+ description,
+ className));
+ }
+
+ Class<?>[] argTypes = new Class[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argTypes[i] = args[i].getClass();
+ }
+
+ Method method = null;
+ try {
+ method = clazz.getMethod(methodName, argTypes);
+ } catch (Exception e) {
+ throw new HostTestException(String.format(
+ "Unable to find %s: class %s doesn't have method %s"
+ + " (method must take exactly one parameter of type Class,"
+ + " and public static)",
+ description, className, methodName), e);
+ }
+ if (!(Modifier.isPublic(method.getModifiers())
+ && Modifier.isStatic(method.getModifiers()))) {
+ throw new HostTestException(String.format(
+ "Unable to find %s: Method %s in class %s must be public static",
+ description, methodName, className));
+ }
+ try {
+ method.invoke(null, args);
+ } catch (Exception e) {
+ throw new HostTestException(String.format(
+ "Unable to invoke %s %s.%s",
+ description, className, methodName), e);
+ }
+ }
+
+ /**
+ * I can be used as
+ * {@code --default-class-load-hook
+ * com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded}.
+ *
+ * It logs every loaded class.
+ */
+ public static void logClassLoaded(Class<?> clazz) {
+ if (SKIP_CLASS_LOG) {
+ return;
+ }
+ logPrintStream.println("# class loaded: " + clazz.getCanonicalName());
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt b/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt
new file mode 100644
index 000000000000..c371b5d54ebd
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/hoststubgen-standard-options.txt
@@ -0,0 +1,44 @@
+# File containing standard options to HostStubGen
+
+--debug
+
+# Uncomment below lines to enable each feature.
+--enable-non-stub-method-check
+# --no-non-stub-method-check
+
+#--default-method-call-hook
+# com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+#--default-class-load-hook
+# com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+
+# Standard annotations.
+# Note, each line is a single argument, so we need newlines after each `--xxx-annotation`.
+--stub-annotation
+ android.hosttest.annotation.HostSideTestStub
+
+--keep-annotation
+ android.hosttest.annotation.HostSideTestKeep
+
+--stub-class-annotation
+ android.hosttest.annotation.HostSideTestWholeClassStub
+
+--keep-class-annotation
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+
+--throw-annotation
+ android.hosttest.annotation.HostSideTestThrow
+
+--remove-annotation
+ android.hosttest.annotation.HostSideTestRemove
+
+--substitute-annotation
+ android.hosttest.annotation.HostSideTestSubstitute
+
+--native-substitute-annotation
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass
+
+--class-load-hook-annotation
+ android.hosttest.annotation.HostSideTestClassLoadHook
+
+--keep-static-initializer-annotation
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
diff --git a/tools/hoststubgen/hoststubgen/invoketest/Android.bp b/tools/hoststubgen/hoststubgen/invoketest/Android.bp
new file mode 100644
index 000000000000..7e90e421a1f9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/invoketest/Android.bp
@@ -0,0 +1,20 @@
+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"],
+}
+
+sh_test_host {
+ name: "hoststubgen-invoke-test",
+ src: "hoststubgen-invoke-test.sh",
+ test_suites: ["general-tests"],
+
+ // Note: java_data: ["hoststubgen"] will only install the jar file, but not the command wrapper.
+ java_data: [
+ "hoststubgen",
+ "hoststubgen-test-tiny-framework",
+ ],
+}
diff --git a/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
new file mode 100755
index 000000000000..85038be80c51
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/invoketest/hoststubgen-invoke-test.sh
@@ -0,0 +1,234 @@
+#!/bin/bash
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This command is expected to be executed with: atest hoststubgen-invoke-test
+
+set -e # Exit when any command files
+
+# This script runs HostStubGen directly with various arguments and make sure
+# the tool behaves in the expected way.
+
+
+echo "# Listing files in the test environment"
+ls -lR
+
+echo "# Dumping the environment variables"
+env
+
+# Set up the constants and variables
+
+# Bazel sets $TEST_TMPDIR.
+export TEMP=$TEST_TMPDIR
+
+if [[ "$TEMP" == "" ]] ; then
+ TEMP=./tmp
+ mkdir -p $TEMP
+fi
+
+cleanup_temp() {
+ rm -fr $TEMP/*
+}
+
+cleanup_temp
+
+JAR=hoststubgen-test-tiny-framework.jar
+STUB=$TEMP/stub.jar
+IMPL=$TEMP/impl.jar
+
+ANNOTATION_FILTER=$TEMP/annotation-filter.txt
+
+HOSTSTUBGEN_OUT=$TEMP/output.txt
+
+# Because of `set -e`, we can't return non-zero from functions, so we store
+# HostStubGen result in it.
+HOSTSTUBGEN_RC=0
+
+# Note, because the build rule will only install hoststubgen.jar, but not the wrapper script,
+# we need to execute it manually with the java command.
+hoststubgen() {
+ echo "Running hoststubgen with: $*"
+ java -jar ./hoststubgen.jar "$@"
+}
+
+run_hoststubgen() {
+ local test_name="$1"
+ local annotation_filter="$2"
+
+ echo "# Test: $test_name"
+
+ cleanup_temp
+
+ local filter_arg=""
+
+ if [[ "$annotation_filter" != "" ]] ; then
+ echo "$annotation_filter" > $ANNOTATION_FILTER
+ filter_arg="--annotation-allowed-classes-file $ANNOTATION_FILTER"
+ echo "=== filter ==="
+ cat $ANNOTATION_FILTER
+ fi
+
+ local stub_arg=""
+ local impl_arg=""
+
+ if [[ "$STUB" != "" ]] ; then
+ stub_arg="--out-stub-jar $STUB"
+ fi
+ if [[ "$IMPL" != "" ]] ; then
+ impl_arg="--out-impl-jar $IMPL"
+ fi
+
+ hoststubgen \
+ --debug \
+ --in-jar $JAR \
+ $stub_arg \
+ $impl_arg \
+ --stub-annotation \
+ android.hosttest.annotation.HostSideTestStub \
+ --keep-annotation \
+ android.hosttest.annotation.HostSideTestKeep \
+ --stub-class-annotation \
+ android.hosttest.annotation.HostSideTestWholeClassStub \
+ --keep-class-annotation \
+ android.hosttest.annotation.HostSideTestWholeClassKeep \
+ --throw-annotation \
+ android.hosttest.annotation.HostSideTestThrow \
+ --remove-annotation \
+ android.hosttest.annotation.HostSideTestRemove \
+ --substitute-annotation \
+ android.hosttest.annotation.HostSideTestSubstitute \
+ --native-substitute-annotation \
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass \
+ --class-load-hook-annotation \
+ android.hosttest.annotation.HostSideTestClassLoadHook \
+ --keep-static-initializer-annotation \
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep \
+ $filter_arg \
+ |& tee $HOSTSTUBGEN_OUT
+ HOSTSTUBGEN_RC=${PIPESTATUS[0]}
+ echo "HostStubGen exited with $HOSTSTUBGEN_RC"
+ return 0
+}
+
+assert_file_generated() {
+ local file="$1"
+ if [[ "$file" == "" ]] ; then
+ if [[ -f "$file" ]] ; then
+ echo "HostStubGen shouldn't have generated $file"
+ return 1
+ fi
+ else
+ if ! [[ -f "$file" ]] ; then
+ echo "HostStubGen didn't generate $file"
+ return 1
+ fi
+ fi
+}
+
+run_hoststubgen_for_success() {
+ run_hoststubgen "$@"
+
+ if (( $HOSTSTUBGEN_RC != 0 )) ; then
+ echo "HostStubGen expected to finish successfully, but failed with $rc"
+ return 1
+ fi
+
+ assert_file_generated "$STUB"
+ assert_file_generated "$IMPL"
+}
+
+run_hoststubgen_for_failure() {
+ local test_name="$1"
+ local expected_error_message="$2"
+ shift 2
+
+ run_hoststubgen "$test_name" "$@"
+
+ if (( $HOSTSTUBGEN_RC == 0 )) ; then
+ echo "HostStubGen expected to fail, but it didn't fail"
+ return 1
+ fi
+
+ # The output should contain the expected message. (note we se fgrep here.)
+ grep -Fq "$expected_error_message" $HOSTSTUBGEN_OUT
+}
+
+# Start the tests...
+
+# Pass "" as a filter to _not_ add `--annotation-allowed-classes-file`.
+run_hoststubgen_for_success "No annotation filter" ""
+
+# Now, we use " ", so we do add `--annotation-allowed-classes-file`.
+run_hoststubgen_for_failure "No classes are allowed to have annotations" \
+ "not allowed to have Ravenwood annotations" \
+ " "
+
+run_hoststubgen_for_success "All classes allowed (wildcard)" \
+ "
+* # Allow all classes
+"
+
+run_hoststubgen_for_failure "All classes disallowed (wildcard)" \
+ "not allowed to have Ravenwood annotations" \
+ "
+!* # Disallow all classes
+"
+
+run_hoststubgen_for_failure "Some classes not allowed (1)" \
+ "not allowed to have Ravenwood annotations" \
+ "
+android.hosttest.*
+com.android.hoststubgen.*
+com.supported.*
+"
+
+run_hoststubgen_for_failure "Some classes not allowed (2)" \
+ "not allowed to have Ravenwood annotations" \
+ "
+android.hosttest.*
+com.android.hoststubgen.*
+com.unsupported.*
+"
+
+run_hoststubgen_for_success "All classes allowed (package wildcard)" \
+ "
+android.hosttest.*
+com.android.hoststubgen.*
+com.supported.*
+com.unsupported.*
+"
+
+
+run_hoststubgen_for_failure "One specific class disallowed" \
+ "TinyFrameworkClassAnnotations is not allowed to have Ravenwood annotations" \
+ "
+!com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+* # All other classes allowed
+"
+
+run_hoststubgen_for_success "One specific class disallowed, but it doesn't use annotations" \
+ "
+!com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+* # All other classes allowed
+"
+
+STUB="" run_hoststubgen_for_success "No stub generation" ""
+
+IMPL="" run_hoststubgen_for_success "No impl generation" ""
+
+STUB="" IMPL="" run_hoststubgen_for_success "No stub, no impl generation" ""
+
+
+echo "All tests passed"
+exit 0 \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/jarjar-rules.txt b/tools/hoststubgen/hoststubgen/jarjar-rules.txt
new file mode 100644
index 000000000000..4e61ba6f67b3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/jarjar-rules.txt
@@ -0,0 +1,2 @@
+# Rename guava
+rule com.google.common.** com.android.hoststubgen.x.@0 \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Exceptions.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Exceptions.kt
new file mode 100644
index 000000000000..207ba52685f8
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Exceptions.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+/**
+ * We will not print the stack trace for exceptions implementing it.
+ */
+interface UserErrorException
+
+/**
+ * Exceptions about parsing class files.
+ */
+class ClassParseException(message: String) : Exception(message)
+
+/**
+ * Use it for internal exception that really shouldn't happen.
+ */
+class HostStubGenInternalException(message: String) : Exception(message)
+
+/**
+ * Exceptions about the content in a jar file.
+ */
+class InvalidJarFileException(message: String) : Exception(message), UserErrorException
+
+/**
+ * Exceptions missing classes, fields, methods, etc.
+ */
+class UnknownApiException(message: String) : Exception(message), UserErrorException
+
+/**
+ * Exceptions related to invalid annotations -- e.g. more than one visibility annotation
+ * on a single API.
+ */
+class InvalidAnnotationException(message: String) : Exception(message), UserErrorException
+
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
new file mode 100644
index 000000000000..3cdddc23b332
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -0,0 +1,437 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.filters.AnnotationBasedFilter
+import com.android.hoststubgen.filters.ClassWidePolicyPropagatingFilter
+import com.android.hoststubgen.filters.ConstantFilter
+import com.android.hoststubgen.filters.DefaultHookInjectingFilter
+import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.filters.ImplicitOutputFilter
+import com.android.hoststubgen.filters.KeepAllClassesFilter
+import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.filters.StubIntersectingFilter
+import com.android.hoststubgen.filters.createFilterFromTextPolicyFile
+import com.android.hoststubgen.filters.printAsTextPolicy
+import com.android.hoststubgen.utils.ClassFilter
+import com.android.hoststubgen.visitors.BaseAdapter
+import com.android.hoststubgen.visitors.PackageRedirectRemapper
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.ClassWriter
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.util.CheckClassAdapter
+import java.io.BufferedInputStream
+import java.io.FileOutputStream
+import java.io.InputStream
+import java.io.OutputStream
+import java.io.PrintWriter
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+import java.util.zip.ZipOutputStream
+
+/**
+ * Actual main class.
+ */
+class HostStubGen(val options: HostStubGenOptions) {
+ fun run() {
+ val errors = HostStubGenErrors()
+
+ // Load all classes.
+ val allClasses = loadClassStructures(options.inJar)
+
+ // Dump the classes, if specified.
+ options.inputJarDumpFile?.let {
+ PrintWriter(it).use { pw -> allClasses.dump(pw) }
+ log.i("Dump file created at $it")
+ }
+
+ options.inputJarAsKeepAllFile?.let {
+ PrintWriter(it).use {
+ pw -> allClasses.forEach {
+ classNode -> printAsTextPolicy(pw, classNode)
+ }
+ }
+ log.i("Dump file created at $it")
+ }
+
+ // Build the filters.
+ val filter = buildFilter(errors, allClasses, options)
+
+ // Transform the jar.
+ convert(
+ options.inJar,
+ options.outStubJar,
+ options.outImplJar,
+ filter,
+ options.enableClassChecker,
+ allClasses,
+ errors,
+ )
+ }
+
+ /**
+ * Load all the classes, without code.
+ */
+ private fun loadClassStructures(inJar: String): ClassNodes {
+ log.i("Reading class structure from $inJar ...")
+ val start = System.currentTimeMillis()
+
+ val allClasses = ClassNodes()
+
+ log.withIndent {
+ ZipFile(inJar).use { inZip ->
+ val inEntries = inZip.entries()
+
+ while (inEntries.hasMoreElements()) {
+ val entry = inEntries.nextElement()
+
+ BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
+ if (entry.name.endsWith(".class")) {
+ val cr = ClassReader(bis)
+ val cn = ClassNode()
+ cr.accept(cn, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG
+ or ClassReader.SKIP_FRAMES)
+ if (!allClasses.addClass(cn)) {
+ log.w("Duplicate class found: ${cn.name}")
+ }
+ } else if (entry.name.endsWith(".dex")) {
+ // Seems like it's an ART jar file. We can't process it.
+ // It's a fatal error.
+ throw InvalidJarFileException(
+ "$inJar is not a desktop jar file. It contains a *.dex file.")
+ } else {
+ // Unknown file type. Skip.
+ while (bis.available() > 0) {
+ bis.skip((1024 * 1024).toLong())
+ }
+ }
+ }
+ }
+ }
+ }
+ if (allClasses.size == 0) {
+ log.w("$inJar contains no *.class files.")
+ }
+
+ val end = System.currentTimeMillis()
+ log.v("Done reading class structure in %.1f second(s).", (end - start) / 1000.0)
+ return allClasses
+ }
+
+ /**
+ * Build the filter, which decides what classes/methods/fields should be put in stub or impl
+ * jars, and "how". (e.g. with substitution?)
+ */
+ private fun buildFilter(
+ errors: HostStubGenErrors,
+ allClasses: ClassNodes,
+ options: HostStubGenOptions,
+ ): OutputFilter {
+ // We build a "chain" of multiple filters here.
+ //
+ // The filters are build in from "inside", meaning the first filter created here is
+ // the last filter used, so it has the least precedence.
+ //
+ // So, for example, the "remove" annotation, which is handled by AnnotationBasedFilter,
+ // can override a class-wide annotation, which is handled by
+ // ClassWidePolicyPropagatingFilter, and any annotations can be overridden by the
+ // text-file based filter, which is handled by parseTextFilterPolicyFile.
+
+ // The first filter is for the default policy from the command line options.
+ var filter: OutputFilter = ConstantFilter(options.defaultPolicy, "default-by-options")
+
+ // Next, we need a filter that resolves "class-wide" policies.
+ // This is used when a member (methods, fields, nested classes) don't get any polices
+ // from upper filters. e.g. when a method has no annotations, then this filter will apply
+ // the class-wide policy, if any. (if not, we'll fall back to the above filter.)
+ filter = ClassWidePolicyPropagatingFilter(filter)
+
+ // Inject default hooks from options.
+ filter = DefaultHookInjectingFilter(
+ options.defaultClassLoadHook,
+ options.defaultMethodCallHook,
+ filter
+ )
+
+ val annotationAllowedClassesFilter = options.annotationAllowedClassesFile.let { filename ->
+ if (filename == null) {
+ ClassFilter.newNullFilter(true) // Allow all classes
+ } else {
+ ClassFilter.loadFromFile(filename, false)
+ }
+ }
+
+ // Next, Java annotation based filter.
+ filter = AnnotationBasedFilter(
+ errors,
+ allClasses,
+ options.stubAnnotations,
+ options.keepAnnotations,
+ options.stubClassAnnotations,
+ options.keepClassAnnotations,
+ options.throwAnnotations,
+ options.removeAnnotations,
+ options.substituteAnnotations,
+ options.nativeSubstituteAnnotations,
+ options.classLoadHookAnnotations,
+ options.keepStaticInitializerAnnotations,
+ annotationAllowedClassesFilter,
+ filter,
+ )
+
+ // Next, "text based" filter, which allows to override polices without touching
+ // the target code.
+ options.policyOverrideFile?.let {
+ filter = createFilterFromTextPolicyFile(it, allClasses, filter)
+ }
+
+ // If `--intersect-stub-jar` is provided, load from these jar files too.
+ // We use this to restrict stub APIs to public/system/test APIs,
+ // by intersecting with a stub jar file created by metalava.
+ if (options.intersectStubJars.size > 0) {
+ val intersectingJars = loadIntersectingJars(options.intersectStubJars)
+
+ filter = StubIntersectingFilter(errors, intersectingJars, filter)
+ }
+
+ // Apply the implicit filter.
+ filter = ImplicitOutputFilter(errors, allClasses, filter)
+
+ // Optionally keep all classes.
+ if (options.keepAllClasses) {
+ filter = KeepAllClassesFilter(filter)
+ }
+
+ return filter
+ }
+
+ /**
+ * Load jar files specified with "--intersect-stub-jar".
+ */
+ private fun loadIntersectingJars(filenames: Set<String>): Map<String, ClassNodes> {
+ val intersectingJars = mutableMapOf<String, ClassNodes>()
+
+ filenames.forEach { filename ->
+ intersectingJars[filename] = loadClassStructures(filename)
+ }
+ return intersectingJars
+ }
+
+ /**
+ * Convert a JAR file into "stub" and "impl" JAR files.
+ */
+ private fun convert(
+ inJar: String,
+ outStubJar: String?,
+ outImplJar: String?,
+ filter: OutputFilter,
+ enableChecker: Boolean,
+ classes: ClassNodes,
+ errors: HostStubGenErrors,
+ ) {
+ log.i("Converting %s into [stub: %s, impl: %s] ...", inJar, outStubJar, outImplJar)
+ log.i("Checker is %s", if (enableChecker) "enabled" else "disabled")
+
+ val start = System.currentTimeMillis()
+
+ val packageRedirector = PackageRedirectRemapper(options.packageRedirects)
+
+ log.withIndent {
+ // Open the input jar file and process each entry.
+ ZipFile(inJar).use { inZip ->
+ maybeWithZipOutputStream(outStubJar) { stubOutStream ->
+ maybeWithZipOutputStream(outImplJar) { implOutStream ->
+ val inEntries = inZip.entries()
+ while (inEntries.hasMoreElements()) {
+ val entry = inEntries.nextElement()
+ convertSingleEntry(inZip, entry, stubOutStream, implOutStream,
+ filter, packageRedirector, enableChecker, classes, errors)
+ }
+ log.i("Converted all entries.")
+ }
+ }
+ outStubJar?.let { log.i("Created stub: $it") }
+ outImplJar?.let { log.i("Created impl: $it") }
+ }
+ }
+ val end = System.currentTimeMillis()
+ log.v("Done transforming the jar in %.1f second(s).", (end - start) / 1000.0)
+ }
+
+ private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
+ if (filename == null) {
+ return block(null)
+ }
+ return ZipOutputStream(FileOutputStream(filename)).use(block)
+ }
+
+ /**
+ * Convert a single ZIP entry, which may or may not be a class file.
+ */
+ private fun convertSingleEntry(
+ inZip: ZipFile,
+ entry: ZipEntry,
+ stubOutStream: ZipOutputStream?,
+ implOutStream: ZipOutputStream?,
+ filter: OutputFilter,
+ packageRedirector: PackageRedirectRemapper,
+ enableChecker: Boolean,
+ classes: ClassNodes,
+ errors: HostStubGenErrors,
+ ) {
+ log.d("Entry: %s", entry.name)
+ log.withIndent {
+ val name = entry.name
+
+ // Just ignore all the directories. (TODO: make sure it's okay)
+ if (name.endsWith("/")) {
+ return
+ }
+
+ // If it's a class, convert it.
+ if (name.endsWith(".class")) {
+ processSingleClass(inZip, entry, stubOutStream, implOutStream, filter,
+ packageRedirector, enableChecker, classes, errors)
+ return
+ }
+
+ // Handle other file types...
+
+ // - *.uau seems to contain hidden API information.
+ // - *_compat_config.xml is also about compat-framework.
+ if (name.endsWith(".uau") ||
+ name.endsWith("_compat_config.xml")) {
+ log.d("Not needed: %s", entry.name)
+ return
+ }
+
+ // Unknown type, we just copy it to both output zip files.
+ // TODO: We probably shouldn't do it for stub jar?
+ log.v("Copying: %s", entry.name)
+ stubOutStream?.let { copyZipEntry(inZip, entry, it) }
+ implOutStream?.let { copyZipEntry(inZip, entry, it) }
+ }
+ }
+
+ /**
+ * Copy a single ZIP entry to the output.
+ */
+ private fun copyZipEntry(
+ inZip: ZipFile,
+ entry: ZipEntry,
+ out: ZipOutputStream,
+ ) {
+ BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
+ // Copy unknown entries as is to the impl out. (but not to the stub out.)
+ val outEntry = ZipEntry(entry.name)
+ out.putNextEntry(outEntry)
+ while (bis.available() > 0) {
+ out.write(bis.read())
+ }
+ out.closeEntry()
+ }
+ }
+
+ /**
+ * Convert a single class to "stub" and "impl".
+ */
+ private fun processSingleClass(
+ inZip: ZipFile,
+ entry: ZipEntry,
+ stubOutStream: ZipOutputStream?,
+ implOutStream: ZipOutputStream?,
+ filter: OutputFilter,
+ packageRedirector: PackageRedirectRemapper,
+ enableChecker: Boolean,
+ classes: ClassNodes,
+ errors: HostStubGenErrors,
+ ) {
+ val classInternalName = entry.name.replaceFirst("\\.class$".toRegex(), "")
+ val classPolicy = filter.getPolicyForClass(classInternalName)
+ if (classPolicy.policy == FilterPolicy.Remove) {
+ log.d("Removing class: %s %s", classInternalName, classPolicy)
+ return
+ }
+ // Generate stub first.
+ if (stubOutStream != null && classPolicy.policy.needsInStub) {
+ log.v("Creating stub class: %s Policy: %s", classInternalName, classPolicy)
+ log.withIndent {
+ BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
+ val newEntry = ZipEntry(entry.name)
+ stubOutStream.putNextEntry(newEntry)
+ convertClass(classInternalName, /*forImpl=*/false, bis,
+ stubOutStream, filter, packageRedirector, enableChecker, classes,
+ errors)
+ stubOutStream.closeEntry()
+ }
+ }
+ }
+ if (implOutStream != null && classPolicy.policy.needsInImpl) {
+ log.v("Creating impl class: %s Policy: %s", classInternalName, classPolicy)
+ log.withIndent {
+ BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
+ val newEntry = ZipEntry(entry.name)
+ implOutStream.putNextEntry(newEntry)
+ convertClass(classInternalName, /*forImpl=*/true, bis,
+ implOutStream, filter, packageRedirector, enableChecker, classes,
+ errors)
+ implOutStream.closeEntry()
+ }
+ }
+ }
+ }
+
+ /**
+ * Convert a single class to either "stub" or "impl".
+ */
+ private fun convertClass(
+ classInternalName: String,
+ forImpl: Boolean,
+ input: InputStream,
+ out: OutputStream,
+ filter: OutputFilter,
+ packageRedirector: PackageRedirectRemapper,
+ enableChecker: Boolean,
+ classes: ClassNodes,
+ errors: HostStubGenErrors,
+ ) {
+ val cr = ClassReader(input)
+
+ // COMPUTE_FRAMES wouldn't be happy if code uses
+ val flags = ClassWriter.COMPUTE_MAXS // or ClassWriter.COMPUTE_FRAMES
+ val cw = ClassWriter(flags)
+
+ // Connect to the class writer
+ var outVisitor: ClassVisitor = cw
+ if (enableChecker) {
+ outVisitor = CheckClassAdapter(outVisitor)
+ }
+ val visitorOptions = BaseAdapter.Options(
+ enablePreTrace = options.enablePreTrace,
+ enablePostTrace = options.enablePostTrace,
+ enableNonStubMethodCallDetection = options.enableNonStubMethodCallDetection,
+ errors = errors,
+ )
+ outVisitor = BaseAdapter.getVisitor(classInternalName, classes, outVisitor, filter,
+ packageRedirector, forImpl, visitorOptions)
+
+ cr.accept(outVisitor, ClassReader.EXPAND_FRAMES)
+ val data = cw.toByteArray()
+ out.write(data)
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt
new file mode 100644
index 000000000000..9df04892ddbd
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenErrors.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+class HostStubGenErrors {
+ fun onErrorFound(message: String) {
+ // For now, we just throw as soon as any error is found, but eventually we should keep
+ // all errors and print them at the end.
+ throw RuntimeException(message)
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
new file mode 100644
index 000000000000..5e71a3690700
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenLogger.kt
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+import java.io.OutputStream
+import java.io.PrintStream
+
+val log: HostStubGenLogger = HostStubGenLogger()
+
+/** Logging level */
+enum class LogLevel {
+ None,
+ Error,
+ Warn,
+ Info,
+ Verbose,
+ Debug,
+}
+
+/** Simple logging class. */
+class HostStubGenLogger(
+ private var out: PrintStream = System.out!!,
+ var level: LogLevel = LogLevel.Info,
+) {
+ companion object {
+ private val sNullPrintStream: PrintStream = PrintStream(OutputStream.nullOutputStream())
+ }
+
+ private var indentLevel: Int = 0
+ get() = field
+ set(value) {
+ field = value
+ indent = " ".repeat(value)
+ }
+ private var indent: String = ""
+
+ fun indent() {
+ indentLevel++
+ }
+
+ fun unindent() {
+ if (indentLevel <= 0) {
+ throw IllegalStateException("Unbalanced unindent() call.")
+ }
+ indentLevel--
+ }
+
+ inline fun <T> withIndent(block: () -> T): T {
+ try {
+ indent()
+ return block()
+ } finally {
+ unindent()
+ }
+ }
+
+ fun isEnabled(level: LogLevel): Boolean {
+ return level.ordinal <= this.level.ordinal
+ }
+
+ private fun println(message: String) {
+ out.print(indent)
+ out.println(message)
+ }
+
+ /** Log an error. */
+ fun e(message: String) {
+ if (level.ordinal < LogLevel.Error.ordinal) {
+ return
+ }
+ println(message)
+ }
+
+ /** Log an error. */
+ fun e(format: String, vararg args: Any?) {
+ if (level.ordinal < LogLevel.Error.ordinal) {
+ return
+ }
+ e(String.format(format, *args))
+ }
+
+ /** Log a warning. */
+ fun w(message: String) {
+ if (level.ordinal < LogLevel.Warn.ordinal) {
+ return
+ }
+ println(message)
+ }
+
+ /** Log a warning. */
+ fun w(format: String, vararg args: Any?) {
+ if (level.ordinal < LogLevel.Warn.ordinal) {
+ return
+ }
+ w(String.format(format, *args))
+ }
+
+ /** Log an info message. */
+ fun i(message: String) {
+ if (level.ordinal < LogLevel.Info.ordinal) {
+ return
+ }
+ println(message)
+ }
+
+ /** Log a debug message. */
+ fun i(format: String, vararg args: Any?) {
+ if (level.ordinal < LogLevel.Warn.ordinal) {
+ return
+ }
+ i(String.format(format, *args))
+ }
+
+ /** Log a verbose message. */
+ fun v(message: String) {
+ if (level.ordinal < LogLevel.Verbose.ordinal) {
+ return
+ }
+ println(message)
+ }
+
+ /** Log a verbose message. */
+ fun v(format: String, vararg args: Any?) {
+ if (level.ordinal < LogLevel.Verbose.ordinal) {
+ return
+ }
+ v(String.format(format, *args))
+ }
+
+ /** Log a debug message. */
+ fun d(message: String) {
+ if (level.ordinal < LogLevel.Debug.ordinal) {
+ return
+ }
+ println(message)
+ }
+
+ /** Log a debug message. */
+ fun d(format: String, vararg args: Any?) {
+ if (level.ordinal < LogLevel.Warn.ordinal) {
+ return
+ }
+ d(String.format(format, *args))
+ }
+
+ inline fun forVerbose(block: () -> Unit) {
+ if (isEnabled(LogLevel.Verbose)) {
+ block()
+ }
+ }
+
+ inline fun forDebug(block: () -> Unit) {
+ if (isEnabled(LogLevel.Debug)) {
+ block()
+ }
+ }
+
+ /** Return a stream for error. */
+ fun getErrorPrintStream(): PrintStream {
+ if (level.ordinal < LogLevel.Error.ordinal) {
+ return sNullPrintStream
+ }
+
+ // TODO Apply indent
+ return PrintStream(out)
+ }
+
+ /** Return a stream for verbose messages. */
+ fun getVerbosePrintStream(): PrintStream {
+ if (level.ordinal < LogLevel.Verbose.ordinal) {
+ return sNullPrintStream
+ }
+ // TODO Apply indent
+ return PrintStream(out)
+ }
+
+ /** Return a stream for debug messages. */
+ fun getInfoPrintStream(): PrintStream {
+ if (level.ordinal < LogLevel.Info.ordinal) {
+ return sNullPrintStream
+ }
+ // TODO Apply indent
+ return PrintStream(out)
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
new file mode 100644
index 000000000000..83f873d38f1b
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/HostStubGenOptions.kt
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+import com.android.hoststubgen.filters.FilterPolicy
+import java.io.BufferedReader
+import java.io.File
+import java.io.FileReader
+
+/**
+ * Options that can be set from command line arguments.
+ */
+class HostStubGenOptions(
+ /** Input jar file*/
+ var inJar: String = "",
+
+ /** Output stub jar file */
+ var outStubJar: String? = null,
+
+ /** Output implementation jar file */
+ var outImplJar: String? = null,
+
+ var inputJarDumpFile: String? = null,
+
+ var inputJarAsKeepAllFile: String? = null,
+
+ var stubAnnotations: MutableSet<String> = mutableSetOf(),
+ var keepAnnotations: MutableSet<String> = mutableSetOf(),
+ var throwAnnotations: MutableSet<String> = mutableSetOf(),
+ var removeAnnotations: MutableSet<String> = mutableSetOf(),
+ var stubClassAnnotations: MutableSet<String> = mutableSetOf(),
+ var keepClassAnnotations: MutableSet<String> = mutableSetOf(),
+
+ var substituteAnnotations: MutableSet<String> = mutableSetOf(),
+ var nativeSubstituteAnnotations: MutableSet<String> = mutableSetOf(),
+ var classLoadHookAnnotations: MutableSet<String> = mutableSetOf(),
+ var keepStaticInitializerAnnotations: MutableSet<String> = mutableSetOf(),
+
+ var packageRedirects: MutableList<Pair<String, String>> = mutableListOf(),
+
+ var annotationAllowedClassesFile: String? = null,
+
+ var defaultClassLoadHook: String? = null,
+ var defaultMethodCallHook: String? = null,
+
+ var intersectStubJars: MutableSet<String> = mutableSetOf(),
+
+ var policyOverrideFile: String? = null,
+
+ var defaultPolicy: FilterPolicy = FilterPolicy.Remove,
+ var keepAllClasses: Boolean = false,
+
+ var logLevel: LogLevel = LogLevel.Info,
+
+ var cleanUpOnError: Boolean = false,
+
+ var enableClassChecker: Boolean = false,
+ var enablePreTrace: Boolean = false,
+ var enablePostTrace: Boolean = false,
+
+ var enableNonStubMethodCallDetection: Boolean = false,
+) {
+ companion object {
+
+ private fun String.ensureFileExists(): String {
+ if (!File(this).exists()) {
+ throw InputFileNotFoundException(this)
+ }
+ return this
+ }
+
+ private fun parsePackageRedirect(fromColonTo: String): Pair<String, String> {
+ val colon = fromColonTo.indexOf(':')
+ if ((colon < 1) || (colon + 1 >= fromColonTo.length)) {
+ throw ArgumentsException("--package-redirect must be a colon-separated string")
+ }
+ // TODO check for duplicates
+ return Pair(fromColonTo.substring(0, colon), fromColonTo.substring(colon + 1))
+ }
+
+ fun parseArgs(args: Array<String>): HostStubGenOptions {
+ val ret = HostStubGenOptions()
+
+ val ai = ArgIterator(expandAtFiles(args))
+
+ var allAnnotations = mutableSetOf<String>()
+
+ fun ensureUniqueAnnotation(name: String): String {
+ if (!allAnnotations.add(name)) {
+ throw DuplicateAnnotationException(ai.current)
+ }
+ return name
+ }
+
+ while (true) {
+ val arg = ai.nextArgOptional()
+ if (arg == null) {
+ break
+ }
+
+ when (arg) {
+ // TODO: Write help
+ "-h", "--h" -> TODO("Help is not implemented yet")
+
+ "-v", "--verbose" -> ret.logLevel = LogLevel.Verbose
+ "-d", "--debug" -> ret.logLevel = LogLevel.Debug
+ "-q", "--quiet" -> ret.logLevel = LogLevel.None
+
+ "--in-jar" -> ret.inJar = ai.nextArgRequired(arg).ensureFileExists()
+ "--out-stub-jar" -> ret.outStubJar = ai.nextArgRequired(arg)
+ "--out-impl-jar" -> ret.outImplJar = ai.nextArgRequired(arg)
+
+ "--policy-override-file" ->
+ ret.policyOverrideFile = ai.nextArgRequired(arg).ensureFileExists()
+
+ "--clean-up-on-error" -> ret.cleanUpOnError = true
+ "--no-clean-up-on-error" -> ret.cleanUpOnError = false
+
+ "--default-remove" -> ret.defaultPolicy = FilterPolicy.Remove
+ "--default-throw" -> ret.defaultPolicy = FilterPolicy.Throw
+ "--default-keep" -> ret.defaultPolicy = FilterPolicy.Keep
+ "--default-stub" -> ret.defaultPolicy = FilterPolicy.Stub
+
+ "--keep-all-classes" -> ret.keepAllClasses = true
+ "--no-keep-all-classes" -> ret.keepAllClasses = false
+
+ "--stub-annotation" ->
+ ret.stubAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--keep-annotation" ->
+ ret.keepAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--stub-class-annotation" ->
+ ret.stubClassAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--keep-class-annotation" ->
+ ret.keepClassAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--throw-annotation" ->
+ ret.throwAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--remove-annotation" ->
+ ret.removeAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--substitute-annotation" ->
+ ret.substituteAnnotations += ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--native-substitute-annotation" ->
+ ret.nativeSubstituteAnnotations +=
+ ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--class-load-hook-annotation" ->
+ ret.classLoadHookAnnotations +=
+ ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--keep-static-initializer-annotation" ->
+ ret.keepStaticInitializerAnnotations +=
+ ensureUniqueAnnotation(ai.nextArgRequired(arg))
+
+ "--package-redirect" ->
+ ret.packageRedirects += parsePackageRedirect(ai.nextArgRequired(arg))
+
+ "--annotation-allowed-classes-file" ->
+ ret.annotationAllowedClassesFile = ai.nextArgRequired(arg)
+
+ "--default-class-load-hook" ->
+ ret.defaultClassLoadHook = ai.nextArgRequired(arg)
+
+ "--default-method-call-hook" ->
+ ret.defaultMethodCallHook = ai.nextArgRequired(arg)
+
+ "--intersect-stub-jar" ->
+ ret.intersectStubJars += ai.nextArgRequired(arg).ensureFileExists()
+
+ "--gen-keep-all-file" ->
+ ret.inputJarAsKeepAllFile = ai.nextArgRequired(arg)
+
+ // Following options are for debugging.
+ "--enable-class-checker" -> ret.enableClassChecker = true
+ "--no-class-checker" -> ret.enableClassChecker = false
+
+ "--enable-pre-trace" -> ret.enablePreTrace = true
+ "--no-pre-trace" -> ret.enablePreTrace = false
+
+ "--enable-post-trace" -> ret.enablePostTrace = true
+ "--no-post-trace" -> ret.enablePostTrace = false
+
+ "--enable-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = true
+ "--no-non-stub-method-check" -> ret.enableNonStubMethodCallDetection = false
+
+ "--gen-input-dump-file" -> ret.inputJarDumpFile = ai.nextArgRequired(arg)
+
+ else -> throw ArgumentsException("Unknown option: $arg")
+ }
+ }
+ if (ret.inJar.isEmpty()) {
+ throw ArgumentsException("Required option missing: --in-jar")
+ }
+ if (ret.outStubJar == null && ret.outImplJar == null) {
+ log.w("Neither --out-stub-jar nor --out-impl-jar is set." +
+ " $COMMAND_NAME will not generate jar files.")
+ }
+
+ if (ret.enableNonStubMethodCallDetection) {
+ log.w("--enable-non-stub-method-check is not fully implemented yet." +
+ " See the todo in doesMethodNeedNonStubCallCheck().")
+ }
+
+ return ret
+ }
+
+ /**
+ * Scan the arguments, and if any of them starts with an `@`, then load from the file
+ * and use its content as arguments.
+ *
+ * In this file, each line is treated as a single argument.
+ *
+ * The file can contain '#' as comments.
+ */
+ private fun expandAtFiles(args: Array<String>): List<String> {
+ val ret = mutableListOf<String>()
+
+ args.forEach { arg ->
+ if (!arg.startsWith('@')) {
+ ret += arg
+ return@forEach
+ }
+ // Read from the file, and add each line to the result.
+ val filename = arg.substring(1).ensureFileExists()
+
+ log.v("Expanding options file $filename")
+
+ BufferedReader(FileReader(filename)).use { reader ->
+ while (true) {
+ var line = reader.readLine()
+ if (line == null) {
+ break // EOF
+ }
+
+ line = normalizeTextLine(line)
+ if (line.isNotEmpty()) {
+ ret += line
+ }
+ }
+ }
+ }
+ return ret
+ }
+ }
+
+ open class ArgumentsException(message: String?) : Exception(message), UserErrorException
+
+ /** Thrown when the same annotation is used with different annotation arguments. */
+ class DuplicateAnnotationException(annotationName: String?) :
+ ArgumentsException("Duplicate annotation specified: '$annotationName'")
+
+ /** Thrown when an input file does not exist. */
+ class InputFileNotFoundException(filename: String) :
+ ArgumentsException("File '$filename' not found")
+
+ private class ArgIterator(
+ private val args: List<String>,
+ private var currentIndex: Int = -1
+ ) {
+ val current: String
+ get() = args.get(currentIndex)
+
+ /**
+ * Get the next argument, or [null] if there's no more arguments.
+ */
+ fun nextArgOptional(): String? {
+ if ((currentIndex + 1) >= args.size) {
+ return null
+ }
+ return args.get(++currentIndex)
+ }
+
+ /**
+ * Get the next argument, or throw if
+ */
+ fun nextArgRequired(argName: String): String {
+ nextArgOptional().let {
+ if (it == null) {
+ throw ArgumentsException("Missing parameter for option $argName")
+ }
+ if (it.isEmpty()) {
+ throw ArgumentsException("Parameter can't be empty for option $argName")
+ }
+ return it
+ }
+ }
+ }
+
+ override fun toString(): String {
+ return """
+ HostStubGenOptions{
+ inJar='$inJar',
+ outStubJar='$outStubJar',
+ outImplJar='$outImplJar',
+ inputJarDumpFile=$inputJarDumpFile,
+ inputJarAsKeepAllFile=$inputJarAsKeepAllFile,
+ stubAnnotations=$stubAnnotations,
+ keepAnnotations=$keepAnnotations,
+ throwAnnotations=$throwAnnotations,
+ removeAnnotations=$removeAnnotations,
+ stubClassAnnotations=$stubClassAnnotations,
+ keepClassAnnotations=$keepClassAnnotations,
+ substituteAnnotations=$substituteAnnotations,
+ nativeSubstituteAnnotations=$nativeSubstituteAnnotations,
+ classLoadHookAnnotations=$classLoadHookAnnotations,
+ keepStaticInitializerAnnotations=$keepStaticInitializerAnnotations,
+ packageRedirects=$packageRedirects,
+ $annotationAllowedClassesFile=$annotationAllowedClassesFile,
+ defaultClassLoadHook=$defaultClassLoadHook,
+ defaultMethodCallHook=$defaultMethodCallHook,
+ intersectStubJars=$intersectStubJars,
+ policyOverrideFile=$policyOverrideFile,
+ defaultPolicy=$defaultPolicy,
+ keepAllClasses=$keepAllClasses,
+ logLevel=$logLevel,
+ cleanUpOnError=$cleanUpOnError,
+ enableClassChecker=$enableClassChecker,
+ enablePreTrace=$enablePreTrace,
+ enablePostTrace=$enablePostTrace,
+ enableNonStubMethodCallDetection=$enableNonStubMethodCallDetection,
+ }
+ """.trimIndent()
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt
new file mode 100644
index 000000000000..0321d9db03ed
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Main.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+@file:JvmName("Main")
+
+package com.android.hoststubgen
+
+const val COMMAND_NAME = "HostStubGen"
+
+/**
+ * Entry point.
+ */
+fun main(args: Array<String>) {
+ var success = false
+ var clanupOnError = false
+ try {
+ // Parse the command line arguments.
+ val options = HostStubGenOptions.parseArgs(args)
+ clanupOnError = options.cleanUpOnError
+
+ log.level = options.logLevel
+
+ log.v("HostStubGen started")
+ log.v("Options: $options")
+
+ // Run.
+ HostStubGen(options).run()
+
+ success = true
+ } catch (e: Exception) {
+ log.e("$COMMAND_NAME: Error: ${e.message}")
+ if (e !is UserErrorException) {
+ e.printStackTrace(log.getErrorPrintStream())
+ }
+ if (clanupOnError) {
+ TODO("clanupOnError is not implemented yet")
+ }
+ }
+
+ log.v("HostStubGen finished")
+
+ System.exit(if (success) 0 else 1 )
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt
new file mode 100644
index 000000000000..937e56c2cbb5
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/Utils.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen
+
+/**
+ * A regex that maches whitespate.
+ */
+val whitespaceRegex = """\s+""".toRegex()
+
+/**
+ * Remove the comment ('#' and following) and surrounding whitespace from a line.
+ */
+fun normalizeTextLine(s: String): String {
+ // Remove # and after. (comment)
+ val pos = s.indexOf('#')
+ val uncommented = if (pos < 0) s else s.substring(0, pos)
+
+ // Remove surrounding whitespace.
+ return uncommented.trim()
+}
+
+/**
+ * Concatenate list [a] and [b] and return it. As an optimization, it returns an input
+ * [List] as-is if the other [List] is empty, so do not modify input [List]'s.
+ */
+fun <T> addLists(a: List<T>, b: List<T>): List<T> {
+ if (a.isEmpty()) {
+ return b
+ }
+ if (b.isEmpty()) {
+ return a
+ }
+ return a + b
+}
+
+/**
+ * Add element [b] to list [a] if [b] is not null. Otherwise, just return [a].
+ * (because the method may return [a] as-is, do not modify it after passing it.)
+ */
+fun <T> addNonNullElement(a: List<T>, b: T?): List<T> {
+ if (b == null) {
+ return a
+ }
+ if (a.isEmpty()) {
+ return listOf(b)
+ }
+ return a + b
+}
+
+
+/**
+ * Exception for a parse error in a file
+ */
+class ParseException : Exception, UserErrorException {
+ val hasSourceInfo: Boolean
+
+ constructor(message: String) : super(message) {
+ hasSourceInfo = false
+ }
+
+ constructor(message: String, file: String, line: Int) :
+ super("$message in file $file line $line") {
+ hasSourceInfo = true
+ }
+
+ fun withSourceInfo(filename: String, lineNo: Int): ParseException {
+ if (hasSourceInfo) {
+ return this // Already has source information.
+ } else {
+ return ParseException(this.message ?: "", filename, lineNo)
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
new file mode 100644
index 000000000000..d7aa0af13ce2
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/AsmUtils.kt
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.asm
+
+import com.android.hoststubgen.ClassParseException
+import com.android.hoststubgen.HostStubGenInternalException
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Type
+import org.objectweb.asm.tree.AnnotationNode
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.FieldNode
+import org.objectweb.asm.tree.MethodNode
+
+
+/** Name of the class initializer method. */
+val CLASS_INITIALIZER_NAME = "<clinit>"
+
+/** Descriptor of the class initializer method. */
+val CLASS_INITIALIZER_DESC = "()V"
+
+/**
+ * Find any of [anyAnnotations] from the list of visible / invisible annotations.
+ */
+fun findAnyAnnotation(
+ anyAnnotations: Set<String>,
+ visibleAnnotations: List<AnnotationNode>?,
+ invisibleAnnotations: List<AnnotationNode>?,
+ ): AnnotationNode? {
+ for (an in visibleAnnotations ?: emptyList()) {
+ if (anyAnnotations.contains(an.desc)) {
+ return an
+ }
+ }
+ for (an in invisibleAnnotations ?: emptyList()) {
+ if (anyAnnotations.contains(an.desc)) {
+ return an
+ }
+ }
+ return null
+}
+
+fun findAnnotationValueAsString(an: AnnotationNode, propertyName: String): String? {
+ for (i in 0..(an.values?.size ?: 0) - 2 step 2) {
+ val name = an.values[i]
+
+ if (name != propertyName) {
+ continue
+ }
+ val value = an.values[i + 1]
+ if (value is String) {
+ return value
+ }
+ throw ClassParseException(
+ "The type of '$name' in annotation \"${an.desc}\" must be String" +
+ ", but is ${value?.javaClass?.canonicalName}")
+ }
+ return null
+}
+
+private val removeLastElement = """[./][^./]*$""".toRegex()
+
+fun getPackageNameFromClassName(className: String): String {
+ return className.replace(removeLastElement, "")
+}
+
+fun resolveClassName(className: String, packageName: String): String {
+ if (className.contains('.') || className.contains('/')) {
+ return className
+ }
+ return "$packageName.$className"
+}
+
+fun String.toJvmClassName(): String {
+ return this.replace('.', '/')
+}
+
+fun String.toHumanReadableClassName(): String {
+ return this.replace('/', '.')
+}
+
+fun String.toHumanReadableMethodName(): String {
+ return this.replace('/', '.')
+}
+
+private val numericalInnerClassName = """.*\$\d+$""".toRegex()
+
+fun isAnonymousInnerClass(cn: ClassNode): Boolean {
+ // TODO: Is there a better way?
+ return cn.name.matches(numericalInnerClassName)
+}
+
+/**
+ * Take a class name. If it's a nested class, then return the name of its direct outer class name.
+ * Otherwise, return null.
+ */
+fun getDirectOuterClassName(className: String): String? {
+ val pos = className.indexOf('$')
+ if (pos < 0) {
+ return null
+ }
+ return className.substring(0, pos)
+}
+
+/**
+ * Write bytecode to push all the method arguments to the stack.
+ * The number of arguments and their type are taken from [methodDescriptor].
+ */
+fun writeByteCodeToPushArguments(
+ methodDescriptor: String,
+ writer: MethodVisitor,
+ argOffset: Int = 0,
+ ) {
+ var i = argOffset - 1
+ Type.getArgumentTypes(methodDescriptor).forEach { type ->
+ i++
+
+ // See https://en.wikipedia.org/wiki/List_of_Java_bytecode_instructions
+
+ // Note, long and double will consume two local variable spaces, so the extra `i++`.
+ when (type) {
+ Type.VOID_TYPE -> throw HostStubGenInternalException("VOID_TYPE not expected")
+ Type.BOOLEAN_TYPE, Type.INT_TYPE, Type.SHORT_TYPE, Type.CHAR_TYPE
+ -> writer.visitVarInsn(Opcodes.ILOAD, i)
+ Type.LONG_TYPE -> writer.visitVarInsn(Opcodes.LLOAD, i++)
+ Type.FLOAT_TYPE -> writer.visitVarInsn(Opcodes.FLOAD, i)
+ Type.DOUBLE_TYPE -> writer.visitVarInsn(Opcodes.DLOAD, i++)
+ else -> writer.visitVarInsn(Opcodes.ALOAD, i)
+ }
+ }
+}
+
+/**
+ * Write bytecode to "RETURN" that matches the method's return type, according to
+ * [methodDescriptor].
+ */
+fun writeByteCodeToReturn(methodDescriptor: String, writer: MethodVisitor) {
+ Type.getReturnType(methodDescriptor).let { type ->
+ // See https://en.wikipedia.org/wiki/List_of_Java_bytecode_instructions
+ when (type) {
+ Type.VOID_TYPE -> writer.visitInsn(Opcodes.RETURN)
+ Type.BOOLEAN_TYPE, Type.INT_TYPE, Type.SHORT_TYPE, Type.CHAR_TYPE
+ -> writer.visitInsn(Opcodes.IRETURN)
+ Type.LONG_TYPE -> writer.visitInsn(Opcodes.LRETURN)
+ Type.FLOAT_TYPE -> writer.visitInsn(Opcodes.FRETURN)
+ Type.DOUBLE_TYPE -> writer.visitInsn(Opcodes.DRETURN)
+ else -> writer.visitInsn(Opcodes.ARETURN)
+ }
+ }
+}
+
+/**
+ * Given a method descriptor, insert an [argType] as the first argument to it.
+ */
+fun prependArgTypeToMethodDescriptor(methodDescriptor: String, argType: Type): String {
+ val returnType = Type.getReturnType(methodDescriptor)
+ val argTypes = Type.getArgumentTypes(methodDescriptor).toMutableList()
+
+ argTypes.add(0, argType)
+
+ return Type.getMethodDescriptor(returnType, *argTypes.toTypedArray())
+}
+
+/**
+ * Return the "visibility" modifier from an `access` integer.
+ *
+ * (see https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.1-200-E.1)
+ */
+fun getVisibilityModifier(access: Int): Int {
+ return access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED)
+}
+
+/**
+ * Return true if an `access` integer is "private" or "package private".
+ */
+fun isVisibilityPrivateOrPackagePrivate(access: Int): Boolean {
+ return when (getVisibilityModifier(access)) {
+ 0 -> true // Package private.
+ Opcodes.ACC_PRIVATE -> true
+ else -> false
+ }
+}
+
+fun ClassNode.isEnum(): Boolean {
+ return (this.access and Opcodes.ACC_ENUM) != 0
+}
+
+fun ClassNode.isAnnotation(): Boolean {
+ return (this.access and Opcodes.ACC_ANNOTATION) != 0
+}
+
+fun ClassNode.isSynthetic(): Boolean {
+ return (this.access and Opcodes.ACC_SYNTHETIC) != 0
+}
+
+fun MethodNode.isSynthetic(): Boolean {
+ return (this.access and Opcodes.ACC_SYNTHETIC) != 0
+}
+
+fun FieldNode.isEnum(): Boolean {
+ return (this.access and Opcodes.ACC_ENUM) != 0
+}
+
+fun FieldNode.isSynthetic(): Boolean {
+ return (this.access and Opcodes.ACC_SYNTHETIC) != 0
+}
+
+/*
+
+Dump of the members of TinyFrameworkEnumSimple:
+
+class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple keep
+ field Cat keep (ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM)
+ field Dog keep
+ field $VALUES keep (ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC)
+
+ method values ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple; keep
+ ^- NOT synthetic (ACC_PUBLIC, ACC_STATIC)
+ method valueOf (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple; keep
+ ^- NOT synthetic (ACC_PUBLIC, ACC_STATIC)
+ method <init> (Ljava/lang/String;I)V keep
+ ^- NOT synthetic (ACC_PRIVATE)
+
+ method $values ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple; keep
+ (ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC)
+ method <clinit> ()V keep
+
+Dump of the members of TinyFrameworkEnumSimple:
+
+class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex keep
+ field RED keep
+ field BLUE keep
+ field GREEN keep
+ field mLongName keep
+ field mShortName keep
+ field $VALUES keep
+ method values ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex; keep
+ method valueOf (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex; keep
+ method <init> (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V keep
+ method getLongName ()Ljava/lang/String; keep
+ method getShortName ()Ljava/lang/String; keep
+ method $values ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex; keep
+ method <clinit> ()V keep
+
+ */
+
+fun isAutoGeneratedEnumMember(mn: MethodNode): Boolean {
+ if (mn.isSynthetic()) {
+ return true
+ }
+ if (mn.name == "<init>" && mn.desc == "(Ljava/lang/String;I)V") {
+ return true
+ }
+ if (mn.name == "<clinit>" && mn.desc == "()V") {
+ return true
+ }
+ if (mn.name == "values" && mn.desc.startsWith("()")) {
+ return true
+ }
+ if (mn.name == "valueOf" && mn.desc.startsWith("(Ljava/lang/String;)")) {
+ return true
+ }
+
+ return false
+}
+
+fun isAutoGeneratedEnumMember(fn: FieldNode): Boolean {
+ if (fn.isSynthetic() || fn.isEnum()) {
+ return true
+ }
+ return false
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt
new file mode 100644
index 000000000000..4df0bfc4a8d1
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/asm/ClassNodes.kt
@@ -0,0 +1,149 @@
+package com.android.hoststubgen.asm
+
+import com.android.hoststubgen.ClassParseException
+import org.objectweb.asm.tree.AnnotationNode
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.FieldNode
+import org.objectweb.asm.tree.MethodNode
+import org.objectweb.asm.tree.TypeAnnotationNode
+import java.io.PrintWriter
+import java.util.Arrays
+
+/**
+ * Stores all classes loaded from a jar file, in a form of [ClassNode]
+ */
+class ClassNodes {
+ val mAllClasses: MutableMap<String, ClassNode> = HashMap()
+
+ /**
+ * Total number of classes registered.
+ */
+ val size: Int
+ get() = mAllClasses.size
+
+ /** Add a [ClassNode] */
+ fun addClass(cn: ClassNode): Boolean {
+ if (mAllClasses.containsKey(cn.name)) {
+ return false
+ }
+ mAllClasses[cn.name.toJvmClassName()] = cn
+ return true
+ }
+
+ /** Get a class's [ClassNodes] (which may not exist) */
+ fun findClass(name: String): ClassNode? {
+ return mAllClasses[name.toJvmClassName()]
+ }
+
+ /** Get a class's [ClassNodes] (which must exists) */
+ fun getClass(name: String): ClassNode {
+ return findClass(name) ?: throw ClassParseException("Class $name not found")
+ }
+
+ /** Find a field, which may not exist. */
+ fun findField(
+ className: String,
+ fieldName: String,
+ ): FieldNode? {
+ return findClass(className)?.fields?.firstOrNull { it.name == fieldName }?.let { fn ->
+ return fn
+ }
+ }
+
+ /** Find a method, which may not exist. */
+ fun findMethod(
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): MethodNode? {
+ return findClass(className)?.methods
+ ?.firstOrNull { it.name == methodName && it.desc == descriptor }?.let { mn ->
+ return mn
+ }
+ }
+
+ /** @return true if a class has a class initializer. */
+ fun hasClassInitializer(className: String): Boolean {
+ return findMethod(className, CLASS_INITIALIZER_NAME, CLASS_INITIALIZER_DESC) != null
+ }
+
+ /** Run the lambda on each class in alphabetical order. */
+ fun forEach(consumer: (classNode: ClassNode) -> Unit) {
+ val keys = mAllClasses.keys.toTypedArray()
+ Arrays.sort(keys)
+
+ for (name in keys) {
+ consumer(mAllClasses[name]!!)
+ }
+ }
+
+ /**
+ * Dump all classes.
+ */
+ fun dump(pw: PrintWriter) {
+ forEach { classNode -> dumpClass(pw, classNode) }
+ }
+
+ private fun dumpClass(pw: PrintWriter, cn: ClassNode) {
+ pw.printf("Class: %s [access: %x]\n", cn.name, cn.access)
+ dumpAnnotations(pw, " ",
+ cn.visibleTypeAnnotations, cn.invisibleTypeAnnotations,
+ cn.visibleAnnotations, cn.invisibleAnnotations,
+ )
+
+ for (f in cn.fields ?: emptyList()) {
+ pw.printf(" Field: %s [sig: %s] [desc: %s] [access: %x]\n",
+ f.name, f.signature, f.desc, f.access)
+ dumpAnnotations(pw, " ",
+ f.visibleTypeAnnotations, f.invisibleTypeAnnotations,
+ f.visibleAnnotations, f.invisibleAnnotations,
+ )
+ }
+ for (m in cn.methods ?: emptyList()) {
+ pw.printf(" Method: %s [sig: %s] [desc: %s] [access: %x]\n",
+ m.name, m.signature, m.desc, m.access)
+ dumpAnnotations(pw, " ",
+ m.visibleTypeAnnotations, m.invisibleTypeAnnotations,
+ m.visibleAnnotations, m.invisibleAnnotations,
+ )
+ }
+ }
+
+ private fun dumpAnnotations(
+ pw: PrintWriter,
+ prefix: String,
+ visibleTypeAnnotations: List<TypeAnnotationNode>?,
+ invisibleTypeAnnotations: List<TypeAnnotationNode>?,
+ visibleAnnotations: List<AnnotationNode>?,
+ invisibleAnnotations: List<AnnotationNode>?,
+ ) {
+ for (an in visibleTypeAnnotations ?: emptyList()) {
+ pw.printf("%sTypeAnnotation(vis): %s\n", prefix, an.desc)
+ }
+ for (an in invisibleTypeAnnotations ?: emptyList()) {
+ pw.printf("%sTypeAnnotation(inv): %s\n", prefix, an.desc)
+ }
+ for (an in visibleAnnotations ?: emptyList()) {
+ pw.printf("%sAnnotation(vis): %s\n", prefix, an.desc)
+ if (an.values == null) {
+ continue
+ }
+ var i = 0
+ while (i < an.values.size - 1) {
+ pw.printf("%s - %s -> %s \n", prefix, an.values[i], an.values[i + 1])
+ i += 2
+ }
+ }
+ for (an in invisibleAnnotations ?: emptyList()) {
+ pw.printf("%sAnnotation(inv): %s\n", prefix, an.desc)
+ if (an.values == null) {
+ continue
+ }
+ var i = 0
+ while (i < an.values.size - 1) {
+ pw.printf("%s - %s -> %s \n", prefix, an.values[i], an.values[i + 1])
+ i += 2
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
new file mode 100644
index 000000000000..248121c63d78
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/AnnotationBasedFilter.kt
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.ClassParseException
+import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.HostStubGenInternalException
+import com.android.hoststubgen.InvalidAnnotationException
+import com.android.hoststubgen.addNonNullElement
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_DESC
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.findAnnotationValueAsString
+import com.android.hoststubgen.asm.findAnyAnnotation
+import com.android.hoststubgen.asm.toHumanReadableClassName
+import com.android.hoststubgen.asm.toHumanReadableMethodName
+import com.android.hoststubgen.asm.toJvmClassName
+import com.android.hoststubgen.log
+import com.android.hoststubgen.utils.ClassFilter
+import org.objectweb.asm.tree.AnnotationNode
+import org.objectweb.asm.tree.ClassNode
+
+// TODO: Detect invalid cases, such as...
+// - Class's visibility is lower than the members'.
+// - HostSideTestSubstituteWith is set, but it doesn't have @Stub or @Keep
+
+/**
+ * [OutputFilter] using Java annotations.
+ */
+class AnnotationBasedFilter(
+ private val errors: HostStubGenErrors,
+ private val classes: ClassNodes,
+ stubAnnotations_: Set<String>,
+ keepAnnotations_: Set<String>,
+ stubClassAnnotations_: Set<String>,
+ keepClassAnnotations_: Set<String>,
+ throwAnnotations_: Set<String>,
+ removeAnnotations_: Set<String>,
+ substituteAnnotations_: Set<String>,
+ nativeSubstituteAnnotations_: Set<String>,
+ classLoadHookAnnotations_: Set<String>,
+ keepStaticInitializerAnnotations_: Set<String>,
+ private val annotationAllowedClassesFilter: ClassFilter,
+ fallback: OutputFilter,
+) : DelegatingFilter(fallback) {
+ private var stubAnnotations = convertToInternalNames(stubAnnotations_)
+ private var keepAnnotations = convertToInternalNames(keepAnnotations_)
+ private var stubClassAnnotations = convertToInternalNames(stubClassAnnotations_)
+ private var keepClassAnnotations = convertToInternalNames(keepClassAnnotations_)
+ private var throwAnnotations = convertToInternalNames(throwAnnotations_)
+ private var removeAnnotations = convertToInternalNames(removeAnnotations_)
+ private var substituteAnnotations = convertToInternalNames(substituteAnnotations_)
+ private var nativeSubstituteAnnotations = convertToInternalNames(nativeSubstituteAnnotations_)
+ private var classLoadHookAnnotations = convertToInternalNames(classLoadHookAnnotations_)
+ private var keepStaticInitializerAnnotations =
+ convertToInternalNames(keepStaticInitializerAnnotations_)
+
+ /** Annotations that control API visibility. */
+ private var visibilityAnnotations: Set<String> = convertToInternalNames(
+ stubAnnotations_ +
+ keepAnnotations_ +
+ stubClassAnnotations_ +
+ keepClassAnnotations_ +
+ throwAnnotations_ +
+ removeAnnotations_)
+
+ /**
+ * All the annotations we use. Note, this one is in a [convertToJvmNames] format unlike
+ * other ones, because of how it's used.
+ */
+ private var allAnnotations: Set<String> = convertToJvmNames(
+ stubAnnotations_ +
+ keepAnnotations_ +
+ stubClassAnnotations_ +
+ keepClassAnnotations_ +
+ throwAnnotations_ +
+ removeAnnotations_ +
+ substituteAnnotations_ +
+ nativeSubstituteAnnotations_ +
+ classLoadHookAnnotations_)
+
+ private val substitutionHelper = SubstitutionHelper()
+
+ private val reasonAnnotation = "annotation"
+ private val reasonClassAnnotation = "class-annotation"
+
+ /**
+ * Throw if an item has more than one visibility annotations.
+ *
+ * name1 - 4 are only used in exception messages. We take them as separate strings
+ * to avoid unnecessary string concatenations.
+ */
+ private fun detectInvalidAnnotations(
+ visibles: List<AnnotationNode>?,
+ invisibles: List<AnnotationNode>?,
+ type: String,
+ name1: String,
+ name2: String,
+ name3: String,
+ ) {
+ var count = 0
+ for (an in visibles ?: emptyList()) {
+ if (visibilityAnnotations.contains(an.desc)) {
+ count++
+ }
+ }
+ for (an in invisibles ?: emptyList()) {
+ if (visibilityAnnotations.contains(an.desc)) {
+ count++
+ }
+ }
+ if (count > 1) {
+ val description = if (name2 == "" && name3 == "") {
+ "$type $name1"
+ } else {
+ "$type $name1.$name2$name3"
+ }
+ throw InvalidAnnotationException(
+ "Found more than one visibility annotations on $description")
+ }
+ }
+
+ fun findAnyAnnotation(
+ className: String,
+ anyAnnotations: Set<String>,
+ visibleAnnotations: List<AnnotationNode>?,
+ invisibleAnnotations: List<AnnotationNode>?,
+ ): AnnotationNode? {
+ val ret = findAnyAnnotation(anyAnnotations, visibleAnnotations, invisibleAnnotations)
+
+ if (ret != null) {
+ if (!annotationAllowedClassesFilter.matches(className)) {
+ throw InvalidAnnotationException(
+ "Class ${className.toHumanReadableClassName()} is not allowed to have " +
+ "Ravenwood annotations. Contact g/ravenwood for more details.")
+ }
+ }
+
+ return ret
+ }
+
+ /**
+ * Find a visibility annotation.
+ *
+ * name1 - 4 are only used in exception messages.
+ */
+ private fun findAnnotation(
+ className: String,
+ visibles: List<AnnotationNode>?,
+ invisibles: List<AnnotationNode>?,
+ type: String,
+ name1: String,
+ name2: String = "",
+ name3: String = "",
+ ): FilterPolicyWithReason? {
+ detectInvalidAnnotations(visibles, invisibles, type, name1, name2, name3)
+
+ findAnyAnnotation(className, stubAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.Stub.withReason(reasonAnnotation)
+ }
+ findAnyAnnotation(className, stubClassAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.StubClass.withReason(reasonClassAnnotation)
+ }
+ findAnyAnnotation(className, keepAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.Keep.withReason(reasonAnnotation)
+ }
+ findAnyAnnotation(className, keepClassAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.KeepClass.withReason(reasonClassAnnotation)
+ }
+ findAnyAnnotation(className, throwAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.Throw.withReason(reasonAnnotation)
+ }
+ findAnyAnnotation(className, removeAnnotations, visibles, invisibles)?.let {
+ return FilterPolicy.Remove.withReason(reasonAnnotation)
+ }
+
+ return null
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ val cn = classes.getClass(className)
+
+ findAnnotation(
+ cn.name,
+ cn.visibleAnnotations,
+ cn.invisibleAnnotations,
+ "class",
+ className)?.let {
+ return it
+ }
+
+ // If it's any of the annotations, then always keep it.
+ if (allAnnotations.contains(className)) {
+ return FilterPolicy.KeepClass.withReason("HostStubGen Annotation")
+ }
+
+ return super.getPolicyForClass(className)
+ }
+
+ override fun getPolicyForField(
+ className: String,
+ fieldName: String
+ ): FilterPolicyWithReason {
+ val cn = classes.getClass(className)
+
+ cn.fields?.firstOrNull { it.name == fieldName }?.let {fn ->
+ findAnnotation(
+ cn.name,
+ fn.visibleAnnotations,
+ fn.invisibleAnnotations,
+ "field",
+ className,
+ fieldName
+ )?.let { policy ->
+ // If the item has an annotation, then use it.
+ return policy
+ }
+ }
+ return super.getPolicyForField(className, fieldName)
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): FilterPolicyWithReason {
+ val cn = classes.getClass(className)
+
+ if (methodName == CLASS_INITIALIZER_NAME && descriptor == CLASS_INITIALIZER_DESC) {
+ findAnyAnnotation(cn.name, keepStaticInitializerAnnotations,
+ cn.visibleAnnotations, cn.invisibleAnnotations)?.let {
+ return FilterPolicy.Keep.withReason(reasonAnnotation)
+ }
+ }
+
+ cn.methods?.firstOrNull { it.name == methodName && it.desc == descriptor }?.let { mn ->
+ // @SubstituteWith is going to complicate the policy here, so we ask helper
+ // what to do.
+ substitutionHelper.getPolicyFromSubstitution(cn, mn.name, mn.desc)?.let {
+ return it
+ }
+
+ // If there's no substitution, then we check the annotation.
+ findAnnotation(
+ cn.name,
+ mn.visibleAnnotations,
+ mn.invisibleAnnotations,
+ "method",
+ className,
+ methodName,
+ descriptor
+ )?.let { policy ->
+ return policy
+ }
+ }
+ return super.getPolicyForMethod(className, methodName, descriptor)
+ }
+
+ override fun getRenameTo(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): String? {
+ val cn = classes.getClass(className)
+
+ // If the method has a "substitute with" annotation, then return its "value" parameter.
+ cn.methods?.firstOrNull { it.name == methodName && it.desc == descriptor }?.let { mn ->
+ return substitutionHelper.getRenameTo(cn, mn.name, mn.desc)
+ }
+ return null
+ }
+
+ override fun getNativeSubstitutionClass(className: String): String? {
+ classes.getClass(className).let { cn ->
+ findAnyAnnotation(nativeSubstituteAnnotations,
+ cn.visibleAnnotations, cn.invisibleAnnotations)?.let { an ->
+ return getAnnotationField(an, "value")?.toJvmClassName()
+ }
+ }
+ return null
+ }
+
+ override fun getClassLoadHooks(className: String): List<String> {
+ val e = classes.getClass(className).let { cn ->
+ findAnyAnnotation(classLoadHookAnnotations,
+ cn.visibleAnnotations, cn.invisibleAnnotations)?.let { an ->
+ getAnnotationField(an, "value")?.toHumanReadableMethodName()
+ }
+ }
+ return addNonNullElement(super.getClassLoadHooks(className), e)
+ }
+
+ private data class MethodKey(val name: String, val desc: String)
+
+ /**
+ * In order to handle substitution, we need to build a reverse mapping of substitution
+ * methods.
+ *
+ * This class automatically builds such a map internally that the above methods can
+ * take advantage of.
+ */
+ private inner class SubstitutionHelper {
+ private var currentClass: ClassNode? = null
+
+ private var policiesFromSubstitution = mutableMapOf<MethodKey, FilterPolicyWithReason>()
+ private var substituteToMethods = mutableMapOf<MethodKey, String>()
+
+ fun getPolicyFromSubstitution(cn: ClassNode, methodName: String, descriptor: String):
+ FilterPolicyWithReason? {
+ setClass(cn)
+ return policiesFromSubstitution[MethodKey(methodName, descriptor)]
+ }
+
+ fun getRenameTo(cn: ClassNode, methodName: String, descriptor: String): String? {
+ setClass(cn)
+ return substituteToMethods[MethodKey(methodName, descriptor)]
+ }
+
+ /**
+ * Every time we see a different class, we scan all its methods for substitution attributes,
+ * and compute (implicit) policies caused by them.
+ *
+ * For example, for the following methods:
+ *
+ * @Stub
+ * @Substitute(suffix = "_host")
+ * private void foo() {
+ * // This isn't supported on the host side.
+ * }
+ * private void foo_host() {
+ * // Host side implementation
+ * }
+ *
+ * We internally handle them as:
+ *
+ * foo() -> Remove
+ * foo_host() -> Stub, and then rename it to foo().
+ */
+ private fun setClass(cn: ClassNode) {
+ if (currentClass == cn) {
+ return
+ }
+ // If the class is changing, we'll rebuild the internal structure.
+ currentClass = cn
+
+ policiesFromSubstitution.clear()
+ substituteToMethods.clear()
+
+ for (mn in cn.methods ?: emptyList()) {
+ findAnyAnnotation(substituteAnnotations,
+ mn.visibleAnnotations,
+ mn.invisibleAnnotations)?.let { an ->
+
+ // Find the policy for this method.
+ val policy = outermostFilter.getPolicyForMethod(cn.name, mn.name, mn.desc)
+ .policy.resolveClassWidePolicy()
+ // Make sure it's either Stub or Keep.
+ if (!(policy.needsInStub || policy.needsInImpl)) {
+ // TODO: Use the real annotation names in the message
+ errors.onErrorFound("@SubstituteWith must have either @Stub or @Keep")
+ return@let
+ }
+ if (!policy.isUsableWithMethods) {
+ throw HostStubGenInternalException("Policy $policy shouldn't show up here")
+ }
+
+ val suffix = getAnnotationField(an, "suffix", false) ?: "\$ravenwood"
+ val renameFrom = mn.name + suffix
+ val renameTo = mn.name
+
+ if (renameFrom == renameTo) {
+ errors.onErrorFound("@SubstituteWith have a different name")
+ return@let
+ }
+
+ // This mn has "SubstituteWith". This means,
+ // 1. Re move the "rename-to" method, so add it to substitutedMethods.
+ policiesFromSubstitution[MethodKey(renameTo, mn.desc)] =
+ FilterPolicy.Remove.withReason("substitute-to")
+
+ // If the policy is "stub", use "stub".
+ // Otherwise, it must be "keep" or "throw", but there's no point in using
+ // "throw", so let's use "keep".
+ val newPolicy = if (policy.needsInStub) policy else FilterPolicy.Keep
+ // 2. We also keep the from-to in the map.
+ policiesFromSubstitution[MethodKey(renameFrom, mn.desc)] =
+ newPolicy.withReason("substitute-from")
+ substituteToMethods[MethodKey(renameFrom, mn.desc)] = renameTo
+
+ log.v("Substitution found: %s%s -> %s", renameFrom, mn.desc, renameTo)
+ }
+ }
+ }
+ }
+
+ /**
+ * Return the (String) value of 'value' parameter from an annotation.
+ */
+ private fun getAnnotationField(an: AnnotationNode, name: String,
+ required: Boolean = true): String? {
+ try {
+ val suffix = findAnnotationValueAsString(an, name)
+ if (suffix == null && required) {
+ errors.onErrorFound("Annotation \"${an.desc}\" must have field $name")
+ }
+ return suffix
+ } catch (e: ClassParseException) {
+ errors.onErrorFound(e.message!!)
+ return null
+ }
+ }
+
+ companion object {
+ /**
+ * Convert from human-readable type names (e.g. "com.android.TypeName") to the internal type
+ * names (e.g. "Lcom/android/TypeName).
+ */
+ private fun convertToInternalNames(input: Set<String>): Set<String> {
+ val ret = mutableSetOf<String>()
+ input.forEach { ret.add("L" + it.toJvmClassName() + ";") }
+ return ret
+ }
+
+ /**
+ * Convert from human-readable type names to JVM type names.
+ */
+ private fun convertToJvmNames(input: Set<String>): Set<String> {
+ val ret = mutableSetOf<String>()
+ input.forEach { ret.add(it.toJvmClassName()) }
+ return ret
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt
new file mode 100644
index 000000000000..6aac3d88b8b1
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ClassWidePolicyPropagatingFilter.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.asm.getDirectOuterClassName
+
+/**
+ * This is used as the second last fallback filter. This filter propagates the class-wide policy
+ * (obtained from [outermostFilter]) to the fields and methods.
+ */
+class ClassWidePolicyPropagatingFilter(
+ fallback: OutputFilter,
+ ) : DelegatingFilter(fallback) {
+
+ private fun getClassWidePolicy(className: String, resolve: Boolean): FilterPolicyWithReason? {
+ var currentClass = className
+
+ while (true) {
+ outermostFilter.getPolicyForClass(className).let { policy ->
+ if (policy.policy.isClassWidePolicy) {
+ val p = if (resolve) policy.policy.resolveClassWidePolicy() else policy.policy
+
+ return p.withReason(policy.reason).wrapReason("class-wide in $currentClass")
+ }
+ // If the class's policy is remove, then remove it.
+ if (policy.policy == FilterPolicy.Remove) {
+ return FilterPolicy.Remove.withReason("class-wide in $currentClass")
+ }
+ }
+
+ // Next, look at the outer class...
+ val outer = getDirectOuterClassName(currentClass)
+ if (outer == null) {
+ return null
+ }
+ currentClass = outer
+ }
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ // If it's a nested class, use the outer class's policy.
+ getDirectOuterClassName(className)?.let { outerName ->
+ getClassWidePolicy(outerName, resolve = false)?.let { policy ->
+ return policy
+ }
+ }
+
+ return super.getPolicyForClass(className)
+ }
+
+ override fun getPolicyForField(
+ className: String,
+ fieldName: String
+ ): FilterPolicyWithReason {
+ return getClassWidePolicy(className, resolve = true)
+ ?: super.getPolicyForField(className, fieldName)
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): FilterPolicyWithReason {
+ return getClassWidePolicy(className, resolve = true)
+ ?: super.getPolicyForMethod(className, methodName, descriptor)
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt
new file mode 100644
index 000000000000..678e6eae0be6
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ConstantFilter.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.HostStubGenInternalException
+
+
+/**
+ * [OutputFilter] with a given policy. Used to represent the default policy.
+ *
+ * This is used as the last fallback filter.
+ *
+ * @param policy the policy. Cannot be a "substitute" policy.
+ */
+class ConstantFilter(
+ policy: FilterPolicy,
+ val reason: String
+) : OutputFilter() {
+ val classPolicy: FilterPolicy
+ val fieldPolicy: FilterPolicy
+ val methodPolicy: FilterPolicy
+
+ init {
+ if (policy.isSubstitute) {
+ throw HostStubGenInternalException(
+ "ConstantFilter doesn't allow substitution policies.")
+ }
+ if (policy.isClassWidePolicy) {
+ // We prevent it, because there's no point in using class-wide policies because
+ // all members get othe same policy too anyway.
+ throw HostStubGenInternalException(
+ "ConstantFilter doesn't allow class-wide policies.")
+ }
+ methodPolicy = policy
+
+ // If the default policy is "throw", we convert it to "keep" for classes and fields.
+ classPolicy = when (policy) {
+ FilterPolicy.Throw -> FilterPolicy.Keep
+ else -> policy
+ }
+ fieldPolicy = classPolicy
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ return classPolicy.withReason(reason)
+ }
+
+ override fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason {
+ return fieldPolicy.withReason(reason)
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): FilterPolicyWithReason {
+ return methodPolicy.withReason(reason)
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
new file mode 100644
index 000000000000..d771003a955d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DefaultHookInjectingFilter.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.addLists
+
+class DefaultHookInjectingFilter(
+ defaultClassLoadHook: String?,
+ defaultMethodCallHook: String?,
+ fallback: OutputFilter
+) : DelegatingFilter(fallback) {
+ /**
+ * Create a List containing a single element [e], if e != null. Otherwise, returns
+ * an empty list.
+ */
+ private fun toSingleList(e: String?): List<String> {
+ if (e == null) {
+ return emptyList()
+ }
+ return listOf(e)
+ }
+
+ private val defaultClassLoadHookAsList: List<String> = toSingleList(defaultClassLoadHook)
+ private val defaultMethodCallHookAsList: List<String> = toSingleList(defaultMethodCallHook)
+
+ override fun getClassLoadHooks(className: String): List<String> {
+ return addLists(super.getClassLoadHooks(className), defaultClassLoadHookAsList)
+ }
+
+ override fun getMethodCallHooks(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): List<String> {
+ return addLists(
+ super.getMethodCallHooks(className, methodName, descriptor),
+ defaultMethodCallHookAsList,
+ )
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
new file mode 100644
index 000000000000..45f61c5b2c22
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/DelegatingFilter.kt
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+/**
+ * Base class for an [OutputFilter] that uses another filter as a fallback.
+ */
+abstract class DelegatingFilter(
+ // fallback shouldn't be used by subclasses, so make it private.
+ // They should instead be calling into `super` or `outermostFilter`.
+ private val fallback: OutputFilter
+) : OutputFilter() {
+ init {
+ fallback.outermostFilter = this
+ }
+
+ override var outermostFilter: OutputFilter = this
+ get() = field
+ set(value) {
+ field = value
+ // Propagate the inner filters.
+ fallback.outermostFilter = value
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ return fallback.getPolicyForClass(className)
+ }
+
+ override fun getPolicyForField(
+ className: String,
+ fieldName: String
+ ): FilterPolicyWithReason {
+ return fallback.getPolicyForField(className, fieldName)
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): FilterPolicyWithReason {
+ return fallback.getPolicyForMethod(className, methodName, descriptor)
+ }
+
+ override fun getRenameTo(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): String? {
+ return fallback.getRenameTo(className, methodName, descriptor)
+ }
+
+ override fun getNativeSubstitutionClass(className: String): String? {
+ return fallback.getNativeSubstitutionClass(className)
+ }
+
+ override fun getClassLoadHooks(className: String): List<String> {
+ return fallback.getClassLoadHooks(className)
+ }
+
+ override fun getMethodCallHooks(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): List<String> {
+ return fallback.getMethodCallHooks(className, methodName, descriptor)
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
new file mode 100644
index 000000000000..93179969e968
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicy.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+enum class FilterPolicy {
+ /**
+ * Keep the item in the stub jar file, so tests can use it.
+ */
+ Stub,
+
+ /**
+ * Keep the item in the impl jar file, but not in the stub file. Tests cannot use it directly,
+ * but indirectly.
+ */
+ Keep,
+
+ /**
+ * Only used for types. Keep the class in the stub, and also all its members.
+ * But each member can have another annotations to override it.
+ */
+ StubClass,
+
+ /**
+ * Only used for types. Keep the class in the impl, not in the stub, and also all its members.
+ * But each member can have another annotations to override it.
+ */
+ KeepClass,
+
+ /**
+ * Same as [Stub], but replace it with a "substitution" method. Only usable with methods.
+ */
+ SubstituteAndStub,
+
+ /**
+ * Same as [Keep], but replace it with a "substitution" method. Only usable with methods.
+ */
+ SubstituteAndKeep,
+
+ /**
+ * Only usable with methods. The item will be kept in the impl jar file, but when called,
+ * it'll throw.
+ */
+ Throw,
+
+ /**
+ * Only usable with methods. The item will be kept in the impl jar file, but when called,
+ * it'll no-op. Currently only supported for methods returning `void`.
+ */
+ Ignore,
+
+ /**
+ * Remove the item completely.
+ */
+ Remove;
+
+ val isSubstitute: Boolean
+ get() = this == SubstituteAndStub || this == SubstituteAndKeep
+
+ val needsInStub: Boolean
+ get() = this == Stub || this == StubClass || this == SubstituteAndStub
+
+ val needsInImpl: Boolean
+ get() = this != Remove
+
+ /** Returns whether a policy can be used with classes */
+ val isUsableWithClasses: Boolean
+ get() {
+ return when (this) {
+ Stub, StubClass, Keep, KeepClass, Remove -> true
+ else -> false
+ }
+ }
+
+ /** Returns whether a policy can be used with fields. */
+ val isUsableWithFields: Boolean
+ get() {
+ return when (this) {
+ Stub, Keep, Remove -> true
+ else -> false
+ }
+ }
+
+ /** Returns whether a policy can be used with methods */
+ val isUsableWithMethods: Boolean
+ get() {
+ return when (this) {
+ StubClass, KeepClass -> false
+ else -> true
+ }
+ }
+
+ /** Returns whether a policy is a class-wide one. */
+ val isClassWidePolicy: Boolean
+ get() {
+ return when (this) {
+ StubClass, KeepClass -> true
+ else -> false
+ }
+ }
+
+ fun getSubstitutionBasePolicy(): FilterPolicy {
+ return when (this) {
+ SubstituteAndKeep -> Keep
+ SubstituteAndStub -> Stub
+ else -> this
+ }
+ }
+
+ /**
+ * Convert {Stub,Keep}Class to the corresponding Stub or Keep.
+ */
+ fun resolveClassWidePolicy(): FilterPolicy {
+ return when (this) {
+ StubClass -> Stub
+ KeepClass -> Keep
+ else -> this
+ }
+ }
+
+ /**
+ * Create a [FilterPolicyWithReason] with a given reason.
+ */
+ fun withReason(reason: String): FilterPolicyWithReason {
+ return FilterPolicyWithReason(this, reason)
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
new file mode 100644
index 000000000000..b64a2f5fd8a5
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+/**
+ * Captures a [FilterPolicy] with a human-readable reason.
+ */
+data class FilterPolicyWithReason (
+ val policy: FilterPolicy,
+ val reason: String = "",
+) {
+ /**
+ * Return a new [FilterPolicy] with an updated reason, while keeping the original reason
+ * as an "inner-reason".
+ */
+ fun wrapReason(reason: String): FilterPolicyWithReason {
+ return FilterPolicyWithReason(policy, "$reason [inner-reason: ${this.reason}]")
+ }
+
+ /**
+ * If the visibility is lower than "Keep" (meaning if it's "remove"),
+ * then return a new [FilterPolicy] with "Keep".
+ * Otherwise, return itself
+ */
+ fun promoteToKeep(promotionReason: String): FilterPolicyWithReason {
+ if (policy.needsInImpl) {
+ return this
+ }
+ val newPolicy = if (policy.isClassWidePolicy) FilterPolicy.KeepClass else FilterPolicy.Keep
+
+ return FilterPolicyWithReason(newPolicy,
+ "$promotionReason [original remove reason: ${this.reason}]")
+ }
+
+ /**
+ * If the visibility is above "Keep" (meaning if it's "stub"),
+ * then return a new [FilterPolicy] with "Keep".
+ * Otherwise, return itself
+ */
+ fun demoteToKeep(promotionReason: String): FilterPolicyWithReason {
+ if (!policy.needsInStub) {
+ return this
+ }
+ val newPolicy = if (policy.isClassWidePolicy) FilterPolicy.KeepClass else FilterPolicy.Keep
+
+ return FilterPolicyWithReason(newPolicy,
+ "$promotionReason [original stub reason: ${this.reason}]")
+ }
+
+ override fun toString(): String {
+ return "[$policy - reason: $reason]"
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
new file mode 100644
index 000000000000..84856aca84cc
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.HostStubGenInternalException
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_DESC
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME
+import com.android.hoststubgen.asm.isAnonymousInnerClass
+import com.android.hoststubgen.log
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.isAnnotation
+import com.android.hoststubgen.asm.isAutoGeneratedEnumMember
+import com.android.hoststubgen.asm.isEnum
+import com.android.hoststubgen.asm.isSynthetic
+import com.android.hoststubgen.asm.isVisibilityPrivateOrPackagePrivate
+import org.objectweb.asm.tree.ClassNode
+
+/**
+ * Filter implementing "implicit" rules, such as:
+ * - "keep all anonymous inner classes if the outer class is keep".
+ * (But anonymous inner classes should never be in "stub")
+ * - For classes in stub, make sure private parameterless constructors are also in stub, if any.
+ *
+ * TODO: Do we need a way to make anonymous class methods and lambdas "throw"?
+ */
+class ImplicitOutputFilter(
+ private val errors: HostStubGenErrors,
+ private val classes: ClassNodes,
+ fallback: OutputFilter
+) : DelegatingFilter(fallback) {
+ private fun getClassImplicitPolicy(className: String, cn: ClassNode): FilterPolicyWithReason? {
+ if (isAnonymousInnerClass(cn)) {
+ log.forDebug {
+// log.d(" anon-inner class: ${className} outer: ${cn.outerClass} ")
+ }
+ if (cn.outerClass == null) {
+ throw HostStubGenInternalException(
+ "outerClass is null for anonymous inner class")
+ }
+ // If the outer class needs to be in impl, it should be in impl too.
+ val outerPolicy = outermostFilter.getPolicyForClass(cn.outerClass)
+ if (outerPolicy.policy.needsInImpl) {
+ return FilterPolicy.KeepClass.withReason("anonymous-inner-class")
+ }
+ }
+ return null
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ val fallback = super.getPolicyForClass(className)
+
+ val cn = classes.getClass(className)
+
+ // Use the implicit policy, if any.
+ getClassImplicitPolicy(className, cn)?.let { return it }
+
+ return fallback
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): FilterPolicyWithReason {
+ val fallback = super.getPolicyForMethod(className, methodName, descriptor)
+ val classPolicy = outermostFilter.getPolicyForClass(className)
+
+ // If the class is in the stub, then we need to put the private constructor in the stub too,
+ // to prevent the class from getting instantiated.
+ if (classPolicy.policy.needsInStub &&
+ !fallback.policy.needsInStub &&
+ (methodName == "<init>") && // Constructor?
+ (descriptor == "()V")) { // Has zero parameters?
+ classes.findMethod(className, methodName, descriptor)?.let { mn ->
+ if (isVisibilityPrivateOrPackagePrivate(mn.access)) {
+ return FilterPolicy.Stub.withReason("private constructor in stub class")
+ }
+ }
+ }
+
+ val cn = classes.getClass(className)
+
+ // If we throw from the static initializer, the class would be useless, so we convert it
+ // "keep" instead.
+ // Unless it's an enum -- in that case, the below code would handle it.
+ if (!cn.isEnum() &&
+ fallback.policy == FilterPolicy.Throw &&
+ methodName == CLASS_INITIALIZER_NAME && descriptor == CLASS_INITIALIZER_DESC) {
+ // TODO Maybe show a warning?? But that'd be too noisy with --default-throw.
+ return FilterPolicy.Ignore.withReason(
+ "'throw' on static initializer is handled as 'ignore'" +
+ " [original throw reason: ${fallback.reason}]")
+ }
+
+ log.d("Class ${cn.name} Class policy: $classPolicy")
+ if (classPolicy.policy.needsInImpl) {
+ // Do it only when the class needs to be kept...
+
+ // Member policy should be "keep" or "stub".
+ val memberPolicy = classPolicy.policy.resolveClassWidePolicy()
+
+ val mn = classes.findMethod(className, methodName, descriptor)
+
+ // Keep (or stub) the generated enum members.
+ if (cn.isEnum()) {
+ mn?.let { mn ->
+ if (isAutoGeneratedEnumMember(mn)) {
+ return memberPolicy.withReason(classPolicy.reason).wrapReason("enum")
+ }
+ }
+ }
+
+ // Keep (or stub) all members of annotations.
+ if (cn.isAnnotation()) {
+ return memberPolicy.withReason(classPolicy.reason).wrapReason("annotation")
+ }
+
+ mn?.let {
+ if (mn.isSynthetic()) {
+ // For synthetic methods (such as lambdas), let's just inherit the class's
+ // policy.
+ return memberPolicy.withReason(classPolicy.reason).wrapReason(
+ "synthetic method")
+ }
+ }
+ }
+
+ return fallback
+ }
+
+ override fun getPolicyForField(
+ className: String,
+ fieldName: String
+ ): FilterPolicyWithReason {
+ val fallback = super.getPolicyForField(className, fieldName)
+
+ val cn = classes.getClass(className)
+ val classPolicy = super.getPolicyForClass(className)
+
+ log.d("Class ${cn.name} Class policy: $classPolicy")
+ if (classPolicy.policy.needsInImpl) {
+ // Do it only when the class needs to be kept...
+
+ // Member policy should be "keep" or "stub".
+ val memberPolicy = classPolicy.policy.resolveClassWidePolicy()
+
+ // Keep (or stub) the generated enum members.
+ if (cn.isEnum()) {
+ classes.findField(className, fieldName)?.let { fn ->
+ if (isAutoGeneratedEnumMember(fn)) {
+ return memberPolicy.withReason(classPolicy.reason).wrapReason("enum")
+ }
+ }
+ }
+
+ // Keep (or stub) all members of annotations.
+ if (cn.isAnnotation()) {
+ return memberPolicy.withReason(classPolicy.reason).wrapReason("annotation")
+ }
+ }
+
+ return fallback
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
new file mode 100644
index 000000000000..5659a35170c1
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/InMemoryOutputFilter.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.UnknownApiException
+import com.android.hoststubgen.addNonNullElement
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.toHumanReadableClassName
+import com.android.hoststubgen.asm.toHumanReadableMethodName
+
+// TODO: Validate all input names.
+
+class InMemoryOutputFilter(
+ private val classes: ClassNodes,
+ fallback: OutputFilter,
+) : DelegatingFilter(fallback) {
+ private val mPolicies: MutableMap<String, FilterPolicyWithReason> = mutableMapOf()
+ private val mRenames: MutableMap<String, String> = mutableMapOf()
+ private val mNativeSubstitutionClasses: MutableMap<String, String> = mutableMapOf()
+ private val mClassLoadHooks: MutableMap<String, String> = mutableMapOf()
+
+ private fun getClassKey(className: String): String {
+ return className.toHumanReadableClassName()
+ }
+
+ private fun getFieldKey(className: String, fieldName: String): String {
+ return getClassKey(className) + "." + fieldName
+ }
+
+ private fun getMethodKey(className: String, methodName: String, signature: String): String {
+ return getClassKey(className) + "." + methodName + ";" + signature
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ return mPolicies[getClassKey(className)] ?: super.getPolicyForClass(className)
+ }
+
+ private fun ensureClassExists(className: String) {
+ if (classes.findClass(className) == null) {
+ throw UnknownApiException("Unknown class $className")
+ }
+ }
+
+ private fun ensureFieldExists(className: String, fieldName: String) {
+ if (classes.findField(className, fieldName) == null) {
+ throw UnknownApiException("Unknown field $className.$fieldName")
+ }
+ }
+
+ private fun ensureMethodExists(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ) {
+ if (classes.findMethod(className, methodName, descriptor) == null) {
+ throw UnknownApiException("Unknown method $className.$methodName$descriptor")
+ }
+ }
+
+ fun setPolicyForClass(className: String, policy: FilterPolicyWithReason) {
+ ensureClassExists(className)
+ mPolicies[getClassKey(className)] = policy
+ }
+
+ override fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason {
+ return mPolicies[getFieldKey(className, fieldName)]
+ ?: super.getPolicyForField(className, fieldName)
+ }
+
+ fun setPolicyForField(className: String, fieldName: String, policy: FilterPolicyWithReason) {
+ ensureFieldExists(className, fieldName)
+ mPolicies[getFieldKey(className, fieldName)] = policy
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): FilterPolicyWithReason {
+ return mPolicies[getMethodKey(className, methodName, descriptor)]
+ ?: super.getPolicyForMethod(className, methodName, descriptor)
+ }
+
+ fun setPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String,
+ policy: FilterPolicyWithReason,
+ ) {
+ ensureMethodExists(className, methodName, descriptor)
+ mPolicies[getMethodKey(className, methodName, descriptor)] = policy
+ }
+
+ override fun getRenameTo(className: String, methodName: String, descriptor: String): String? {
+ return mRenames[getMethodKey(className, methodName, descriptor)]
+ ?: super.getRenameTo(className, methodName, descriptor)
+ }
+
+ fun setRenameTo(className: String, methodName: String, descriptor: String, toName: String) {
+ ensureMethodExists(className, methodName, descriptor)
+ ensureMethodExists(className, toName, descriptor)
+ mRenames[getMethodKey(className, methodName, descriptor)] = toName
+ }
+
+ override fun getNativeSubstitutionClass(className: String): String? {
+ return mNativeSubstitutionClasses[getClassKey(className)]
+ ?: super.getNativeSubstitutionClass(className)
+ }
+
+ fun setNativeSubstitutionClass(from: String, to: String) {
+ ensureClassExists(from)
+
+ // Native substitute classes may be provided from other jars, so we can't do this check.
+ // ensureClassExists(to)
+ mNativeSubstitutionClasses[getClassKey(from)] = to.toHumanReadableClassName()
+ }
+
+ override fun getClassLoadHooks(className: String): List<String> {
+ return addNonNullElement(super.getClassLoadHooks(className),
+ mClassLoadHooks[getClassKey(className)])
+ }
+
+ fun setClassLoadHook(className: String, methodName: String) {
+ mClassLoadHooks[getClassKey(className)] = methodName.toHumanReadableMethodName()
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt
new file mode 100644
index 000000000000..45dd38d10ef5
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/KeepAllClassesFilter.kt
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+/**
+ * An [OutputFilter] that keeps all classes by default. (but none of its members)
+ *
+ * We're not currently using it, but using it *might* make certain things easier. For example, with
+ * this, all classes would at least be loadable.
+ */
+class KeepAllClassesFilter(fallback: OutputFilter) : DelegatingFilter(fallback) {
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ // If the default visibility wouldn't keep it, change it to "keep".
+ val f = super.getPolicyForClass(className)
+ return f.promoteToKeep("keep-all-classes")
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
new file mode 100644
index 000000000000..3df16ffa99b3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/OutputFilter.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+/**
+ * Base class for "filters", which decides what APIs should go to the stub / impl jars.
+ */
+abstract class OutputFilter {
+ /**
+ * Filters are stacked over one another. This fields contains the "outermost" filter in a
+ * filter stack chain.
+ *
+ * Subclasses must use this filter to get a policy, when they need to infer a policy
+ * from the policy of another API.
+ *
+ * For example, [ClassWidePolicyPropagatingFilter] needs to check the policy of the enclosing
+ * class to propagate "class-wide" policies, but when it does so, it can't just use
+ * `this.getPolicyForClass()` because that wouldn't return policies decided by "outer"
+ * filters. Instead, it uses [outermostFilter.getPolicyForClass()].
+ *
+ * Note, [outermostFilter] can be itself, so make sure not to cause infinity recursions when
+ * using it.
+ */
+ open var outermostFilter: OutputFilter = this
+ get() = field
+ set(value) {
+ field = value
+ }
+
+ abstract fun getPolicyForClass(className: String): FilterPolicyWithReason
+
+ abstract fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason
+
+ abstract fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String,
+ ): FilterPolicyWithReason
+
+ /**
+ * If a given method is a substitute-from method, return the substitute-to method name.
+ *
+ * The substitute-to and from methods must have the same signature, in the same class.
+ */
+ open fun getRenameTo(className: String, methodName: String, descriptor: String): String? {
+ return null
+ }
+
+ /**
+ * Return a "native substitution class" name for a given class.
+ *
+ * The result will be in a "human readable" form. (e.g. uses '.'s instead of '/'s)
+ *
+ * (which corresponds to @HostSideTestNativeSubstitutionClass of the standard annotations.)
+ */
+ open fun getNativeSubstitutionClass(className: String): String? {
+ return null
+ }
+
+ /**
+ * Return a "class load hook" class name for a given class.
+ *
+ * (which corresponds to @HostSideTestClassLoadHook of the standard annotations.)
+ */
+ open fun getClassLoadHooks(className: String): List<String> {
+ return emptyList()
+ }
+
+ /**
+ * Return the "method call hook" class name.
+ *
+ * The class has to have a function with the following signature:
+ * `public static void onMethodCalled(Class<?> clazz, String name, String descriptor)`.
+ */
+ open fun getMethodCallHooks(className: String, methodName: String, descriptor: String):
+ List<String> {
+ return emptyList()
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/StubIntersectingFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/StubIntersectingFilter.kt
new file mode 100644
index 000000000000..f92a0271d7c7
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/StubIntersectingFilter.kt
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.asm.ClassNodes
+
+private const val REASON = "demoted, not in intersect jars"
+
+/**
+ * An [OutputFilter] that will restrict what to put in stub to only what shows up in "intersecting
+ * jar" files.
+ *
+ * For example, if the Android public API stub jar is provided, then the HostStubGen's output
+ * stub will be restricted to public APIs.
+ */
+class StubIntersectingFilter(
+ private val errors: HostStubGenErrors,
+ /**
+ * If a class / field / method is not in any of these jars, then we will not put it in
+ * stub.
+ */
+ private val intersectingJars: Map<String, ClassNodes>,
+ fallback: OutputFilter,
+) : DelegatingFilter(fallback) {
+ private inline fun exists(predicate: (ClassNodes) -> Boolean): Boolean {
+ intersectingJars.forEach { entry ->
+ if (predicate(entry.value)) {
+ return true
+ }
+ }
+ return false
+ }
+
+ /**
+ * If [origPolicy] is less than "Stub", then return it as-is.
+ *
+ * Otherwise, call [inStubChecker] to see if the API is in any of [intersectingJars].
+ * If yes, then return [origPolicy] as-is. Otherwise, demote to "Keep".
+ */
+ private fun intersectWithStub(
+ origPolicy: FilterPolicyWithReason,
+ inStubChecker: () -> Boolean,
+ ): FilterPolicyWithReason {
+ if (origPolicy.policy.needsInStub) {
+ // Only check the stub jars, when the class is supposed to be in stub otherwise.
+ if (!inStubChecker()) {
+ return origPolicy.demoteToKeep(REASON)
+ }
+ }
+ return origPolicy
+ }
+
+ override fun getPolicyForClass(className: String): FilterPolicyWithReason {
+ return intersectWithStub(super.getPolicyForClass(className)) {
+ exists { classes -> classes.findClass(className) != null }
+ }
+ }
+
+ override fun getPolicyForField(
+ className: String,
+ fieldName: String
+ ): FilterPolicyWithReason {
+ return intersectWithStub(super.getPolicyForField(className, fieldName)) {
+ exists { classes -> classes.findField(className, fieldName) != null }
+ }
+ }
+
+ override fun getPolicyForMethod(
+ className: String,
+ methodName: String,
+ descriptor: String
+ ): FilterPolicyWithReason {
+ return intersectWithStub(super.getPolicyForMethod(className, methodName, descriptor)) {
+ exists { classes -> classes.findMethod(className, methodName, descriptor) != null }
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
new file mode 100644
index 000000000000..416f08505867
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/filters/TextFileFilterPolicyParser.kt
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.filters
+
+import com.android.hoststubgen.ParseException
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.log
+import com.android.hoststubgen.normalizeTextLine
+import com.android.hoststubgen.whitespaceRegex
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.tree.ClassNode
+import java.io.BufferedReader
+import java.io.FileReader
+import java.io.PrintWriter
+import java.util.Objects
+
+/**
+ * Print a class node as a "keep" policy.
+ */
+fun printAsTextPolicy(pw: PrintWriter, cn: ClassNode) {
+ pw.printf("class %s\t%s\n", cn.name, "keep")
+
+ for (f in cn.fields ?: emptyList()) {
+ pw.printf(" field %s\t%s\n", f.name, "keep")
+ }
+ for (m in cn.methods ?: emptyList()) {
+ pw.printf(" method %s\t%s\t%s\n", m.name, m.desc, "keep")
+ }
+}
+
+/** Return true if [access] is either public or protected. */
+private fun isVisible(access: Int): Boolean {
+ return (access and (Opcodes.ACC_PUBLIC or Opcodes.ACC_PROTECTED)) != 0
+}
+
+private const val FILTER_REASON = "file-override"
+
+/**
+ * Read a given "policy" file and return as an [OutputFilter]
+ */
+fun createFilterFromTextPolicyFile(
+ filename: String,
+ classes: ClassNodes,
+ fallback: OutputFilter,
+ ): OutputFilter {
+ log.i("Loading offloaded annotations from $filename ...")
+ log.withIndent {
+ val ret = InMemoryOutputFilter(classes, fallback)
+
+ var lineNo = 0
+
+ try {
+ BufferedReader(FileReader(filename)).use { reader ->
+ var className = ""
+
+ while (true) {
+ var line = reader.readLine()
+ if (line == null) {
+ break
+ }
+ lineNo++
+
+ line = normalizeTextLine(line)
+
+ if (line.isEmpty()) {
+ continue // skip empty lines.
+ }
+
+ val fields = line.split(whitespaceRegex).toTypedArray()
+ when (fields[0].lowercase()) {
+ "c", "class" -> {
+ if (fields.size < 3) {
+ throw ParseException("Class ('c') expects 2 fields.")
+ }
+ className = fields[1]
+ if (fields[2].startsWith("!")) {
+ // It's a native-substitution.
+ val toClass = fields[2].substring(1)
+ ret.setNativeSubstitutionClass(className, toClass)
+ } else if (fields[2].startsWith("~")) {
+ // It's a class-load hook
+ val callback = fields[2].substring(1)
+ ret.setClassLoadHook(className, callback)
+ } else {
+ val policy = parsePolicy(fields[2])
+ if (!policy.isUsableWithClasses) {
+ throw ParseException("Class can't have policy '$policy'")
+ }
+ Objects.requireNonNull(className)
+
+ // TODO: Duplicate check, etc
+ ret.setPolicyForClass(className, policy.withReason(FILTER_REASON))
+ }
+ }
+
+ "f", "field" -> {
+ if (fields.size < 3) {
+ throw ParseException("Field ('f') expects 2 fields.")
+ }
+ val name = fields[1]
+ val policy = parsePolicy(fields[2])
+ if (!policy.isUsableWithFields) {
+ throw ParseException("Field can't have policy '$policy'")
+ }
+ Objects.requireNonNull(className)
+
+ // TODO: Duplicate check, etc
+ ret.setPolicyForField(className, name, policy.withReason(FILTER_REASON))
+ }
+
+ "m", "method" -> {
+ if (fields.size < 4) {
+ throw ParseException("Method ('m') expects 3 fields.")
+ }
+ val name = fields[1]
+ val signature = fields[2]
+ val policy = parsePolicy(fields[3])
+
+ if (!policy.isUsableWithMethods) {
+ throw ParseException("Method can't have policy '$policy'")
+ }
+
+ Objects.requireNonNull(className)
+
+ ret.setPolicyForMethod(className, name, signature,
+ policy.withReason(FILTER_REASON))
+ if (policy.isSubstitute) {
+ val fromName = fields[3].substring(1)
+
+ if (fromName == name) {
+ throw ParseException(
+ "Substitution must have a different name")
+ }
+
+ // Set the policy for the "from" method.
+ ret.setPolicyForMethod(className, fromName, signature,
+ policy.getSubstitutionBasePolicy()
+ .withReason(FILTER_REASON))
+
+ // Keep "from" -> "to" mapping.
+ ret.setRenameTo(className, fromName, signature, name)
+ }
+ }
+
+ else -> {
+ throw ParseException("Unknown directive \"${fields[0]}\"")
+ }
+ }
+ }
+ }
+ } catch (e: ParseException) {
+ throw e.withSourceInfo(filename, lineNo)
+ }
+ return ret
+ }
+}
+
+private fun parsePolicy(s: String): FilterPolicy {
+ return when (s.lowercase()) {
+ "s", "stub" -> FilterPolicy.Stub
+ "k", "keep" -> FilterPolicy.Keep
+ "t", "throw" -> FilterPolicy.Throw
+ "r", "remove" -> FilterPolicy.Remove
+ "sc", "stubclass" -> FilterPolicy.StubClass
+ "kc", "keepclass" -> FilterPolicy.KeepClass
+ else -> {
+ if (s.startsWith("@")) {
+ FilterPolicy.SubstituteAndStub
+ } else if (s.startsWith("%")) {
+ FilterPolicy.SubstituteAndKeep
+ } else {
+ throw ParseException("Invalid policy \"$s\"")
+ }
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt
new file mode 100644
index 000000000000..01a7ab3eacfa
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/utils/ClassFilter.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.utils
+
+import com.android.hoststubgen.ParseException
+import com.android.hoststubgen.asm.toHumanReadableClassName
+import com.android.hoststubgen.asm.toJvmClassName
+import com.android.hoststubgen.normalizeTextLine
+import java.io.File
+
+/**
+ * General purpose filter for class names.
+ */
+class ClassFilter private constructor (
+ val defaultResult: Boolean,
+) {
+ private data class FilterElement(
+ val allowed: Boolean,
+ val internalName: String,
+ val isPrefix: Boolean,
+ ) {
+ fun matches(classInternalName: String): Boolean {
+ if (isPrefix) {
+ return classInternalName.startsWith(internalName)
+ } else {
+ return classInternalName == internalName
+ }
+ }
+ }
+
+ private val elements: MutableList<FilterElement> = mutableListOf()
+
+ private val cache: MutableMap<String, Boolean> = mutableMapOf()
+
+ /**
+ * Takes an internal class name (e.g. "com/android/hoststubgen/ClassName") and returns if
+ * matches the filter or not.
+ */
+ fun matches(classInternalName: String): Boolean {
+ cache[classInternalName]?.let {
+ return it
+ }
+
+ var result = defaultResult
+ run outer@{
+ elements.forEach { e ->
+ if (e.matches(classInternalName)) {
+ result = e.allowed
+ return@outer // break equivalent.
+ }
+ }
+ }
+ cache[classInternalName] = result
+
+ return result
+ }
+
+ fun getCacheSizeForTest(): Int {
+ return cache.size
+ }
+
+ companion object {
+ /**
+ * Return a filter that alawys returns true or false.
+ */
+ fun newNullFilter(defaultResult: Boolean): ClassFilter {
+ return ClassFilter(defaultResult)
+ }
+
+ /** Build a filter from a file. */
+ fun loadFromFile(filename: String, defaultResult: Boolean): ClassFilter {
+ return buildFromString(File(filename).readText(), defaultResult, filename)
+ }
+
+ /** Build a filter from a string (for unit tests). */
+ fun buildFromString(
+ filterString: String,
+ defaultResult: Boolean,
+ filenameForErrorMessage: String
+ ): ClassFilter {
+ val ret = ClassFilter(defaultResult)
+
+ var lineNo = 0
+ filterString.split('\n').forEach { s ->
+ lineNo++
+
+ var line = normalizeTextLine(s)
+
+ if (line.isEmpty()) {
+ return@forEach // skip empty lines.
+ }
+
+ line = line.toHumanReadableClassName() // Convert all the slashes to periods.
+
+ var allow = true
+ if (line.startsWith("!")) {
+ allow = false
+ line = line.substring(1).trimStart()
+ }
+
+ // Special case -- matches any class names.
+ if (line == "*") {
+ ret.elements.add(FilterElement(allow, "", true))
+ return@forEach
+ }
+
+ // Handle wildcard -- e.g. "package.name.*"
+ if (line.endsWith(".*")) {
+ ret.elements.add(FilterElement(
+ allow, line.substring(0, line.length - 2).toJvmClassName(), true))
+ return@forEach
+ }
+
+ // Any other uses of "*" would be an error.
+ if (line.contains('*')) {
+ throw ParseException(
+ "Wildcard (*) can only show up as the last element",
+ filenameForErrorMessage,
+ lineNo
+ )
+ }
+ ret.elements.add(FilterElement(allow, line.toJvmClassName(), false))
+ }
+
+ return ret
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
new file mode 100644
index 000000000000..f25e862d6095
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BaseAdapter.kt
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.visitors
+
+import com.android.hoststubgen.HostStubGenErrors
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.getPackageNameFromClassName
+import com.android.hoststubgen.asm.resolveClassName
+import com.android.hoststubgen.asm.toJvmClassName
+import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+import com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+import com.android.hoststubgen.log
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.FieldVisitor
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.commons.ClassRemapper
+import org.objectweb.asm.util.TraceClassVisitor
+import java.io.PrintWriter
+
+val OPCODE_VERSION = Opcodes.ASM9
+
+abstract class BaseAdapter (
+ protected val classes: ClassNodes,
+ nextVisitor: ClassVisitor,
+ protected val filter: OutputFilter,
+ protected val options: Options,
+) : ClassVisitor(OPCODE_VERSION, nextVisitor) {
+
+ /**
+ * Options to control the behavior.
+ */
+ data class Options (
+ val errors: HostStubGenErrors,
+ val enablePreTrace: Boolean,
+ val enablePostTrace: Boolean,
+ val enableNonStubMethodCallDetection: Boolean,
+ )
+
+ protected lateinit var currentPackageName: String
+ protected lateinit var currentClassName: String
+ protected var nativeSubstitutionClass: String? = null
+ protected lateinit var classPolicy: FilterPolicyWithReason
+
+ /**
+ * Return whether an item with a given policy should be included in the output.
+ */
+ protected abstract fun shouldEmit(policy: FilterPolicy): Boolean
+
+ override fun visit(
+ version: Int,
+ access: Int,
+ name: String,
+ signature: String?,
+ superName: String?,
+ interfaces: Array<String>,
+ ) {
+ super.visit(version, access, name, signature, superName, interfaces)
+ currentClassName = name
+ currentPackageName = getPackageNameFromClassName(name)
+ classPolicy = filter.getPolicyForClass(currentClassName)
+
+ log.d("[%s] visit: %s (package: %s)", this.javaClass.simpleName, name, currentPackageName)
+ log.indent()
+ log.v("Emitting class: %s", name)
+ log.indent()
+
+ filter.getNativeSubstitutionClass(currentClassName)?.let { className ->
+ val fullClassName = resolveClassName(className, currentPackageName).toJvmClassName()
+ log.d(" NativeSubstitutionClass: $fullClassName")
+ if (classes.findClass(fullClassName) == null) {
+ log.w("Native substitution class $fullClassName not found. Class must be " +
+ "available at runtime.")
+ } else {
+ // If the class exists, it must have a KeepClass policy.
+ if (filter.getPolicyForClass(fullClassName).policy != FilterPolicy.KeepClass) {
+ // TODO: Use real annotation name.
+ options.errors.onErrorFound(
+ "Native substitution class $fullClassName should have @Keep.")
+ }
+ }
+
+ nativeSubstitutionClass = fullClassName
+ }
+ // Inject annotations to generated classes.
+ if (classPolicy.policy.needsInStub) {
+ visitAnnotation(HostStubGenProcessedStubClass.CLASS_DESCRIPTOR, true)
+ }
+ if (classPolicy.policy.needsInImpl) {
+ visitAnnotation(HostStubGenProcessedKeepClass.CLASS_DESCRIPTOR, true)
+ }
+ }
+
+ override fun visitEnd() {
+ log.unindent()
+ log.unindent()
+ super.visitEnd()
+ }
+
+ var skipMemberModificationNestCount = 0
+
+ /**
+ * This method allows writing class members without any modifications.
+ */
+ protected inline fun writeRawMembers(callback: () -> Unit) {
+ skipMemberModificationNestCount++
+ try {
+ callback()
+ } finally {
+ skipMemberModificationNestCount--
+ }
+ }
+
+ override fun visitField(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ value: Any?,
+ ): FieldVisitor? {
+ if (skipMemberModificationNestCount > 0) {
+ return super.visitField(access, name, descriptor, signature, value)
+ }
+ val policy = filter.getPolicyForField(currentClassName, name)
+ log.d("visitField: %s %s [%x] Policy: %s", name, descriptor, access, policy)
+
+ log.withIndent {
+ if (!shouldEmit(policy.policy)) {
+ log.d("Removing %s %s", name, policy)
+ return null
+ }
+
+ log.v("Emitting field: %s %s %s", name, descriptor, policy)
+ return super.visitField(access, name, descriptor, signature, value)
+ }
+ }
+
+ override fun visitMethod(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ ): MethodVisitor? {
+ if (skipMemberModificationNestCount > 0) {
+ return super.visitMethod(access, name, descriptor, signature, exceptions)
+ }
+ val p = filter.getPolicyForMethod(currentClassName, name, descriptor)
+ log.d("visitMethod: %s%s [%x] [%s] Policy: %s", name, descriptor, access, signature, p)
+
+ log.withIndent {
+ // If it's a substitute-to method, then skip.
+ val policy = filter.getPolicyForMethod(currentClassName, name, descriptor)
+ if (policy.policy.isSubstitute) {
+ log.d("Skipping %s%s %s", name, descriptor, policy)
+ return null
+ }
+ if (!shouldEmit(p.policy)) {
+ log.d("Removing %s%s %s", name, descriptor, policy)
+ return null
+ }
+
+ // Maybe rename the method.
+ val newName: String
+ val substituteTo = filter.getRenameTo(currentClassName, name, descriptor)
+ if (substituteTo != null) {
+ newName = substituteTo
+ log.v("Emitting %s.%s%s as %s %s", currentClassName, name, descriptor,
+ newName, policy)
+ } else {
+ log.v("Emitting method: %s%s %s", name, descriptor, policy)
+ newName = name
+ }
+
+ // Let subclass update the flag.
+ // But note, we only use it when calling the super's method,
+ // but not for visitMethodInner(), beucase when subclass wants to change access,
+ // it can do so inside visitMethodInner().
+ val newAccess = updateAccessFlags(access, name, descriptor)
+
+ return visitMethodInner(access, newName, descriptor, signature, exceptions, policy,
+ super.visitMethod(newAccess, newName, descriptor, signature, exceptions))
+ }
+ }
+
+ open fun updateAccessFlags(
+ access: Int,
+ name: String,
+ descriptor: String,
+ ): Int {
+ return access
+ }
+
+ abstract fun visitMethodInner(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ policy: FilterPolicyWithReason,
+ superVisitor: MethodVisitor?,
+ ): MethodVisitor?
+
+ companion object {
+ fun getVisitor(
+ classInternalName: String,
+ classes: ClassNodes,
+ nextVisitor: ClassVisitor,
+ filter: OutputFilter,
+ packageRedirector: PackageRedirectRemapper,
+ forImpl: Boolean,
+ options: Options,
+ ): ClassVisitor {
+ var next = nextVisitor
+
+ val verbosePrinter = PrintWriter(log.getVerbosePrintStream())
+
+ // Inject TraceClassVisitor for debugging.
+ if (options.enablePostTrace) {
+ next = TraceClassVisitor(next, verbosePrinter)
+ }
+
+ // Handle --package-redirect
+ if (!packageRedirector.isEmpty) {
+ // Don't apply the remapper on redirect-from classes.
+ // Otherwise, if the target jar actually contains the "from" classes (which
+ // may or may not be the case) they'd be renamed.
+ // But we update all references in other places, so, a method call to a "from" class
+ // would be replaced with the "to" class. All type references (e.g. variable types)
+ // will be updated too.
+ if (!packageRedirector.isTarget(classInternalName)) {
+ next = ClassRemapper(next, packageRedirector)
+ } else {
+ log.v("Class $classInternalName is a redirect-from class, not applying" +
+ " --package-redirect")
+ }
+ }
+
+ var ret: ClassVisitor
+ if (forImpl) {
+ ret = ImplGeneratingAdapter(classes, next, filter, options)
+ } else {
+ ret = StubGeneratingAdapter(classes, next, filter, options)
+ }
+
+ // Inject TraceClassVisitor for debugging.
+ if (options.enablePreTrace) {
+ ret = TraceClassVisitor(ret, verbosePrinter)
+ }
+ return ret
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt
new file mode 100644
index 000000000000..8250412b3717
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/BodyReplacingMethodVisitor.kt
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.visitors
+
+import org.objectweb.asm.AnnotationVisitor
+import org.objectweb.asm.Attribute
+import org.objectweb.asm.Handle
+import org.objectweb.asm.Label
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.TypePath
+
+/**
+ * A method visitor that removes everything from method body.
+ *
+ * To inject a method body, override [visitCode] and create the opcodes there.
+ */
+abstract class BodyReplacingMethodVisitor(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?,
+) : MethodVisitor(OPCODE_VERSION, next) {
+ val isVoid: Boolean
+ val isStatic: Boolean
+
+ init {
+ isVoid = descriptor.endsWith(")V")
+ isStatic = access and Opcodes.ACC_STATIC != 0
+ }
+
+ // Following methods are for things that we need to keep.
+ // Since they're all calling the super method, we can just remove them, but we keep them
+ // just to clarify what we're keeping.
+
+ final override fun visitParameter(
+ name: String?,
+ access: Int
+ ) {
+ super.visitParameter(name, access)
+ }
+
+ final override fun visitAnnotationDefault(): AnnotationVisitor? {
+ return super.visitAnnotationDefault()
+ }
+
+ final override fun visitAnnotation(
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ return super.visitAnnotation(descriptor, visible)
+ }
+
+ final override fun visitTypeAnnotation(
+ typeRef: Int,
+ typePath: TypePath?,
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ return super.visitTypeAnnotation(typeRef, typePath, descriptor, visible)
+ }
+
+ final override fun visitAnnotableParameterCount(
+ parameterCount: Int,
+ visible: Boolean
+ ) {
+ super.visitAnnotableParameterCount(parameterCount, visible)
+ }
+
+ final override fun visitParameterAnnotation(
+ parameter: Int,
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ return super.visitParameterAnnotation(parameter, descriptor, visible)
+ }
+
+ final override fun visitAttribute(attribute: Attribute?) {
+ super.visitAttribute(attribute)
+ }
+
+ override fun visitEnd() {
+ super.visitEnd()
+ }
+
+ /**
+ * Control when to emit the code. We use this to ignore all visitXxx method calls caused by
+ * the original method, so we'll remove all the original code.
+ *
+ * Only when visitXxx methods are called from [emitNewCode], we pass-through to the base class,
+ * so the body will be generated.
+ *
+ * (See also https://asm.ow2.io/asm4-guide.pdf section 3.2.1 about the MethovVisitor
+ * call order.)
+ */
+ var emitCode = false
+
+ final override fun visitCode() {
+ super.visitCode()
+
+ try {
+ emitCode = true
+
+ emitNewCode()
+ } finally {
+ emitCode = false
+ }
+ }
+
+ /**
+ * Subclass must implement it and emit code, and call [visitMaxs] at the end.
+ */
+ abstract fun emitNewCode()
+
+ final override fun visitMaxs(
+ maxStack: Int,
+ maxLocals: Int
+ ) {
+ if (emitCode) {
+ super.visitMaxs(maxStack, maxLocals)
+ }
+ }
+
+ // Following methods are called inside a method body, and we don't want to
+ // emit any of them, so they are all no-op.
+
+ final override fun visitFrame(
+ type: Int,
+ numLocal: Int,
+ local: Array<out Any>?,
+ numStack: Int,
+ stack: Array<out Any>?
+ ) {
+ if (emitCode) {
+ super.visitFrame(type, numLocal, local, numStack, stack)
+ }
+ }
+
+ final override fun visitInsn(opcode: Int) {
+ if (emitCode) {
+ super.visitInsn(opcode)
+ }
+ }
+
+ final override fun visitIntInsn(
+ opcode: Int,
+ operand: Int
+ ) {
+ if (emitCode) {
+ super.visitIntInsn(opcode, operand)
+ }
+ }
+
+ final override fun visitVarInsn(
+ opcode: Int,
+ varIndex: Int
+ ) {
+ if (emitCode) {
+ super.visitVarInsn(opcode, varIndex)
+ }
+ }
+
+ final override fun visitTypeInsn(
+ opcode: Int,
+ type: String?
+ ) {
+ if (emitCode) {
+ super.visitTypeInsn(opcode, type)
+ }
+ }
+
+ final override fun visitFieldInsn(
+ opcode: Int,
+ owner: String?,
+ name: String?,
+ descriptor: String?
+ ) {
+ if (emitCode) {
+ super.visitFieldInsn(opcode, owner, name, descriptor)
+ }
+ }
+
+ final override fun visitMethodInsn(
+ opcode: Int,
+ owner: String?,
+ name: String?,
+ descriptor: String?,
+ isInterface: Boolean
+ ) {
+ if (emitCode) {
+ super.visitMethodInsn(opcode, owner, name, descriptor, isInterface)
+ }
+ }
+
+ final override fun visitInvokeDynamicInsn(
+ name: String?,
+ descriptor: String?,
+ bootstrapMethodHandle: Handle?,
+ vararg bootstrapMethodArguments: Any?
+ ) {
+ if (emitCode) {
+ super.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle,
+ *bootstrapMethodArguments)
+ }
+ }
+
+ final override fun visitJumpInsn(
+ opcode: Int,
+ label: Label?
+ ) {
+ if (emitCode) {
+ super.visitJumpInsn(opcode, label)
+ }
+ }
+
+ final override fun visitLabel(label: Label?) {
+ if (emitCode) {
+ super.visitLabel(label)
+ }
+ }
+
+ final override fun visitLdcInsn(value: Any?) {
+ if (emitCode) {
+ super.visitLdcInsn(value)
+ }
+ }
+
+ final override fun visitIincInsn(
+ varIndex: Int,
+ increment: Int
+ ) {
+ if (emitCode) {
+ super.visitIincInsn(varIndex, increment)
+ }
+ }
+
+ final override fun visitTableSwitchInsn(
+ min: Int,
+ max: Int,
+ dflt: Label?,
+ vararg labels: Label?
+ ) {
+ if (emitCode) {
+ super.visitTableSwitchInsn(min, max, dflt, *labels)
+ }
+ }
+
+ final override fun visitLookupSwitchInsn(
+ dflt: Label?,
+ keys: IntArray?,
+ labels: Array<out Label>?
+ ) {
+ if (emitCode) {
+ super.visitLookupSwitchInsn(dflt, keys, labels)
+ }
+ }
+
+ final override fun visitMultiANewArrayInsn(
+ descriptor: String?,
+ numDimensions: Int
+ ) {
+ if (emitCode) {
+ super.visitMultiANewArrayInsn(descriptor, numDimensions)
+ }
+ }
+
+ final override fun visitInsnAnnotation(
+ typeRef: Int,
+ typePath: TypePath?,
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ if (emitCode) {
+ return super.visitInsnAnnotation(typeRef, typePath, descriptor, visible)
+ }
+ return null
+ }
+
+ final override fun visitTryCatchBlock(
+ start: Label?,
+ end: Label?,
+ handler: Label?,
+ type: String?
+ ) {
+ if (emitCode) {
+ super.visitTryCatchBlock(start, end, handler, type)
+ }
+ }
+
+ final override fun visitTryCatchAnnotation(
+ typeRef: Int,
+ typePath: TypePath?,
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ if (emitCode) {
+ return super.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible)
+ }
+ return null
+ }
+
+ final override fun visitLocalVariable(
+ name: String?,
+ descriptor: String?,
+ signature: String?,
+ start: Label?,
+ end: Label?,
+ index: Int
+ ) {
+ if (emitCode) {
+ super.visitLocalVariable(name, descriptor, signature, start, end, index)
+ }
+ }
+
+ final override fun visitLocalVariableAnnotation(
+ typeRef: Int,
+ typePath: TypePath?,
+ start: Array<out Label>?,
+ end: Array<out Label>?,
+ index: IntArray?,
+ descriptor: String?,
+ visible: Boolean
+ ): AnnotationVisitor? {
+ if (emitCode) {
+ return super.visitLocalVariableAnnotation(
+ typeRef, typePath, start, end, index, descriptor, visible)
+ }
+ return null
+ }
+
+ final override fun visitLineNumber(
+ line: Int,
+ start: Label?
+ ) {
+ if (emitCode) {
+ super.visitLineNumber(line, start)
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
new file mode 100644
index 000000000000..88db15b86143
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/ImplGeneratingAdapter.kt
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.visitors
+
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_DESC
+import com.android.hoststubgen.asm.CLASS_INITIALIZER_NAME
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.asm.isVisibilityPrivateOrPackagePrivate
+import com.android.hoststubgen.asm.prependArgTypeToMethodDescriptor
+import com.android.hoststubgen.asm.writeByteCodeToPushArguments
+import com.android.hoststubgen.asm.writeByteCodeToReturn
+import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.hosthelper.HostTestUtils
+import com.android.hoststubgen.log
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+import org.objectweb.asm.Type
+
+/**
+ * An adapter that generates the "impl" class file from an input class file.
+ */
+class ImplGeneratingAdapter(
+ classes: ClassNodes,
+ nextVisitor: ClassVisitor,
+ filter: OutputFilter,
+ options: Options,
+) : BaseAdapter(classes, nextVisitor, filter, options) {
+
+ override fun shouldEmit(policy: FilterPolicy): Boolean {
+ return policy.needsInImpl
+ }
+
+ private var classLoadHooks: List<String> = emptyList()
+
+ override fun visit(
+ version: Int,
+ access: Int,
+ name: String,
+ signature: String?,
+ superName: String?,
+ interfaces: Array<String>
+ ) {
+ super.visit(version, access, name, signature, superName, interfaces)
+
+ classLoadHooks = filter.getClassLoadHooks(currentClassName)
+
+ // classLoadHookMethod is non-null, then we need to inject code to call it
+ // in the class initializer.
+ // If the target class already has a class initializer, then we need to inject code to it.
+ // Otherwise, we need to create one.
+
+ if (classLoadHooks.isNotEmpty()) {
+ log.d(" ClassLoadHooks: $classLoadHooks")
+ if (!classes.hasClassInitializer(currentClassName)) {
+ injectClassLoadHook()
+ }
+ }
+ }
+
+ private fun injectClassLoadHook() {
+ writeRawMembers {
+ // Create a class initializer to call onClassLoaded().
+ // Each class can only have at most one class initializer, but the base class
+ // StaticInitMerger will merge it with the existing one, if any.
+ visitMethod(
+ Opcodes.ACC_PRIVATE or Opcodes.ACC_STATIC,
+ CLASS_INITIALIZER_NAME,
+ "()V",
+ null,
+ null
+ )!!.let { mv ->
+ // Method prologue
+ mv.visitCode()
+
+ writeClassLoadHookCalls(mv)
+ mv.visitInsn(Opcodes.RETURN)
+
+ // Method epilogue
+ mv.visitMaxs(0, 0)
+ mv.visitEnd()
+ }
+ }
+ }
+
+ private fun writeClassLoadHookCalls(mv: MethodVisitor) {
+ classLoadHooks.forEach { classLoadHook ->
+ // First argument: the class type.
+ mv.visitLdcInsn(Type.getType("L" + currentClassName + ";"))
+
+ // Second argument: method name
+ mv.visitLdcInsn(classLoadHook)
+
+ // Call HostTestUtils.onClassLoaded().
+ mv.visitMethodInsn(
+ Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "onClassLoaded",
+ "(Ljava/lang/Class;Ljava/lang/String;)V",
+ false
+ )
+ }
+ }
+
+ override fun updateAccessFlags(
+ access: Int,
+ name: String,
+ descriptor: String,
+ ): Int {
+ if ((access and Opcodes.ACC_NATIVE) != 0 && nativeSubstitutionClass != null) {
+ return access and Opcodes.ACC_NATIVE.inv()
+ }
+ return access
+ }
+
+ override fun visitMethodInner(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ policy: FilterPolicyWithReason,
+ superVisitor: MethodVisitor?,
+ ): MethodVisitor? {
+ // Inject method log, if needed.
+ var innerVisitor = superVisitor
+
+ // If method logging is enabled, inject call to the logging method.
+ val methodCallHooks = filter.getMethodCallHooks(currentClassName, name, descriptor)
+ if (methodCallHooks.isNotEmpty()) {
+ innerVisitor = MethodCallHookInjectingAdapter(
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions,
+ innerVisitor,
+ methodCallHooks,
+ )
+ }
+
+ // If this class already has a class initializer and a class load hook is needed, then
+ // we inject code.
+ if (classLoadHooks.isNotEmpty() &&
+ name == CLASS_INITIALIZER_NAME &&
+ descriptor == CLASS_INITIALIZER_DESC) {
+ innerVisitor = ClassLoadHookInjectingMethodAdapter(
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions,
+ innerVisitor,
+ )
+ }
+
+ // If non-stub method call detection is enabled, then inject a call to the checker.
+ if (options.enableNonStubMethodCallDetection && doesMethodNeedNonStubCallCheck(
+ access, name, descriptor, policy) ) {
+ innerVisitor = NonStubMethodCallDetectingAdapter(
+ access,
+ name,
+ descriptor,
+ signature,
+ exceptions,
+ innerVisitor,
+ )
+ }
+
+ log.withIndent {
+ if ((access and Opcodes.ACC_NATIVE) != 0 && nativeSubstitutionClass != null) {
+ log.v("Rewriting native method...")
+ return NativeSubstitutingMethodAdapter(
+ access, name, descriptor, signature, exceptions, innerVisitor)
+ }
+ if (policy.policy == FilterPolicy.Throw) {
+ log.v("Making method throw...")
+ return ThrowingMethodAdapter(
+ access, name, descriptor, signature, exceptions, innerVisitor)
+ }
+ if (policy.policy == FilterPolicy.Ignore) {
+ when (Type.getReturnType(descriptor)) {
+ Type.VOID_TYPE -> {
+ log.v("Making method ignored...")
+ return IgnoreMethodAdapter(
+ access, name, descriptor, signature, exceptions, innerVisitor)
+ }
+ else -> {
+ throw RuntimeException("Ignored policy only allowed for void methods")
+ }
+ }
+ }
+ }
+
+ return innerVisitor
+ }
+
+ fun doesMethodNeedNonStubCallCheck(
+ access: Int,
+ name: String,
+ descriptor: String,
+ policy: FilterPolicyWithReason,
+ ): Boolean {
+ // If a method is in the stub, then no need to check.
+ if (policy.policy.needsInStub) {
+ return false
+ }
+ // If a method is private or package-private, no need to check.
+ // Technically test code can use framework package name, so it's a bit too lenient.
+ if (isVisibilityPrivateOrPackagePrivate(access)) {
+ return false
+ }
+ // TODO: If the method overrides a method that's accessible by tests, then we shouldn't
+ // do the check. (e.g. overrides a stub method or java standard method.)
+
+ return true
+ }
+
+ /**
+ * A method adapter that replaces the method body with a HostTestUtils.onThrowMethodCalled()
+ * call.
+ */
+ private inner class ThrowingMethodAdapter(
+ access: Int,
+ val name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : BodyReplacingMethodVisitor(access, name, descriptor, signature, exceptions, next) {
+ override fun emitNewCode() {
+ visitMethodInsn(Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "onThrowMethodCalled",
+ "()V",
+ false)
+
+ // We still need a RETURN opcode for the return type.
+ // For now, let's just inject a `throw`.
+ visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException")
+ visitInsn(Opcodes.DUP)
+ visitLdcInsn("Unreachable")
+ visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException",
+ "<init>", "(Ljava/lang/String;)V", false)
+ visitInsn(Opcodes.ATHROW)
+
+ // visitMaxs(3, if (isStatic) 0 else 1)
+ visitMaxs(0, 0) // We let ASM figure them out.
+ }
+ }
+
+ /**
+ * A method adapter that replaces the method body with a no-op return.
+ */
+ private inner class IgnoreMethodAdapter(
+ access: Int,
+ val name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : BodyReplacingMethodVisitor(access, name, descriptor, signature, exceptions, next) {
+ override fun emitNewCode() {
+ visitInsn(Opcodes.RETURN)
+ visitMaxs(0, 0) // We let ASM figure them out.
+ }
+ }
+
+ /**
+ * A method adapter that replaces a native method call with a call to the "native substitution"
+ * class.
+ */
+ private inner class NativeSubstitutingMethodAdapter(
+ val access: Int,
+ private val name: String,
+ private val descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : MethodVisitor(OPCODE_VERSION, next) {
+ override fun visitCode() {
+ super.visitCode()
+
+ throw RuntimeException("NativeSubstitutingMethodVisitor should be called on " +
+ " native method, where visitCode() shouldn't be called.")
+ }
+
+ override fun visitEnd() {
+ var targetDescriptor = descriptor
+ var argOffset = 0
+
+ // For non-static native method, we need to tweak it a bit.
+ if ((access and Opcodes.ACC_STATIC) == 0) {
+ // Push `this` as the first argument.
+ this.visitVarInsn(Opcodes.ALOAD, 0)
+
+ // Update the descriptor -- add this class's type as the first argument
+ // to the method descriptor.
+ val thisType = Type.getType("L" + currentClassName + ";")
+
+ targetDescriptor = prependArgTypeToMethodDescriptor(
+ descriptor,
+ thisType,
+ )
+
+ // Shift the original arguments by one.
+ argOffset = 1
+ }
+
+ writeByteCodeToPushArguments(descriptor, this, argOffset)
+
+ visitMethodInsn(Opcodes.INVOKESTATIC,
+ nativeSubstitutionClass,
+ name,
+ targetDescriptor,
+ false)
+
+ writeByteCodeToReturn(descriptor, this)
+
+ visitMaxs(99, 0) // We let ASM figure them out.
+ super.visitEnd()
+ }
+ }
+
+ /**
+ * Inject calls to the method call hooks.
+ *
+ * Note, when the target method is a constructor, it may contain calls to `super(...)` or
+ * `this(...)`. The logging code will be injected *before* such calls.
+ */
+ private inner class MethodCallHookInjectingAdapter(
+ access: Int,
+ val name: String,
+ val descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?,
+ val hooks: List<String>,
+ ) : MethodVisitor(OPCODE_VERSION, next) {
+ override fun visitCode() {
+ super.visitCode()
+
+ hooks.forEach { hook ->
+ mv.visitLdcInsn(Type.getType("L" + currentClassName + ";"))
+ visitLdcInsn(name)
+ visitLdcInsn(descriptor)
+ visitLdcInsn(hook)
+
+ visitMethodInsn(
+ Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "callMethodCallHook",
+ "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
+ false
+ )
+ }
+ }
+ }
+
+ /**
+ * Inject a class load hook call.
+ */
+ private inner class ClassLoadHookInjectingMethodAdapter(
+ access: Int,
+ val name: String,
+ val descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : MethodVisitor(OPCODE_VERSION, next) {
+ override fun visitCode() {
+ super.visitCode()
+
+ writeClassLoadHookCalls(this)
+ }
+ }
+
+ /**
+ * A method adapter that detects calls to non-stub methods.
+ */
+ private inner class NonStubMethodCallDetectingAdapter(
+ access: Int,
+ val name: String,
+ val descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : MethodVisitor(OPCODE_VERSION, next) {
+ override fun visitCode() {
+ super.visitCode()
+
+ // First three arguments to HostTestUtils.onNonStubMethodCalled().
+ visitLdcInsn(currentClassName)
+ visitLdcInsn(name)
+ visitLdcInsn(descriptor)
+
+ // Call: HostTestUtils.getStackWalker().getCallerClass().
+ // This push the caller Class in the stack.
+ visitMethodInsn(Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "getStackWalker",
+ "()Ljava/lang/StackWalker;",
+ false)
+ visitMethodInsn(Opcodes.INVOKEVIRTUAL,
+ "java/lang/StackWalker",
+ "getCallerClass",
+ "()Ljava/lang/Class;",
+ false)
+
+ // Then call onNonStubMethodCalled().
+ visitMethodInsn(Opcodes.INVOKESTATIC,
+ HostTestUtils.CLASS_INTERNAL_NAME,
+ "onNonStubMethodCalled",
+ "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V",
+ false)
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt
new file mode 100644
index 000000000000..b3790e12a111
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/PackageRedirectRemapper.kt
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.visitors
+
+import com.android.hoststubgen.asm.toJvmClassName
+import org.objectweb.asm.commons.Remapper
+
+/**
+ * A [Remapper] for `--package-redirect`
+ */
+class PackageRedirectRemapper(
+ packageRedirects: List<Pair<String, String>>,
+ ) : Remapper() {
+
+ /**
+ * Example: `dalvik/` -> `com/android/hostsubgen/substitution/dalvik/`
+ */
+ private val packageRedirectsWithSlash: List<Pair<String, String>> = packageRedirects.map {
+ p -> Pair(p.first.toJvmClassName() + "/", p.second.toJvmClassName() + "/")
+ }
+
+ /**
+ * Cache.
+ * If a class is a redirect-from class, then the "to" class name will be stored as the value.
+ * Otherwise, "" will be stored.
+ */
+ private val cache = mutableMapOf<String, String>()
+
+ /**
+ * Return whether any redirect is defined.
+ */
+ val isEmpty get() = packageRedirectsWithSlash.isEmpty()
+
+ override fun map(internalName: String?): String? {
+ if (internalName == null) {
+ return null
+ }
+ val to = mapInner(internalName)
+ return to ?: internalName
+ }
+
+ /**
+ * Internal "map" function. Unlike [map(String)], this method will return null
+ * if a class is not a redirect-from class.
+ */
+ private fun mapInner(internalName: String): String? {
+ cache[internalName]?.let {
+ return if (it.isEmpty()) null else it
+ }
+
+ var ret = ""
+ packageRedirectsWithSlash.forEach { fromTo ->
+ if (internalName.startsWith(fromTo.first)) {
+ ret = fromTo.second + internalName.substring(fromTo.first.length)
+ }
+ }
+ cache.set(internalName, ret)
+
+ return if (ret.isEmpty()) null else ret
+ }
+
+ /**
+ * Return true if a class is a redirect-from class.
+ */
+ fun isTarget(internalName: String): Boolean {
+ return mapInner(internalName) != null
+ }
+}
+
diff --git a/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/StubGeneratingAdapter.kt b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/StubGeneratingAdapter.kt
new file mode 100644
index 000000000000..37e2a888969d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/src/com/android/hoststubgen/visitors/StubGeneratingAdapter.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.visitors
+
+import com.android.hoststubgen.asm.ClassNodes
+import com.android.hoststubgen.filters.FilterPolicy
+import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.log
+import org.objectweb.asm.ClassVisitor
+import org.objectweb.asm.MethodVisitor
+import org.objectweb.asm.Opcodes
+
+/**
+ * An adapter that generates the "impl" class file from an input class file.
+ */
+class StubGeneratingAdapter(
+ classes: ClassNodes,
+ nextVisitor: ClassVisitor,
+ filter: OutputFilter,
+ options: Options,
+) : BaseAdapter(classes, nextVisitor, filter, options) {
+
+ override fun shouldEmit(policy: FilterPolicy): Boolean {
+ return policy.needsInStub
+ }
+
+ override fun visitMethodInner(
+ access: Int,
+ name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ policy: FilterPolicyWithReason,
+ superVisitor: MethodVisitor?,
+ ): MethodVisitor? {
+ return StubMethodVisitor(access, name, descriptor, signature, exceptions, superVisitor)
+ }
+
+ private inner class StubMethodVisitor(
+ access: Int,
+ val name: String,
+ descriptor: String,
+ signature: String?,
+ exceptions: Array<String>?,
+ next: MethodVisitor?
+ ) : BodyReplacingMethodVisitor(access, name, descriptor, signature, exceptions, next) {
+ override fun emitNewCode() {
+ log.d(" Generating stub method for $currentClassName.$name")
+
+ // Inject the following code:
+ // throw new RuntimeException("Stub!");
+
+ /*
+ NEW java/lang/RuntimeException
+ DUP
+ LDC "not supported on host side"
+ INVOKESPECIAL java/lang/RuntimeException.<init> (Ljava/lang/String;)V
+ ATHROW
+ MAXSTACK = 3
+ MAXLOCALS = 2 <- 1 for this, 1 for return value.
+ */
+ visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException")
+ visitInsn(Opcodes.DUP)
+ visitLdcInsn("Stub!")
+ visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException",
+ "<init>", "(Ljava/lang/String;)V", false)
+ visitInsn(Opcodes.ATHROW)
+ visitMaxs(0, 0) // We let ASM figure them out.
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-framework/Android.bp
new file mode 100644
index 000000000000..2b91cc161b7f
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/Android.bp
@@ -0,0 +1,19 @@
+// Copyright (C) 2023 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+build = ["AndroidHostTest.bp"]
diff --git a/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
new file mode 100644
index 000000000000..1f8382ad468d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/AndroidHostTest.bp
@@ -0,0 +1,57 @@
+// Copyright (C) 2023 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.
+
+// Add `build = ["AndroidHostTest.bp"]` to Android.bp to include this file.
+
+// Compile the test jar, using 2 rules.
+// 1. Build the test against the stub.
+java_library_host {
+ name: "HostStubGenTest-framework-test-host-test-lib",
+ defaults: ["hosttest-with-framework-all-hidden-api-test-lib-defaults"],
+ srcs: [
+ "src/**/*.java",
+ ],
+ static_libs: [
+ "junit",
+ "truth",
+ "mockito",
+
+ // http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
+ "platform-test-annotations",
+ "hoststubgen-annotations",
+ ],
+}
+
+// 2. Link the above module with necessary runtime dependencies, so it can be executed stand-alone.
+java_test_host {
+ name: "HostStubGenTest-framework-all-test-host-test",
+ defaults: ["hosttest-with-framework-all-hidden-api-test-defaults"],
+ static_libs: [
+ "HostStubGenTest-framework-test-host-test-lib",
+ ],
+ test_suites: ["general-tests"],
+}
+
+// "Productionized" build rule.
+android_ravenwood_test {
+ name: "HostStubGenTest-framework-test",
+ srcs: [
+ "src/**/*.java",
+ ],
+ static_libs: [
+ "junit",
+ "truth",
+ "mockito",
+ ],
+}
diff --git a/tools/hoststubgen/hoststubgen/test-framework/AndroidTest-host.xml b/tools/hoststubgen/hoststubgen/test-framework/AndroidTest-host.xml
new file mode 100644
index 000000000000..f35dcf69ecc9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/AndroidTest-host.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+
+<!-- [Ravenwood] Copied from $ANDROID_BUILD_TOP/cts/hostsidetests/devicepolicy/AndroidTest.xml -->
+<configuration description="CtsContentTestCases host-side test">
+ <option name="test-suite-tag" value="ravenwood" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
+
+ <test class="com.android.tradefed.testtype.IsolatedHostTest" >
+ <option name="jar" value="HostStubGenTest-framework-all-test-host-test.jar" />
+ </test>
+</configuration>
diff --git a/tools/hoststubgen/hoststubgen/test-framework/README.md b/tools/hoststubgen/hoststubgen/test-framework/README.md
new file mode 100644
index 000000000000..f616ad61d219
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/README.md
@@ -0,0 +1,21 @@
+# HostStubGen: real framework test
+
+This directory contains tests against the actual framework.jar code. The tests were
+copied from somewhere else in the android tree. We use this directory to quickly run existing
+tests.
+
+## How to run
+
+- With `atest`. This is the proper way to run it, but it may fail due to atest's known problems.
+
+ See the top level README.md on why `--no-bazel-mode` is needed (for now).
+
+```
+$ atest --no-bazel-mode HostStubGenTest-framework-test-host-test
+```
+
+- Advanced option: `run-test-without-atest.sh` runs the test without using `atest` or `run-ravenwood-test`
+
+```
+$ ./run-test-without-atest.sh
+``` \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/test-framework/run-test-without-atest.sh b/tools/hoststubgen/hoststubgen/test-framework/run-test-without-atest.sh
new file mode 100755
index 000000000000..cfc06a12e881
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/run-test-without-atest.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+# Run HostStubGenTest-framework-test-host-test directly with JUnit.
+# (without using atest.)
+
+source "${0%/*}"/../../common.sh
+
+
+# Options:
+# -v enable verbose log
+# -d enable debugger
+
+verbose=0
+debug=0
+while getopts "vd" opt; do
+ case "$opt" in
+ v) verbose=1 ;;
+ d) debug=1 ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+
+if (( $verbose )) ; then
+ JAVA_OPTS="$JAVA_OPTS -verbose:class"
+fi
+
+if (( $debug )) ; then
+ JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8700"
+fi
+
+#=======================================
+module=HostStubGenTest-framework-all-test-host-test
+module_jar=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/$module/$module.jar
+run m $module
+
+out=out
+
+rm -fr $out
+mkdir -p $out
+
+
+# Copy and extract the relevant jar files so we can look into them.
+run cp \
+ $module_jar \
+ $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/framework-all-hidden-api-host/linux_glibc_common/gen/*.jar \
+ $out
+
+run extract $out/*.jar
+
+# Result is the number of failed tests.
+result=0
+
+
+# This suite runs all tests in the JAR.
+tests=(com.android.hoststubgen.hosthelper.HostTestSuite)
+
+# Uncomment this to run a specific test.
+# tests=(com.android.hoststubgen.frameworktest.LogTest)
+
+
+for class in ${tests[@]} ; do
+ echo "Running $class ..."
+
+ run cd "${module_jar%/*}"
+ run $JAVA $JAVA_OPTS \
+ -cp $module_jar \
+ org.junit.runner.JUnitCore \
+ $class || result=$(( $result + 1 ))
+done
+
+exit $result
diff --git a/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/ArrayMapTest.java b/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/ArrayMapTest.java
new file mode 100644
index 000000000000..2c5949c1c630
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/ArrayMapTest.java
@@ -0,0 +1,472 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.frameworktest;
+
+// [ravewnwood] Copied from cts/, and commented out unsupported stuff.
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.util.ArrayMap;
+import android.util.Log;
+
+import org.junit.Test;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.function.BiFunction;
+
+/**
+ * Some basic tests for {@link android.util.ArrayMap}.
+ */
+public class ArrayMapTest {
+ static final boolean DEBUG = false;
+
+ private static boolean compare(Object v1, Object v2) {
+ if (v1 == null) {
+ return v2 == null;
+ }
+ if (v2 == null) {
+ return false;
+ }
+ return v1.equals(v2);
+ }
+
+ private static void compareMaps(HashMap map, ArrayMap array) {
+ if (map.size() != array.size()) {
+ fail("Bad size: expected " + map.size() + ", got " + array.size());
+ }
+
+ Set<Entry> mapSet = map.entrySet();
+ for (Map.Entry entry : mapSet) {
+ Object expValue = entry.getValue();
+ Object gotValue = array.get(entry.getKey());
+ if (!compare(expValue, gotValue)) {
+ fail("Bad value: expected " + expValue + ", got " + gotValue
+ + " at key " + entry.getKey());
+ }
+ }
+
+ for (int i = 0; i < array.size(); i++) {
+ Object gotValue = array.valueAt(i);
+ Object key = array.keyAt(i);
+ Object expValue = map.get(key);
+ if (!compare(expValue, gotValue)) {
+ fail("Bad value: expected " + expValue + ", got " + gotValue
+ + " at key " + key);
+ }
+ }
+
+ if (map.entrySet().hashCode() != array.entrySet().hashCode()) {
+ fail("Entry set hash codes differ: map=0x"
+ + Integer.toHexString(map.entrySet().hashCode()) + " array=0x"
+ + Integer.toHexString(array.entrySet().hashCode()));
+ }
+
+ if (!map.entrySet().equals(array.entrySet())) {
+ fail("Failed calling equals on map entry set against array set");
+ }
+
+ if (!array.entrySet().equals(map.entrySet())) {
+ fail("Failed calling equals on array entry set against map set");
+ }
+
+ if (map.keySet().hashCode() != array.keySet().hashCode()) {
+ fail("Key set hash codes differ: map=0x"
+ + Integer.toHexString(map.keySet().hashCode()) + " array=0x"
+ + Integer.toHexString(array.keySet().hashCode()));
+ }
+
+ if (!map.keySet().equals(array.keySet())) {
+ fail("Failed calling equals on map key set against array set");
+ }
+
+ if (!array.keySet().equals(map.keySet())) {
+ fail("Failed calling equals on array key set against map set");
+ }
+
+ if (!map.keySet().containsAll(array.keySet())) {
+ fail("Failed map key set contains all of array key set");
+ }
+
+ if (!array.keySet().containsAll(map.keySet())) {
+ fail("Failed array key set contains all of map key set");
+ }
+
+ if (!array.containsAll(map.keySet())) {
+ fail("Failed array contains all of map key set");
+ }
+
+ if (!map.entrySet().containsAll(array.entrySet())) {
+ fail("Failed map entry set contains all of array entry set");
+ }
+
+ if (!array.entrySet().containsAll(map.entrySet())) {
+ fail("Failed array entry set contains all of map entry set");
+ }
+ }
+
+ private static void validateArrayMap(ArrayMap array) {
+ Set<Map.Entry> entrySet = array.entrySet();
+ int index = 0;
+ Iterator<Entry> entryIt = entrySet.iterator();
+ while (entryIt.hasNext()) {
+ Map.Entry entry = entryIt.next();
+ Object value = entry.getKey();
+ Object realValue = array.keyAt(index);
+ if (!compare(realValue, value)) {
+ fail("Bad array map entry set: expected key " + realValue
+ + ", got " + value + " at index " + index);
+ }
+ value = entry.getValue();
+ realValue = array.valueAt(index);
+ if (!compare(realValue, value)) {
+ fail("Bad array map entry set: expected value " + realValue
+ + ", got " + value + " at index " + index);
+ }
+ index++;
+ }
+
+ index = 0;
+ Set keySet = array.keySet();
+ Iterator keyIt = keySet.iterator();
+ while (keyIt.hasNext()) {
+ Object value = keyIt.next();
+ Object realValue = array.keyAt(index);
+ if (!compare(realValue, value)) {
+ fail("Bad array map key set: expected key " + realValue
+ + ", got " + value + " at index " + index);
+ }
+ index++;
+ }
+
+ index = 0;
+ Collection valueCol = array.values();
+ Iterator valueIt = valueCol.iterator();
+ while (valueIt.hasNext()) {
+ Object value = valueIt.next();
+ Object realValue = array.valueAt(index);
+ if (!compare(realValue, value)) {
+ fail("Bad array map value col: expected value " + realValue
+ + ", got " + value + " at index " + index);
+ }
+ index++;
+ }
+ }
+
+ private static void dump(Map map, ArrayMap array) {
+ Log.e("test", "HashMap of " + map.size() + " entries:");
+ Set<Map.Entry> mapSet = map.entrySet();
+ for (Map.Entry entry : mapSet) {
+ Log.e("test", " " + entry.getKey() + " -> " + entry.getValue());
+ }
+ Log.e("test", "ArrayMap of " + array.size() + " entries:");
+ for (int i = 0; i < array.size(); i++) {
+ Log.e("test", " " + array.keyAt(i) + " -> " + array.valueAt(i));
+ }
+ }
+
+ private static void dump(ArrayMap map1, ArrayMap map2) {
+ Log.e("test", "ArrayMap of " + map1.size() + " entries:");
+ for (int i = 0; i < map1.size(); i++) {
+ Log.e("test", " " + map1.keyAt(i) + " -> " + map1.valueAt(i));
+ }
+ Log.e("test", "ArrayMap of " + map2.size() + " entries:");
+ for (int i = 0; i < map2.size(); i++) {
+ Log.e("test", " " + map2.keyAt(i) + " -> " + map2.valueAt(i));
+ }
+ }
+
+ @Test
+ public void testCopyArrayMap() {
+ // map copy constructor test
+ ArrayMap newMap = new ArrayMap<Integer, String>();
+ for (int i = 0; i < 10; ++i) {
+ newMap.put(i, String.valueOf(i));
+ }
+ ArrayMap mapCopy = new ArrayMap(newMap);
+ if (!compare(mapCopy, newMap)) {
+ String msg = "ArrayMap copy constructor failure: expected " +
+ newMap + ", got " + mapCopy;
+ Log.e("test", msg);
+ dump(newMap, mapCopy);
+ fail(msg);
+ return;
+ }
+ }
+
+ @Test
+ public void testEqualsArrayMap() {
+ ArrayMap<Integer, String> map1 = new ArrayMap<>();
+ ArrayMap<Integer, String> map2 = new ArrayMap<>();
+ HashMap<Integer, String> map3 = new HashMap<>();
+ if (!compare(map1, map2) || !compare(map1, map3) || !compare(map3, map2)) {
+ fail("ArrayMap equals failure for empty maps " + map1 + ", " +
+ map2 + ", " + map3);
+ }
+
+ for (int i = 0; i < 10; ++i) {
+ String value = String.valueOf(i);
+ map1.put(i, value);
+ map2.put(i, value);
+ map3.put(i, value);
+ }
+ if (!compare(map1, map2) || !compare(map1, map3) || !compare(map3, map2)) {
+ fail("ArrayMap equals failure for populated maps " + map1 + ", " +
+ map2 + ", " + map3);
+ }
+
+ map1.remove(0);
+ if (compare(map1, map2) || compare(map1, map3) || compare(map3, map1)) {
+ fail("ArrayMap equals failure for map size " + map1 + ", " +
+ map2 + ", " + map3);
+ }
+
+ map1.put(0, "-1");
+ if (compare(map1, map2) || compare(map1, map3) || compare(map3, map1)) {
+ fail("ArrayMap equals failure for map contents " + map1 + ", " +
+ map2 + ", " + map3);
+ }
+ }
+
+ private static void checkEntrySetToArray(ArrayMap<?, ?> testMap) {
+ try {
+ testMap.entrySet().toArray();
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+
+ try {
+ Map.Entry<?, ?>[] entries = new Map.Entry[20];
+ testMap.entrySet().toArray(entries);
+ fail();
+ } catch (UnsupportedOperationException expected) {
+ }
+ }
+
+ // http://b/32294038, Test ArrayMap.entrySet().toArray()
+ @Test
+ public void testEntrySetArray() {
+ // Create
+ ArrayMap<Integer, String> testMap = new ArrayMap<>();
+
+ // Test empty
+ checkEntrySetToArray(testMap);
+
+ // Test non-empty
+ for (int i = 0; i < 10; ++i) {
+ testMap.put(i, String.valueOf(i));
+ }
+ checkEntrySetToArray(testMap);
+ }
+
+ @Test
+ public void testCanNotIteratePastEnd_entrySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<Map.Entry<String, String>> expectedEntriesToIterate = new HashSet<>(Arrays.asList(
+ entryOf("key 1", "value 1"),
+ entryOf("key 2", "value 2")
+ ));
+ Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
+
+ // Assert iteration over the expected two entries in any order
+ assertTrue(iterator.hasNext());
+ Map.Entry<String, String> firstEntry = copyOf(iterator.next());
+ assertTrue(expectedEntriesToIterate.remove(firstEntry));
+
+ assertTrue(iterator.hasNext());
+ Map.Entry<String, String> secondEntry = copyOf(iterator.next());
+ assertTrue(expectedEntriesToIterate.remove(secondEntry));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ private static <K, V> Map.Entry<K, V> entryOf(K key, V value) {
+ return new AbstractMap.SimpleEntry<>(key, value);
+ }
+
+ private static <K, V> Map.Entry<K, V> copyOf(Map.Entry<K, V> entry) {
+ return entryOf(entry.getKey(), entry.getValue());
+ }
+
+ @Test
+ public void testCanNotIteratePastEnd_keySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<String> expectedKeysToIterate = new HashSet<>(Arrays.asList("key 1", "key 2"));
+ Iterator<String> iterator = map.keySet().iterator();
+
+ // Assert iteration over the expected two keys in any order
+ assertTrue(iterator.hasNext());
+ String firstKey = iterator.next();
+ assertTrue(expectedKeysToIterate.remove(firstKey));
+
+ assertTrue(iterator.hasNext());
+ String secondKey = iterator.next();
+ assertTrue(expectedKeysToIterate.remove(secondKey));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ @Test
+ public void testCanNotIteratePastEnd_valuesIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Set<String> expectedValuesToIterate = new HashSet<>(Arrays.asList("value 1", "value 2"));
+ Iterator<String> iterator = map.values().iterator();
+
+ // Assert iteration over the expected two values in any order
+ assertTrue(iterator.hasNext());
+ String firstValue = iterator.next();
+ assertTrue(expectedValuesToIterate.remove(firstValue));
+
+ assertTrue(iterator.hasNext());
+ String secondValue = iterator.next();
+ assertTrue(expectedValuesToIterate.remove(secondValue));
+
+ assertFalse(iterator.hasNext());
+
+ try {
+ iterator.next();
+ fail();
+ } catch (NoSuchElementException expected) {
+ }
+ }
+
+ @Test
+ public void testForEach() {
+ ArrayMap<String, Integer> map = new ArrayMap<>();
+
+ for (int i = 0; i < 50; ++i) {
+ map.put(Integer.toString(i), i * 10);
+ }
+
+ // Make sure forEach goes through all of the elements.
+ HashMap<String, Integer> seen = new HashMap<>();
+ map.forEach(seen::put);
+ compareMaps(seen, map);
+ }
+
+ /**
+ * The entrySet Iterator returns itself from each call to {@code next()}. This is unusual
+ * behavior for {@link Iterator#next()}; this test ensures that any future change to this
+ * behavior is deliberate.
+ */
+ @Test
+ public void testUnusualBehavior_eachEntryIsSameAsIterator_entrySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
+
+ assertSame(iterator, iterator.next());
+ assertSame(iterator, iterator.next());
+ }
+
+ @SuppressWarnings("SelfEquals")
+ @Test
+ public void testUnusualBehavior_equalsThrowsAfterRemove_entrySetIterator() {
+ Map<String, String> map = new ArrayMap<>();
+ map.put("key 1", "value 1");
+ map.put("key 2", "value 2");
+ Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
+ iterator.next();
+ iterator.remove();
+ try {
+ iterator.equals(iterator);
+ fail();
+ } catch (IllegalStateException expected) {
+ }
+ }
+
+ private static <T> void assertEqualsBothWays(T a, T b) {
+ assertEquals(a, b);
+ assertEquals(b, a);
+ assertEquals(a.hashCode(), b.hashCode());
+ }
+
+ @Test
+ public void testRemoveAll() {
+ final ArrayMap<Integer, String> map = new ArrayMap<>();
+ for (Integer i : Arrays.asList(0, 1, 2, 3, 4, 5)) {
+ map.put(i, i.toString());
+ }
+
+ final ArrayMap<Integer, String> expectedMap = new ArrayMap<>();
+ for (Integer i : Arrays.asList(2, 4)) {
+ expectedMap.put(i, String.valueOf(i));
+ }
+ map.removeAll(Arrays.asList(0, 1, 3, 5, 6));
+ if (!compare(map, expectedMap)) {
+ fail("ArrayMap removeAll failure, expect " + expectedMap + ", but " + map);
+ }
+
+ map.removeAll(Collections.emptyList());
+ if (!compare(map, expectedMap)) {
+ fail("ArrayMap removeAll failure for empty maps, expect " + expectedMap + ", but " +
+ map);
+ }
+
+ map.removeAll(Arrays.asList(2, 4));
+ if (!map.isEmpty()) {
+ fail("ArrayMap removeAll failure, expect empty, but " + map);
+ }
+ }
+
+ @Test
+ public void testReplaceAll() {
+ final ArrayMap<Integer, Integer> map = new ArrayMap<>();
+ final ArrayMap<Integer, Integer> expectedMap = new ArrayMap<>();
+ final BiFunction<Integer, Integer, Integer> function = (k, v) -> 2 * v;
+ for (Integer i : Arrays.asList(0, 1, 2, 3, 4, 5)) {
+ map.put(i, i);
+ expectedMap.put(i, 2 * i);
+ }
+
+ map.replaceAll(function);
+ if (!compare(map, expectedMap)) {
+ fail("ArrayMap replaceAll failure, expect " + expectedMap + ", but " + map);
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/LogTest.java b/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/LogTest.java
new file mode 100644
index 000000000000..3e33b54bb9f9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-framework/src/com/android/hoststubgen/frameworktest/LogTest.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.frameworktest;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.util.Log;
+
+import org.junit.Test;
+
+/**
+ * Some basic tests for {@link android.util.Log}.
+ */
+public class LogTest {
+ @Test
+ public void testBasicLogging() {
+ Log.v("TAG", "Test v log");
+ Log.d("TAG", "Test d log");
+ Log.i("TAG", "Test i log");
+ Log.w("TAG", "Test w log");
+ Log.e("TAG", "Test e log");
+ }
+
+ @Test
+ public void testNativeMethods() {
+ assertThat(Log.isLoggable("mytag", Log.INFO)).isTrue();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
new file mode 100644
index 000000000000..e7873d6eecc3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/Android.bp
@@ -0,0 +1,216 @@
+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"],
+}
+
+// A library that simulates framework-all.jar
+java_library {
+ name: "hoststubgen-test-tiny-framework",
+ installable: true,
+ host_supported: true,
+ srcs: ["tiny-framework/src/**/*.java"],
+ static_libs: [
+ "hoststubgen-annotations",
+ ],
+ visibility: ["//frameworks/base/tools/hoststubgen:__subpackages__"],
+}
+
+// Create stub/impl jars from "hoststubgen-test-tiny-framework", using the following 3 rules.
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host",
+ defaults: ["hoststubgen-command-defaults"],
+ cmd: hoststubgen_common_options +
+ "--in-jar $(location :hoststubgen-test-tiny-framework) " +
+ "--policy-override-file $(location policy-override-tiny-framework.txt) " +
+ "--package-redirect com.unsupported:com.supported ",
+ srcs: [
+ ":hoststubgen-test-tiny-framework",
+ "policy-override-tiny-framework.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-stub",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host{host_stub.jar}",
+ ],
+ out: [
+ "host_stub.jar",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-impl",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host{host_impl.jar}",
+ ],
+ out: [
+ "host_impl.jar",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Same as "hoststubgen-test-tiny-framework-host", but with more options, to test more hoststubgen
+// features.
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext",
+ defaults: ["hoststubgen-command-defaults"],
+ cmd: hoststubgen_common_options +
+ "--in-jar $(location :hoststubgen-test-tiny-framework) " +
+ "--policy-override-file $(location policy-override-tiny-framework.txt) " +
+ "--package-redirect com.unsupported:com.supported " +
+
+ // More options.
+ "--default-method-call-hook com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall " +
+ "--default-class-load-hook com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded ",
+ srcs: [
+ ":hoststubgen-test-tiny-framework",
+ "policy-override-tiny-framework.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-stub",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext{host_stub.jar}",
+ ],
+ out: [
+ "host_stub.jar",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-impl",
+ cmd: "cp $(in) $(out)",
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext{host_impl.jar}",
+ ],
+ out: [
+ "host_impl.jar",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Compile the test jar, using 2 rules.
+// 1. Build the test against the stub.
+java_library_host {
+ name: "hoststubgen-test-tiny-test-lib",
+ srcs: ["tiny-test/src/**/*.java"],
+
+ libs: [
+ "hoststubgen-test-tiny-framework-host-stub",
+ ],
+ static_libs: [
+ "junit",
+ "truth",
+
+ // http://cs/h/googleplex-android/platform/superproject/main/+/main:platform_testing/libraries/annotations/src/android/platform/test/annotations/
+ "platform-test-annotations",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// 2. Link "hoststubgen-test-tiny-test-lib" with necessary runtime dependencies, so it can be
+// executed stand-alone.
+java_test_host {
+ name: "hoststubgen-test-tiny-test",
+ test_config: "AndroidTest-host.xml",
+ static_libs: [
+ "hoststubgen-test-tiny-test-lib",
+ "hoststubgen-helper-runtime",
+ "hoststubgen-test-tiny-framework-host-impl",
+ ],
+ test_suites: ["general-tests"],
+}
+
+// Dump the original, stub and impl jars as text files.
+// We use them in test-and-update-golden.sh.
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-orig-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework",
+ ],
+ out: [
+ "01-hoststubgen-test-tiny-framework-orig-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-stub-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-stub",
+ ],
+ out: [
+ "02-hoststubgen-test-tiny-framework-host-stub-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-impl-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-impl",
+ ],
+ out: [
+ "03-hoststubgen-test-tiny-framework-host-impl-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-stub-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext-stub",
+ ],
+ out: [
+ "12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+java_genrule_host {
+ name: "hoststubgen-test-tiny-framework-host-ext-impl-dump",
+ defaults: ["hoststubgen-jar-dump-defaults"],
+ srcs: [
+ ":hoststubgen-test-tiny-framework-host-ext-impl",
+ ],
+ out: [
+ "13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt",
+ ],
+ visibility: ["//visibility:private"],
+}
+
+// Run it with `atest`. Compare the dump of the jar files to the golden output.
+python_test_host {
+ name: "tiny-framework-dump-test",
+ srcs: [
+ "tiny-framework-dump-test.py",
+ ],
+ data: [
+ "golden-output/*.txt",
+ ],
+ java_data: [
+ "hoststubgen-test-tiny-framework-host-stub-dump",
+ "hoststubgen-test-tiny-framework-host-impl-dump",
+ "hoststubgen-test-tiny-framework-orig-dump",
+ "hoststubgen-test-tiny-framework-host-ext-stub-dump",
+ "hoststubgen-test-tiny-framework-host-ext-impl-dump",
+ ],
+ test_suites: ["general-tests"],
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/AndroidTest-host.xml b/tools/hoststubgen/hoststubgen/test-tiny-framework/AndroidTest-host.xml
new file mode 100644
index 000000000000..84aad69c33bc
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/AndroidTest-host.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2023 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.
+-->
+
+<!-- [Ravenwood] Copied from $ANDROID_BUILD_TOP/cts/hostsidetests/devicepolicy/AndroidTest.xml -->
+<configuration description="HostStubGen sample test">
+ <option name="test-suite-tag" value="ravenwood" />
+ <option name="config-descriptor:metadata" key="component" value="framework" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
+ <option name="config-descriptor:metadata" key="parameter" value="not_secondary_user" />
+ <option name="config-descriptor:metadata" key="parameter" value="no_foldable_states" />
+
+ <test class="com.android.tradefed.testtype.IsolatedHostTest" >
+ <option name="jar" value="hoststubgen-test-tiny-test.jar" />
+ </test>
+</configuration>
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md b/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md
new file mode 100644
index 000000000000..3bfad9bd673b
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/README.md
@@ -0,0 +1,21 @@
+# HostStubGen: tiny-framework test
+
+This directory contains a small classes that "simulates" framework.jar, and tests against it.
+
+This test doesn't use the actual android framework code.
+
+## How to run
+
+- With `atest`. This is the proper way to run it, but `atest` has known problems that may
+ affect the result. If you see weird problems, try the next `run-ravenwood-test` command.
+
+```
+$ atest hoststubgen-test-tiny-test
+```
+
+- `run-test-manually.sh` also run the test, but it builds the stub/impl jars and the test without
+ using the build system. This is useful for debugging the tool.
+
+```
+$ ./run-test-manually.sh
+``` \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt
new file mode 100644
index 000000000000..bd9e85e17890
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/annotation-allowed-classes-tiny-framework.txt
@@ -0,0 +1,29 @@
+# Only classes listed here can use the hoststubgen annotations.
+
+# For each class, we check each item in this file, and when a match is found, we
+# either allow it if the line doesn't have a !, or disallow if the line has a !.
+# All the lines after the matching line will be ignored.
+
+
+# To allow a specific class to use annotations:
+# com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+
+# To disallow a specific class to use annotations:
+# !com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+
+# To allow a specific package to use annotations:
+# com.android.hoststubgen.test.*
+
+# To disallow a specific package to use annotations:
+# !com.android.hoststubgen.test.*
+
+
+com.android.hoststubgen.test.tinyframework.*
+com.supported.*
+com.unsupported.*
+
+# Use this to allow all packages
+# *
+
+# Use this to allow all packages
+# !* \ No newline at end of file
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh b/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
new file mode 100755
index 000000000000..00cbfe38e815
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
@@ -0,0 +1,134 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+help() {
+ cat <<'EOF'
+
+ diff-and-update-golden.sh [OPTIONS]
+
+ Compare the generated jar files from tiny-framework to the "golden" files.
+
+ OPTIONS:
+ -u: Update the golden files.
+
+ -3: Run `meld` to compare original, stub and impl jar files in 3-way diff.
+ This is useful to visualize the exact differences between 3 jar files.
+
+ -2: Run `meld` to compare original <-> impl, and impl <-> stub as two different diffs.
+EOF
+}
+
+source "${0%/*}"/../../common.sh
+
+SCRIPT_NAME="${0##*/}"
+
+GOLDEN_DIR=golden-output
+mkdir -p $GOLDEN_DIR
+
+DIFF_CMD=${DIFF:-diff -u --ignore-blank-lines --ignore-space-change}
+
+update=0
+three_way=0
+two_way=0
+while getopts "u32" opt; do
+case "$opt" in
+ u)
+ update=1
+ ;;
+ 3)
+ three_way=1
+ ;;
+ 2)
+ two_way=1
+ ;;
+ '?')
+ help
+ exit 1
+ ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+
+# Build the dump files, which are the input of this test.
+run m tiny-framework-dump-test
+
+
+# Get the path to the generate text files. (not the golden files.)
+# We get them from $OUT/module-info.json
+
+files=(
+$(python3 -c '
+import sys
+import os
+import json
+
+with open(sys.argv[1], "r") as f:
+ data = json.load(f)
+
+ # Equivalent to: jq -r '.["tiny-framework-dump-test"]["installed"][]'
+ for path in data["tiny-framework-dump-test"]["installed"]:
+
+ if "golden-output" in path:
+ continue
+ if path.endswith(".txt"):
+ print(os.getenv("ANDROID_BUILD_TOP") + "/" + path)
+' $OUT/module-info.json)
+)
+
+# Next, compare each file and update them in $GOLDEN_DIR
+
+any_file_changed=0
+
+for file in ${files[*]} ; do
+ name=$(basename $file)
+ echo "# Checking $name ..."
+
+ file_changed=0
+ if run $DIFF_CMD $GOLDEN_DIR/$name $file; then
+ : # No diff
+ else
+ file_changed=1
+ any_file_changed=1
+ fi
+
+ if (( $update && $file_changed )) ; then
+ echo "# Updating $name ..."
+ run cp $file $GOLDEN_DIR/$name
+ fi
+done
+
+if (( $three_way )) ; then
+ echo "# Running 3-way diff with meld..."
+ run meld ${files[0]} ${files[1]} ${files[2]} &
+fi
+
+if (( $two_way )) ; then
+ echo "# Running meld..."
+ run meld --diff ${files[0]} ${files[1]} --diff ${files[1]} ${files[2]} --diff ${files[0]} ${files[2]}
+fi
+
+if (( $any_file_changed == 0 )) ; then
+ echo "$SCRIPT_NAME: Success: no changes detected."
+ exit 0
+else
+ if (( $update )) ; then
+ echo "$SCRIPT_NAME: Warning: golden files have been updated."
+ exit 2
+ else
+ echo "$SCRIPT_NAME: Failure: changes detected. See above diff for the details."
+ exit 3
+ fi
+fi
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
new file mode 100644
index 000000000000..673d3e8e25e9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/01-hoststubgen-test-tiny-framework-orig-dump.txt
@@ -0,0 +1,2567 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestNativeSubstitutionClass.class
+ Compiled from "HostSideTestNativeSubstitutionClass.java"
+public interface android.hosttest.annotation.HostSideTestNativeSubstitutionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestNativeSubstitutionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStaticInitializerKeep.class
+ Compiled from "HostSideTestStaticInitializerKeep.java"
+public interface android.hosttest.annotation.HostSideTestStaticInitializerKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStaticInitializerKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStaticInitializerKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStub.class
+ Compiled from "HostSideTestStub.java"
+public interface android.hosttest.annotation.HostSideTestStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStub.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassStub.class
+ Compiled from "HostSideTestWholeClassStub.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassStub.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/tests/HostSideTestSuppress.class
+ Compiled from "HostSideTestSuppress.java"
+public interface android.hosttest.annotation.tests.HostSideTestSuppress extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/tests/HostSideTestSuppress
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestSuppress.java"
+RuntimeVisibleAnnotations:
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD]
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl;
+
+ public static int getOneKeep();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkCallerCheck.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck;
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I
+ x: ireturn
+ LineNumberTable:
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I
+ x: ireturn
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 10, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 6 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 4 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 8 1 foo Ljava/lang/String;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestRemove
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 10 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 4 1 value I
+
+ public static native int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public static int nativeAddThree_host(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 10, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 8 1 foo Ljava/lang/String;
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 10 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 4 1 value I
+
+ public static native int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestSubstitute(
+ suffix="_host"
+ )
+
+ public static int nativeAddThree_host(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 2
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 2
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 2
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 3
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 0 18 3 longName Ljava/lang/String;
+ 0 18 4 shortName Ljava/lang/String;
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 3
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 0 10 10 Class java/lang/Exception
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 e Ljava/lang/Exception;
+ StackMapTable: number_of_entries = 1
+ frame_type = 74 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 10, attributes: 1
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 8 1 foo Ljava/lang/String;
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String not supported on host side
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 10 1 value I
+
+ public int addTwo_host(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+
+ public static native int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int addThree_host(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 8, attributes: 2
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+ public static native int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg I
+
+ public static native long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 arg1 J
+ 0 6 2 arg2 J
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 v I
+
+ public native int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 arg I
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 arg1 J
+ 0 4 2 arg2 J
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 7 1 arg I
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 3, attributes: 5
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 3, attributes: 5
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 3
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 0 10 1 x I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 0 15 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 5
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 0 6 1 x I
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 4
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/unsupported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/unsupported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/unsupported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 2
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+ public com.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/supported/UnsupportedClass;
+ 0 10 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/supported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 2
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/unsupported/UnsupportedClass;
+ 0 14 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/unsupported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
new file mode 100644
index 000000000000..d12588ae4ce2
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/02-hoststubgen-test-tiny-framework-host-stub-dump.txt
@@ -0,0 +1,1452 @@
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 4, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 7, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 7, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 8, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=4, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public native int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
new file mode 100644
index 000000000000..97fb64f38b2d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/03-hoststubgen-test-tiny-framework-host-impl-dump.txt
@@ -0,0 +1,2673 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestNativeSubstitutionClass.class
+ Compiled from "HostSideTestNativeSubstitutionClass.java"
+public interface android.hosttest.annotation.HostSideTestNativeSubstitutionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestNativeSubstitutionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStub.class
+ Compiled from "HostSideTestStub.java"
+public interface android.hosttest.annotation.HostSideTestStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassStub.class
+ Compiled from "HostSideTestWholeClassStub.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 0, attributes: 2
+}
+SourceFile: "HostSideTestWholeClassStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 4
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl;
+
+ public static int getOneKeep();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneKeep
+ x: ldc #x // String ()I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck;
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I
+ x: ireturn
+ LineNumberTable:
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I
+ x: ireturn
+ LineNumberTable:
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 6 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 15 4 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 0 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 8 1 foo Ljava/lang/String;
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 0 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 0 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 0 18 3 longName Ljava/lang/String;
+ 0 18 4 shortName Ljava/lang/String;
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: iconst_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 0 10 10 Class java/lang/Exception
+ StackMapTable: number_of_entries = 1
+ frame_type = 74 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 e Ljava/lang/Exception;
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 15 4 1 value I
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 0 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=1, locals=0, args_size=0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 8, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 arg1 J
+ 0 6 2 arg2 J
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 v I
+
+ public int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 0 6 1 arg I
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 4 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 4 0 arg1 J
+ 15 4 2 arg2 J
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeNonStaticAddToValue
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 15 7 1 arg I
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 3, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 3, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ 0 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 0 10 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 0 15 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 3, attributes: 6
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 0 6 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class com/supported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/supported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/supported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 12 0 value I
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+ public com.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // String com/supported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 10 0 this Lcom/supported/UnsupportedClass;
+ 15 10 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // String com/supported/UnsupportedClass
+ x: ldc #x // String getValue
+ x: ldc #x // String ()I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 15 5 0 this Lcom/supported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 14 0 this Lcom/unsupported/UnsupportedClass;
+ 0 14 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 0 10 0 this Lcom/unsupported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
new file mode 100644
index 000000000000..d12588ae4ce2
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/12-hoststubgen-test-tiny-framework-host-ext-stub-dump.txt
@@ -0,0 +1,1452 @@
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 5
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 4, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=5, args_size=5
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=3, locals=3, args_size=3
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 5, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 7, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 7, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 8, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static native long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0109) ACC_PUBLIC, ACC_STATIC, ACC_NATIVE
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=4, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public native int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0101) ACC_PUBLIC, ACC_NATIVE
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 1, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 1, attributes: 4
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=3, locals=0, args_size=0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 2, attributes: 3
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=2, args_size=2
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=3, locals=1, args_size=1
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Stub!
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
new file mode 100644
index 000000000000..8035189b50c9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/golden-output/13-hoststubgen-test-tiny-framework-host-ext-impl-dump.txt
@@ -0,0 +1,3469 @@
+## Class: android/hosttest/annotation/HostSideTestClassLoadHook.class
+ Compiled from "HostSideTestClassLoadHook.java"
+public interface android.hosttest.annotation.HostSideTestClassLoadHook extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestClassLoadHook
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestKeep.class
+ Compiled from "HostSideTestKeep.java"
+public interface android.hosttest.annotation.HostSideTestKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestKeep
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestNativeSubstitutionClass.class
+ Compiled from "HostSideTestNativeSubstitutionClass.java"
+public interface android.hosttest.annotation.HostSideTestNativeSubstitutionClass extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestNativeSubstitutionClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String value();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestNativeSubstitutionClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestRemove.class
+ Compiled from "HostSideTestRemove.java"
+public interface android.hosttest.annotation.HostSideTestRemove extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestRemove
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestRemove
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestRemove.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestStub.class
+ Compiled from "HostSideTestStub.java"
+public interface android.hosttest.annotation.HostSideTestStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestStub
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x,e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE,Ljava/lang/annotation/ElementType;.FIELD,Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestSubstitute.class
+ Compiled from "HostSideTestSubstitute.java"
+public interface android.hosttest.annotation.HostSideTestSubstitute extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestSubstitute
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 2, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestSubstitute
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public abstract java.lang.String suffix();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0401) ACC_PUBLIC, ACC_ABSTRACT
+}
+SourceFile: "HostSideTestSubstitute.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestThrow.class
+ Compiled from "HostSideTestThrow.java"
+public interface android.hosttest.annotation.HostSideTestThrow extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestThrow
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestThrow
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestThrow.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x,e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.METHOD,Ljava/lang/annotation/ElementType;.CONSTRUCTOR]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassKeep.class
+ Compiled from "HostSideTestWholeClassKeep.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassKeep extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassKeep
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassKeep
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestWholeClassKeep.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: android/hosttest/annotation/HostSideTestWholeClassStub.class
+ Compiled from "HostSideTestWholeClassStub.java"
+public interface android.hosttest.annotation.HostSideTestWholeClassStub extends java.lang.annotation.Annotation
+ minor version: 0
+ major version: 61
+ flags: (0x2601) ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT, ACC_ANNOTATION
+ this_class: #x // android/hosttest/annotation/HostSideTestWholeClassStub
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 1, attributes: 2
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class android/hosttest/annotation/HostSideTestWholeClassStub
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+}
+SourceFile: "HostSideTestWholeClassStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+ x: #x(#x=[e#x.#x])
+ java.lang.annotation.Target(
+ value=[Ljava/lang/annotation/ElementType;.TYPE]
+ )
+ x: #x(#x=e#x.#x)
+ java.lang.annotation.Retention(
+ value=Ljava/lang/annotation/RetentionPolicy;.CLASS
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 4
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck$Impl();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl;
+
+ public static int getOneKeep();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneKeep
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneKeep
+ x: ldc #x // String ()I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public static int getOneStub();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+ x: ldc #x // String getOneStub
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: ireturn
+ LineNumberTable:
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.class
+ Compiled from "TinyFrameworkCallerCheck.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 4, attributes: 5
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkCallerCheck();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck;
+
+ public static int getOne_withCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String getOne_withCheck
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneKeep:()I
+ x: ireturn
+ LineNumberTable:
+
+ public static int getOne_noCheck();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+ x: ldc #x // String getOne_noCheck
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl.getOneStub:()I
+ x: ireturn
+ LineNumberTable:
+}
+InnerClasses:
+ private static #x= #x of #x; // Impl=class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl of class com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck
+SourceFile: "TinyFrameworkCallerCheck.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck$Impl
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.class
+ Compiled from "TinyFrameworkClassAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 11 6 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 26 4 1 value I
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestThrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+}
+SourceFile: "TinyFrameworkClassAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.class
+ Compiled from "TinyFrameworkClassClassWideAnnotations.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 3, methods: 9, attributes: 3
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int remove;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkClassClassWideAnnotations();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 4 1 value I
+
+ public void toBeRemoved(java.lang.String);
+ descriptor: (Ljava/lang/String;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String toBeRemoved
+ x: ldc #x // String (Ljava/lang/String;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":()V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 8 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 8 1 foo Ljava/lang/String;
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String This value shouldn\'t be seen on the host side.
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 3 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations;
+}
+SourceFile: "TinyFrameworkClassClassWideAnnotations.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.class
+ Compiled from "TinyFrameworkClassLoadHook.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ public static final java.util.Set<java.lang.Class<?>> sLoadedClasses;
+ descriptor: Ljava/util/Set;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/Set<Ljava/lang/Class<*>;>;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook();
+ descriptor: ()V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook;
+
+ public static void onClassLoaded(java.lang.Class<?>);
+ descriptor: (Ljava/lang/Class;)V
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String onClassLoaded
+ x: ldc #x // String (Ljava/lang/Class;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: getstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: aload_0
+ x: invokeinterface #x, 2 // InterfaceMethod java/util/Set.add:(Ljava/lang/Object;)Z
+ x: pop
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class;
+ LocalVariableTypeTable:
+ Start Length Slot Name Signature
+ 11 11 0 clazz Ljava/lang/Class<*>;
+ Signature: #x // (Ljava/lang/Class<*>;)V
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class java/util/HashSet
+ x: dup
+ x: invokespecial #x // Method java/util/HashSet."<init>":()V
+ x: putstatic #x // Field sLoadedClasses:Ljava/util/Set;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassLoadHook.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.class
+ Compiled from "TinyFrameworkClassWithInitializerDefault.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerDefault
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 0, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+}
+SourceFile: "TinyFrameworkClassWithInitializerDefault.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.class
+ Compiled from "TinyFrameworkClassWithInitializerStub.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkClassWithInitializerStub
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 1, attributes: 3
+ public static boolean sInitialized;
+ descriptor: Z
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.lang.Object sObject;
+ descriptor: Ljava/lang/Object;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: iconst_1
+ x: putstatic #x // Field sInitialized:Z
+ x: new #x // class java/lang/Object
+ x: dup
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: putstatic #x // Field sObject:Ljava/lang/Object;
+ x: return
+ LineNumberTable:
+}
+SourceFile: "TinyFrameworkClassWithInitializerStub.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestClassLoadHook(
+ value="com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded"
+ )
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.class
+ Compiled from "TinyFrameworkEnumComplex.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 6, methods: 7, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex RED;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex GREEN;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex BLUE;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private final java.lang.String mLongName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private final java.lang.String mShortName;
+ descriptor: Ljava/lang/String;
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestKeep
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String valueOf
+ x: ldc #x // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex(java.lang.String, java.lang.String);
+ descriptor: (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=5, args_size=5
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String <init>
+ x: ldc #x // String (Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: aload_0
+ x: aload_3
+ x: putfield #x // Field mLongName:Ljava/lang/String;
+ x: aload_0
+ x: aload 4
+ x: putfield #x // Field mShortName:Ljava/lang/String;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 18 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ 11 18 3 longName Ljava/lang/String;
+ 11 18 4 shortName Ljava/lang/String;
+ Signature: #x // (Ljava/lang/String;Ljava/lang/String;)V
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getLongName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String getLongName
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: getfield #x // Field mLongName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.lang.String getShortName();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String getShortName
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: getfield #x // Field mShortName:Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumComplex[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String $values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_3
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: dup
+ x: iconst_2
+ x: getstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=6, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String RED
+ x: iconst_0
+ x: ldc #x // String Red
+ x: ldc #x // String R
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field RED:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String GREEN
+ x: iconst_1
+ x: ldc #x // String Green
+ x: ldc #x // String G
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field GREEN:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex
+ x: dup
+ x: ldc #x // String BLUE
+ x: iconst_2
+ x: ldc #x // String Blue
+ x: ldc #x // String B
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;)V
+ x: putstatic #x // Field BLUE:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex;>;
+SourceFile: "TinyFrameworkEnumComplex.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.class
+ Compiled from "TinyFrameworkEnumSimple.java"
+public final class com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple extends java.lang.Enum<com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple>
+ minor version: 0
+ major version: 61
+ flags: (0x4031) ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ super_class: #x // java/lang/Enum
+ interfaces: 0, fields: 3, methods: 5, attributes: 4
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple CAT;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple DOG;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x4019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL, ACC_ENUM
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static final com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $VALUES;
+ descriptor: [Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x101a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL, ACC_SYNTHETIC
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: getstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokevirtual #x // Method "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;".clone:()Ljava/lang/Object;
+ x: checkcast #x // class "[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;"
+ x: areturn
+ LineNumberTable:
+
+ public static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple valueOf(java.lang.String);
+ descriptor: (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String valueOf
+ x: ldc #x // String (Ljava/lang/String;)Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: aload_0
+ x: invokestatic #x // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
+ x: checkcast #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 name Ljava/lang/String;
+
+ private com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple();
+ descriptor: (Ljava/lang/String;I)V
+ flags: (0x0002) ACC_PRIVATE
+ Code:
+ stack=4, locals=3, args_size=3
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String <init>
+ x: ldc #x // String (Ljava/lang/String;I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: iload_2
+ x: invokespecial #x // Method java/lang/Enum."<init>":(Ljava/lang/String;I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 7 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ Signature: #x // ()V
+
+ private static com.android.hoststubgen.test.tinyframework.TinyFrameworkEnumSimple[] $values();
+ descriptor: ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String $values
+ x: ldc #x // String ()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_2
+ x: anewarray #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: iconst_0
+ x: getstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: dup
+ x: iconst_1
+ x: getstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: aastore
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String CAT
+ x: iconst_0
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field CAT:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple
+ x: dup
+ x: ldc #x // String DOG
+ x: iconst_1
+ x: invokespecial #x // Method "<init>":(Ljava/lang/String;I)V
+ x: putstatic #x // Field DOG:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: invokestatic #x // Method $values:()[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: putstatic #x // Field $VALUES:[Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;
+ x: return
+ LineNumberTable:
+}
+Signature: #x // Ljava/lang/Enum<Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple;>;
+SourceFile: "TinyFrameworkEnumSimple.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.class
+ Compiled from "TinyFrameworkExceptionTester.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkExceptionTester();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester;
+
+ public static int testException();
+ descriptor: ()I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester
+ x: ldc #x // String testException
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/lang/IllegalStateException
+ x: dup
+ x: ldc #x // String Inner exception
+ x: invokespecial #x // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ x: astore_0
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Outer exception
+ x: aload_0
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;Ljava/lang/Throwable;)V
+ x: athrow
+ Exception table:
+ from to target type
+ 11 21 21 Class java/lang/Exception
+ StackMapTable: number_of_entries = 1
+ frame_type = 85 /* same_locals_1_stack_item */
+ stack = [ class java/lang/Exception ]
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 22 11 0 e Ljava/lang/Exception;
+}
+SourceFile: "TinyFrameworkExceptionTester.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.class
+ Compiled from "TinyFrameworkForTextPolicy.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 2
+ public int stub;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ public int keep;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkForTextPolicy();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_1
+ x: putfield #x // Field stub:I
+ x: aload_0
+ x: iconst_2
+ x: putfield #x // Field keep:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+
+ public int addOne(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOne
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokevirtual #x // Method addOneInner:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 6 1 value I
+
+ public int addOneInner(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addOneInner
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_1
+ x: iconst_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 26 4 1 value I
+
+ public int addTwo(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String addTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_1
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+ 11 4 1 value I
+
+ public static int nativeAddThree(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String nativeAddThree
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: iconst_3
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 4 0 value I
+
+ public java.lang.String unsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String unsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onThrowMethodCalled:()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String Unreachable
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+
+ public java.lang.String visibleButUsesUnsupportedMethod();
+ descriptor: ()Ljava/lang/String;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy
+ x: ldc #x // String visibleButUsesUnsupportedMethod
+ x: ldc #x // String ()Ljava/lang/String;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokevirtual #x // Method unsupportedMethod:()Ljava/lang/String;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy;
+}
+SourceFile: "TinyFrameworkForTextPolicy.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas$Nested();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$getSupplier_static$3
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: bipush 8
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$getSupplier$2
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$static$1
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: bipush 6
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String lambda$new$0
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_5
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.class
+ Compiled from "TinyFrameworkLambdas.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 8, attributes: 6
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkLambdas();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+ RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+
+ private static java.lang.Integer lambda$getSupplier_static$3();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$getSupplier_static$3
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$getSupplier$2();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$getSupplier$2
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$static$1();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$static$1
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ private static java.lang.Integer lambda$new$0();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x100a) ACC_PRIVATE, ACC_STATIC, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String lambda$new$0
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: invokedynamic #x, 0 // InvokeDynamic #x:get:()Ljava/util/function/Supplier;
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ public static #x= #x of #x; // Nested=class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested of class com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas
+ public static final #x= #x of #x; // Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
+SourceFile: "TinyFrameworkLambdas.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestStub
+ x: #x()
+ android.hosttest.annotation.HostSideTestStaticInitializerKeep
+BootstrapMethods:
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$new$0:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier$2:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$getSupplier_static$3:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+ x: #x REF_invokeStatic java/lang/invoke/LambdaMetafactory.metafactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
+ Method arguments:
+ #x ()Ljava/lang/Object;
+ #x REF_invokeStatic com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.lambda$static$1:()Ljava/lang/Integer;
+ #x ()Ljava/lang/Integer;
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas$Nested
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.class
+ Compiled from "TinyFrameworkNative.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 9, attributes: 3
+ int value;
+ descriptor: I
+ flags: (0x0000)
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=1, locals=1, args_size=1
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+
+ public static int nativeAddTwo_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeAddTwo_should_be_like_this
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: iload_0
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeAddTwo:(I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+
+ public static long nativeLongPlus_should_be_like_this(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeLongPlus_should_be_like_this
+ x: ldc #x // String (JJ)J
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: lload_0
+ x: lload_2
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeLongPlus:(JJ)J
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 arg1 J
+ 11 6 2 arg2 J
+
+ public void setValue(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String setValue
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 11 6 1 v I
+
+ public int nativeNonStaticAddToValue(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=2, locals=2, args_size=2
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int);
+ descriptor: (I)I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative
+ x: ldc #x // String nativeNonStaticAddToValue_should_be_like_this
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokestatic #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.nativeNonStaticAddToValue:(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 11 6 1 arg I
+}
+SourceFile: "TinyFrameworkNative.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+ x: #x(#x=s#x)
+ android.hosttest.annotation.HostSideTestNativeSubstitutionClass(
+ value="TinyFrameworkNative_host"
+ )
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.class
+ Compiled from "TinyFrameworkNative_host.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 5, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNative_host();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host;
+
+ public static int nativeAddTwo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeAddTwo
+ x: ldc #x // String (I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iload_0
+ x: iconst_2
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 arg I
+
+ public static long nativeLongPlus(long, long);
+ descriptor: (JJ)J
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=4, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeLongPlus
+ x: ldc #x // String (JJ)J
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: lload_0
+ x: lload_2
+ x: ladd
+ x: lreturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 4 0 arg1 J
+ 26 4 2 arg2 J
+
+ public static int nativeNonStaticAddToValue(com.android.hoststubgen.test.tinyframework.TinyFrameworkNative, int);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeNonStaticAddToValue
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host
+ x: ldc #x // String nativeNonStaticAddToValue
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;I)I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: getfield #x // Field com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.value:I
+ x: iload_1
+ x: iadd
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 7 0 source Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNative;
+ 26 7 1 arg I
+}
+SourceFile: "TinyFrameworkNative_host.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 4, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$1(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+ 11 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_1
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$2();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_2
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 1, methods: 4, attributes: 6
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$3(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+ 11 10 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_3
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$4();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: iconst_4
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4;
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 2, attributes: 4
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass;
+ 11 10 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 2, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ final com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses this$0;
+ descriptor: Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ flags: (0x1010) ACC_FINAL, ACC_SYNTHETIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$InnerClass(com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses);
+ descriptor: (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: aload_1
+ x: putfield #x // Field this$0:Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iconst_5
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 15 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass;
+ 11 15 1 this$0 Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+}
+InnerClasses:
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1 extends java.lang.Object implements java.util.function.Supplier<java.lang.Integer>
+ minor version: 0
+ major version: 61
+ flags: (0x0020) ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ super_class: #x // java/lang/Object
+ interfaces: 1, fields: 0, methods: 4, attributes: 6
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass$1();
+ descriptor: ()V
+ flags: (0x0000)
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Integer get();
+ descriptor: ()Ljava/lang/Integer;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Integer;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: bipush 7
+ x: invokestatic #x // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+
+ public java.lang.Object get();
+ descriptor: ()Ljava/lang/Object;
+ flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: ldc #x // String get
+ x: ldc #x // String ()Ljava/lang/Object;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokevirtual #x // Method get:()Ljava/lang/Integer;
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+EnclosingMethod: #x.#x // com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass.getSupplier_static
+Signature: #x // Ljava/lang/Object;Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 5
+ public int value;
+ descriptor: I
+ flags: (0x0001) ACC_PUBLIC
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$StaticNestedClass();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: bipush 6
+ x: putfield #x // Field value:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 11 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+}
+InnerClasses:
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass extends com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$BaseClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ super_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ interfaces: 0, fields: 0, methods: 2, attributes: 4
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses$SubClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: iload_1
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass."<init>":(I)V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 6 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass;
+ 11 6 1 x I
+}
+InnerClasses:
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+NestHost: class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.class
+ Compiled from "TinyFrameworkNestedClasses.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 2, methods: 4, attributes: 5
+ public final java.util.function.Supplier<java.lang.Integer> mSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0011) ACC_PUBLIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static final java.util.function.Supplier<java.lang.Integer> sSupplier;
+ descriptor: Ljava/util/function/Supplier;
+ flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
+ Signature: #x // Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: putfield #x // Field mSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 17 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+
+ public java.util.function.Supplier<java.lang.Integer> getSupplier();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ x: dup
+ x: aload_0
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3."<init>":(Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;)V
+ x: areturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 9 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses;
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ public static java.util.function.Supplier<java.lang.Integer> getSupplier_static();
+ descriptor: ()Ljava/util/function/Supplier;
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String getSupplier_static
+ x: ldc #x // String ()Ljava/util/function/Supplier;
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4."<init>":()V
+ x: areturn
+ LineNumberTable:
+ Signature: #x // ()Ljava/util/function/Supplier<Ljava/lang/Integer;>;
+
+ static {};
+ descriptor: ()V
+ flags: (0x0008) ACC_STATIC
+ Code:
+ stack=4, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String <clinit>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: new #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ x: dup
+ x: invokespecial #x // Method com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2."<init>":()V
+ x: putstatic #x // Field sSupplier:Ljava/util/function/Supplier;
+ x: return
+ LineNumberTable:
+}
+InnerClasses:
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ public static #x= #x of #x; // SubClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // BaseClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public static #x= #x of #x; // StaticNestedClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ public #x= #x of #x; // InnerClass=class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass of class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses
+ #x; // class com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+SourceFile: "TinyFrameworkNestedClasses.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+NestMembers:
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$SubClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$BaseClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$StaticNestedClass$1
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$InnerClass
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$4
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$3
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$2
+ com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses$1
+## Class: com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.class
+ Compiled from "TinyFrameworkPackageRedirect.java"
+public class com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.android.hoststubgen.test.tinyframework.TinyFrameworkPackageRedirect();
+ descriptor: ()V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ x: ldc #x // String <init>
+ x: ldc #x // String ()V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 5 0 this Lcom/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect;
+
+ public static int foo(int);
+ descriptor: (I)I
+ flags: (0x0009) ACC_PUBLIC, ACC_STATIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect
+ x: ldc #x // String foo
+ x: ldc #x // String (I)I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class com/supported/UnsupportedClass
+ x: dup
+ x: iload_0
+ x: invokespecial #x // Method com/supported/UnsupportedClass."<init>":(I)V
+ x: invokevirtual #x // Method com/supported/UnsupportedClass.getValue:()I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 12 0 value I
+}
+SourceFile: "TinyFrameworkPackageRedirect.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
+## Class: com/supported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.supported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/supported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 1, methods: 3, attributes: 3
+ private final int mValue;
+ descriptor: I
+ flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/supported/UnsupportedClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.supported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/supported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/supported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: aload_0
+ x: iload_1
+ x: putfield #x // Field mValue:I
+ x: return
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 10 0 this Lcom/supported/UnsupportedClass;
+ 26 10 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/supported/UnsupportedClass
+ x: ldc #x // String getValue
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: ldc #x // String com/supported/UnsupportedClass
+ x: ldc #x // String getValue
+ x: ldc #x // String ()I
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.getStackWalker:()Ljava/lang/StackWalker;
+ x: invokevirtual #x // Method java/lang/StackWalker.getCallerClass:()Ljava/lang/Class;
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onNonStubMethodCalled:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)V
+ x: aload_0
+ x: getfield #x // Field mValue:I
+ x: ireturn
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 26 5 0 this Lcom/supported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassKeep
+## Class: com/unsupported/UnsupportedClass.class
+ Compiled from "UnsupportedClass.java"
+public class com.unsupported.UnsupportedClass
+ minor version: 0
+ major version: 61
+ flags: (0x0021) ACC_PUBLIC, ACC_SUPER
+ this_class: #x // com/unsupported/UnsupportedClass
+ super_class: #x // java/lang/Object
+ interfaces: 0, fields: 0, methods: 3, attributes: 3
+ private static {};
+ descriptor: ()V
+ flags: (0x000a) ACC_PRIVATE, ACC_STATIC
+ Code:
+ stack=2, locals=0, args_size=0
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logClassLoaded
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.onClassLoaded:(Ljava/lang/Class;Ljava/lang/String;)V
+ x: return
+
+ public com.unsupported.UnsupportedClass(int);
+ descriptor: (I)V
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=2, args_size=2
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ x: ldc #x // String <init>
+ x: ldc #x // String (I)V
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: aload_0
+ x: invokespecial #x // Method java/lang/Object."<init>":()V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 14 0 this Lcom/unsupported/UnsupportedClass;
+ 11 14 1 value I
+
+ public int getValue();
+ descriptor: ()I
+ flags: (0x0001) ACC_PUBLIC
+ Code:
+ stack=4, locals=1, args_size=1
+ x: ldc #x // class com/unsupported/UnsupportedClass
+ x: ldc #x // String getValue
+ x: ldc #x // String ()I
+ x: ldc #x // String com.android.hoststubgen.hosthelper.HostTestUtils.logMethodCall
+ x: invokestatic #x // Method com/android/hoststubgen/hosthelper/HostTestUtils.callMethodCallHook:(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+ x: new #x // class java/lang/RuntimeException
+ x: dup
+ x: ldc #x // String This class is not supported
+ x: invokespecial #x // Method java/lang/RuntimeException."<init>":(Ljava/lang/String;)V
+ x: athrow
+ LineNumberTable:
+ LocalVariableTable:
+ Start Length Slot Name Signature
+ 11 10 0 this Lcom/unsupported/UnsupportedClass;
+}
+SourceFile: "UnsupportedClass.java"
+RuntimeVisibleAnnotations:
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedStubClass
+ x: #x()
+ com.android.hoststubgen.hosthelper.HostStubGenProcessedKeepClass
+RuntimeInvisibleAnnotations:
+ x: #x()
+ android.hosttest.annotation.HostSideTestWholeClassStub
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
new file mode 100644
index 000000000000..079d2a84e498
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/policy-override-tiny-framework.txt
@@ -0,0 +1,17 @@
+class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy stub
+ field stub stub
+ field keep keep
+ # field remove remove # Implicitly remove
+ method <init> ()V stub
+ method addOne (I)I stub
+ method addOneInner (I)I keep
+ method toBeRemoved (Ljava/lang/String;)V remove
+ method addTwo (I)I @addTwo_host
+ # method addTwo_host (I)I # used as a substitute
+ method nativeAddThree (I)I @addThree_host
+ # method addThree_host (I)I # used as a substitute
+ method unsupportedMethod ()Ljava/lang/String; throw
+ method visibleButUsesUnsupportedMethod ()Ljava/lang/String; stub
+
+# Class load hook
+class com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy ~com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/run-test-manually.sh b/tools/hoststubgen/hoststubgen/test-tiny-framework/run-test-manually.sh
new file mode 100755
index 000000000000..872bbf878de4
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/run-test-manually.sh
@@ -0,0 +1,132 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+
+source "${0%/*}"/../../common.sh
+
+# This scripts run the "tiny-framework" test, but does most stuff from the command line, using
+# the native java and javac commands.
+
+debug=0
+while getopts "d" opt; do
+case "$opt" in
+ d) debug=1 ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+
+out=out
+
+rm -fr $out
+mkdir -p $out
+
+HOSTSTUBGEN=hoststubgen
+
+# Rebuild the tool and the dependencies. These are the only things we build with the build system.
+run m $HOSTSTUBGEN hoststubgen-annotations hoststubgen-helper-runtime truth junit
+
+
+# Build tiny-framework
+
+tiny_framework_classes=$out/tiny-framework/classes/
+tiny_framework_jar=$out/tiny-framework.jar
+tiny_framework_host_stub_jar=$out/tiny-framework_host_stub.jar
+tiny_framework_host_impl_jar=$out/tiny-framework_host_impl.jar
+
+tiny_test_classes=$out/tiny-test/classes/
+tiny_test_jar=$out/tiny-test.jar
+
+framework_compile_classpaths=(
+ $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/hoststubgen-annotations/android_common/javac/hoststubgen-annotations.jar
+)
+
+test_compile_classpaths=(
+ $SOONG_INT/external/junit/junit/android_common/combined/junit.jar
+ $SOONG_INT/external/truth/truth/android_common/combined/truth.jar
+)
+
+test_runtime_classpaths=(
+ $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/hoststubgen-helper-runtime/linux_glibc_common/javac/hoststubgen-helper-runtime.jar
+)
+
+# This suite runs all tests in the JAR.
+test_classes=(com.android.hoststubgen.hosthelper.HostTestSuite)
+
+# Uncomment this to run a specific test.
+# tests=(com.android.hoststubgen.test.tinyframework.TinyFrameworkBenchmark)
+
+
+# Build tiny-framework.jar
+echo "# Building tiny-framework..."
+run $JAVAC \
+ -cp $( \
+ join : \
+ ${framework_compile_classpaths[@]} \
+ ) \
+ -d $tiny_framework_classes \
+ tiny-framework/src/**/*.java
+
+run $JAR cvf $tiny_framework_jar \
+ -C $tiny_framework_classes .
+
+# Build stub/impl jars
+echo "# Generating the stub and impl jars..."
+run $HOSTSTUBGEN \
+ @../hoststubgen-standard-options.txt \
+ --in-jar $tiny_framework_jar \
+ --out-stub-jar $tiny_framework_host_stub_jar \
+ --out-impl-jar $tiny_framework_host_impl_jar \
+ --policy-override-file policy-override-tiny-framework.txt \
+ --gen-keep-all-file out/tiny-framework_keep_all.txt \
+ --gen-input-dump-file out/tiny-framework_dump.txt \
+ --package-redirect com.unsupported:com.supported \
+ --annotation-allowed-classes-file annotation-allowed-classes-tiny-framework.txt \
+ $HOSTSTUBGEN_OPTS
+
+# Extract the jar files, so we can look into them.
+extract $tiny_framework_host_stub_jar $tiny_framework_host_impl_jar
+
+# Build the test
+echo "# Building tiny-test..."
+run $JAVAC \
+ -cp $( \
+ join : \
+ $tiny_framework_host_stub_jar \
+ "${test_compile_classpaths[@]}" \
+ ) \
+ -d $tiny_test_classes \
+ tiny-test/src/**/*.java
+
+run $JAR cvf $tiny_test_jar \
+ -C $tiny_test_classes .
+
+if (( $debug )) ; then
+ JAVA_OPTS="$JAVA_OPTS -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8700"
+fi
+
+# Run the test
+echo "# Running tiny-test..."
+run $JAVA \
+ $JAVA_OPTS \
+ -cp $( \
+ join : \
+ $tiny_test_jar \
+ $tiny_framework_host_impl_jar \
+ "${test_compile_classpaths[@]}" \
+ "${test_runtime_classpaths[@]}" \
+ ) \
+ org.junit.runner.JUnitCore \
+ ${test_classes[@]}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
new file mode 100755
index 000000000000..cee29dcd1d59
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python3
+# Copyright (C) 2023 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.
+
+# Compare the tiny-framework JAR dumps to the golden files.
+
+import sys
+import os
+import unittest
+import subprocess
+
+GOLDEN_DIR = 'golden-output'
+
+# Run diff.
+def run_diff(file1, file2):
+ command = ['diff', '-u', '--ignore-blank-lines', '--ignore-space-change', file1, file2]
+ print(' '.join(command))
+ result = subprocess.run(command, stderr = sys.stdout)
+
+ success = result.returncode == 0
+
+ if success:
+ print(f'No diff found.')
+ else:
+ print(f'Fail: {file1} and {file2} are different.')
+
+ return success
+
+
+# Check one golden file.
+def check_one_file(filename):
+ print(f'= Checking file: {filename}')
+ return run_diff(os.path.join(GOLDEN_DIR, filename), filename)
+
+class TestWithGoldenOutput(unittest.TestCase):
+
+ # Test to check the generated jar files to the golden output.
+ def test_compare_to_golden(self):
+ files = os.listdir(GOLDEN_DIR)
+ files.sort()
+
+ print(f"Golden files: {files}")
+ success = True
+
+ for file in files:
+ if not check_one_file(file):
+ success = False
+
+ if not success:
+ self.fail('Some files are different. See stdout log for more details.')
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.java
new file mode 100644
index 000000000000..f53020771cc3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkCallerCheck.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestKeep;
+import android.hosttest.annotation.HostSideTestStub;
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+/**
+ * Used by the benchmark.
+ */
+@HostSideTestWholeClassStub
+public class TinyFrameworkCallerCheck {
+
+ /**
+ * This method uses an inner method (which has the caller check).
+ *
+ * Benchmark result: 768ns
+ */
+ public static int getOne_withCheck() {
+ return Impl.getOneKeep();
+ }
+
+ /**
+ * This method doesn't have any caller check.
+ *
+ * Benchmark result: 2ns
+ */
+ public static int getOne_noCheck() {
+ return Impl.getOneStub();
+ }
+
+ private static class Impl {
+ @HostSideTestKeep
+ public static int getOneKeep() {
+ return 1;
+ }
+
+ @HostSideTestStub
+ public static int getOneStub() {
+ return 1;
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java
new file mode 100644
index 000000000000..ab387e0938c3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassAnnotations.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestClassLoadHook;
+import android.hosttest.annotation.HostSideTestKeep;
+import android.hosttest.annotation.HostSideTestRemove;
+import android.hosttest.annotation.HostSideTestStub;
+import android.hosttest.annotation.HostSideTestSubstitute;
+import android.hosttest.annotation.HostSideTestThrow;
+
+/**
+ * Test without class-wide annotations.
+ */
+@HostSideTestStub
+@HostSideTestClassLoadHook(
+ "com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded")
+public class TinyFrameworkClassAnnotations {
+ @HostSideTestStub
+ public TinyFrameworkClassAnnotations() {
+ }
+
+ @HostSideTestStub
+ public int stub = 1;
+
+ @HostSideTestKeep
+ public int keep = 2;
+
+ // Members will be deleted by default.
+ // Deleted fields cannot have an initial value, because otherwise .ctor will fail to set it at
+ // runtime.
+ public int remove;
+
+ @HostSideTestStub
+ public int addOne(int value) {
+ return addOneInner(value);
+ }
+
+ @HostSideTestKeep
+ public int addOneInner(int value) {
+ return value + 1;
+ }
+
+ @HostSideTestRemove // Explicitly remove
+ public void toBeRemoved(String foo) {
+ throw new RuntimeException();
+ }
+
+ @HostSideTestStub
+ @HostSideTestSubstitute(suffix = "_host")
+ public int addTwo(int value) {
+ throw new RuntimeException("not supported on host side");
+ }
+
+ public int addTwo_host(int value) {
+ return value + 2;
+ }
+
+ @HostSideTestStub
+ @HostSideTestSubstitute(suffix = "_host")
+ public static native int nativeAddThree(int value);
+
+ public static int nativeAddThree_host(int value) {
+ return value + 3;
+ }
+
+ @HostSideTestThrow
+ public String unsupportedMethod() {
+ return "This value shouldn't be seen on the host side.";
+ }
+
+ @HostSideTestStub
+ public String visibleButUsesUnsupportedMethod() {
+ return unsupportedMethod();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java
new file mode 100644
index 000000000000..145b65a98d7b
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassClassWideAnnotations.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestStub;
+import android.hosttest.annotation.HostSideTestSubstitute;
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkClassClassWideAnnotations {
+ public TinyFrameworkClassClassWideAnnotations() {
+ }
+
+ public int stub = 1;
+
+ public int keep = 2;
+
+ // Cannot have an initial value, because otherwise .ctor will fail to set it at runtime.
+ public int remove;
+
+ // @Stub
+ public int addOne(int value) {
+ return addOneInner(value);
+ }
+
+ // @Keep
+ public int addOneInner(int value) {
+ return value + 1;
+ }
+
+ // @Remove
+ public void toBeRemoved(String foo) {
+ throw new RuntimeException();
+ }
+
+ @HostSideTestStub
+ @HostSideTestSubstitute(suffix = "_host")
+ public int addTwo(int value) {
+ throw new RuntimeException("not supported on host side");
+ }
+
+ public int addTwo_host(int value) {
+ return value + 2;
+ }
+
+ @HostSideTestStub
+ @HostSideTestSubstitute(suffix = "_host")
+ public static native int nativeAddThree(int value);
+
+ public static int nativeAddThree_host(int value) {
+ return value + 3;
+ }
+
+ public String unsupportedMethod() {
+ return "This value shouldn't be seen on the host side.";
+ }
+
+ public String visibleButUsesUnsupportedMethod() {
+ return unsupportedMethod();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.java
new file mode 100644
index 000000000000..98fc6349cdc9
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassLoadHook.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+import java.util.HashSet;
+import java.util.Set;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkClassLoadHook {
+ private TinyFrameworkClassLoadHook() {
+ }
+
+ public static final Set<Class<?>> sLoadedClasses = new HashSet<>();
+
+ public static void onClassLoaded(Class<?> clazz) {
+ sLoadedClasses.add(clazz);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.java
new file mode 100644
index 000000000000..8324ed93bf26
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerDefault.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestClassLoadHook;
+import android.hosttest.annotation.HostSideTestStub;
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+@HostSideTestStub
+public class TinyFrameworkClassWithInitializerDefault {
+ static {
+ sInitialized = true;
+ }
+
+ @HostSideTestStub
+ public static boolean sInitialized;
+ @HostSideTestStub
+ public static Object sObject = new Object();
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.java
new file mode 100644
index 000000000000..ea1ad93b21b4
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithInitializerStub.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestClassLoadHook;
+import android.hosttest.annotation.HostSideTestStaticInitializerKeep;
+import android.hosttest.annotation.HostSideTestStub;
+
+@HostSideTestClassLoadHook(
+ "com.android.hoststubgen.test.tinyframework.TinyFrameworkClassLoadHook.onClassLoaded")
+@HostSideTestStub
+@HostSideTestStaticInitializerKeep
+public class TinyFrameworkClassWithInitializerStub {
+ static {
+ sInitialized = true;
+ }
+
+ @HostSideTestStub
+ public static boolean sInitialized;
+ @HostSideTestStub
+ public static Object sObject = new Object();
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.java
new file mode 100644
index 000000000000..51f48188fe74
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumComplex.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestKeep;
+import android.hosttest.annotation.HostSideTestStub;
+
+@HostSideTestStub
+public enum TinyFrameworkEnumComplex {
+ @HostSideTestStub
+ RED("Red", "R"),
+ @HostSideTestStub
+ GREEN("Green", "G"),
+ @HostSideTestStub
+ BLUE("Blue", "B");
+
+ @HostSideTestKeep
+ private final String mLongName;
+
+ @HostSideTestKeep
+ private final String mShortName;
+
+ @HostSideTestStub
+ TinyFrameworkEnumComplex(String longName, String shortName) {
+ mLongName = longName;
+ mShortName = shortName;
+ }
+
+ @HostSideTestStub
+ public String getLongName() {
+ return mLongName;
+ }
+
+ @HostSideTestStub
+ public String getShortName() {
+ return mShortName;
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.java
new file mode 100644
index 000000000000..f440d8667fb4
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkEnumSimple.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestStub;
+
+@HostSideTestStub
+public enum TinyFrameworkEnumSimple {
+ @HostSideTestStub
+ CAT,
+ @HostSideTestStub
+ DOG,
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.java
new file mode 100644
index 000000000000..909d3b440f50
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkExceptionTester.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkExceptionTester {
+ public static int testException() {
+ try {
+ throw new IllegalStateException("Inner exception");
+ } catch (Exception e) {
+ throw new RuntimeException("Outer exception", e);
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java
new file mode 100644
index 000000000000..bde7c35dc294
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkForTextPolicy.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+/**
+ * Class for testing the "text policy" file.
+ */
+public class TinyFrameworkForTextPolicy {
+ public TinyFrameworkForTextPolicy() {
+ }
+
+ public int stub = 1;
+
+ public int keep = 2;
+
+ // Removed fields cannot have an initial value, because otherwise .ctor will fail to set it at
+ // runtime.
+ public int remove;
+
+ public int addOne(int value) {
+ return addOneInner(value);
+ }
+
+ public int addOneInner(int value) {
+ return value + 1;
+ }
+
+ public void toBeRemoved(String foo) {
+ throw new RuntimeException();
+ }
+
+ public int addTwo(int value) {
+ throw new RuntimeException("not supported on host side");
+ }
+
+ public int addTwo_host(int value) {
+ return value + 2;
+ }
+
+ public static native int nativeAddThree(int value);
+
+ public static int addThree_host(int value) {
+ return value + 3;
+ }
+
+ public String unsupportedMethod() {
+ return "This value shouldn't be seen on the host side.";
+ }
+
+ public String visibleButUsesUnsupportedMethod() {
+ return unsupportedMethod();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.java
new file mode 100644
index 000000000000..0d1203b0dedc
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkLambdas.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestStaticInitializerKeep;
+import android.hosttest.annotation.HostSideTestStub;
+
+import java.util.function.Supplier;
+
+
+/**
+ * In this class, we explicitly mark each member as "stub". (rather than using WholeClassStub)
+ *
+ * This means the actual generated lambda functions would be removed by default.
+ *
+ * Implicit filter should take care of them.
+ */
+@HostSideTestStub
+@HostSideTestStaticInitializerKeep
+public class TinyFrameworkLambdas {
+ @HostSideTestStub
+ public TinyFrameworkLambdas() {
+ }
+
+ @HostSideTestStub
+ public final Supplier<Integer> mSupplier = () -> 1;
+
+ @HostSideTestStub
+ public static final Supplier<Integer> sSupplier = () -> 2;
+
+ @HostSideTestStub
+ public Supplier<Integer> getSupplier() {
+ return () -> 3;
+ }
+
+ @HostSideTestStub
+ public static Supplier<Integer> getSupplier_static() {
+ return () -> 4;
+ }
+
+ @HostSideTestStub
+ @HostSideTestStaticInitializerKeep
+ public static class Nested {
+ @HostSideTestStub
+ public Nested() {
+ }
+
+ @HostSideTestStub
+ public final Supplier<Integer> mSupplier = () -> 5;
+
+ @HostSideTestStub
+ public static final Supplier<Integer> sSupplier = () -> 6;
+
+ @HostSideTestStub
+ public Supplier<Integer> getSupplier() {
+ return () -> 7;
+ }
+
+ @HostSideTestStub
+ public static Supplier<Integer> getSupplier_static() {
+ return () -> 8;
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.java
new file mode 100644
index 000000000000..e7b5d9fc2ece
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestNativeSubstitutionClass;
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+@HostSideTestWholeClassStub
+@HostSideTestNativeSubstitutionClass("TinyFrameworkNative_host")
+public class TinyFrameworkNative {
+ public static native int nativeAddTwo(int arg);
+
+ public static int nativeAddTwo_should_be_like_this(int arg) {
+ return TinyFrameworkNative_host.nativeAddTwo(arg);
+ }
+
+ public static native long nativeLongPlus(long arg1, long arg2);
+
+ public static long nativeLongPlus_should_be_like_this(long arg1, long arg2) {
+ return TinyFrameworkNative_host.nativeLongPlus(arg1, arg2);
+ }
+
+ int value;
+
+ public void setValue(int v) {
+ this.value = v;
+ }
+
+ public native int nativeNonStaticAddToValue(int arg);
+
+ public int nativeNonStaticAddToValue_should_be_like_this(int arg) {
+ return TinyFrameworkNative_host.nativeNonStaticAddToValue(this, arg);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.java
new file mode 100644
index 000000000000..749ebaa378e3
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNative_host.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassKeep;
+
+// TODO: This annotation shouldn't be needed.
+// We should infer it from HostSideTestNativeSubstitutionClass.
+@HostSideTestWholeClassKeep
+public class TinyFrameworkNative_host {
+ public static int nativeAddTwo(int arg) {
+ return arg + 2;
+ }
+
+ public static long nativeLongPlus(long arg1, long arg2) {
+ return arg1 + arg2;
+ }
+
+ // Note, the method must be static even for a non-static native method, but instead it
+ // must take the "source" instance as the first argument.
+ public static int nativeNonStaticAddToValue(TinyFrameworkNative source, int arg) {
+ return source.value + arg;
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java
new file mode 100644
index 000000000000..e1c48bb85563
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkNestedClasses.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+import java.util.function.Supplier;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkNestedClasses {
+ public final Supplier<Integer> mSupplier = new Supplier<Integer>() {
+ @Override
+ public Integer get() {
+ return 1;
+ }
+ };
+
+ public static final Supplier<Integer> sSupplier = new Supplier<Integer>() {
+ @Override
+ public Integer get() {
+ return 2;
+ }
+ };
+ public Supplier<Integer> getSupplier() {
+ return new Supplier<Integer>() {
+ @Override
+ public Integer get() {
+ return 3;
+ }
+ };
+ }
+
+ public static Supplier<Integer> getSupplier_static() {
+ return new Supplier<Integer>() {
+ @Override
+ public Integer get() {
+ return 4;
+ }
+ };
+ }
+
+ @HostSideTestWholeClassStub
+ public class InnerClass {
+ public int value = 5;
+ }
+
+ @HostSideTestWholeClassStub
+ public static class StaticNestedClass {
+ public int value = 6;
+
+ // Double-nest
+ public static Supplier<Integer> getSupplier_static() {
+ return new Supplier<Integer>() {
+ @Override
+ public Integer get() {
+ return 7;
+ }
+ };
+ }
+ }
+
+ public static class BaseClass {
+ public int value;
+ public BaseClass(int x) {
+ value = x;
+ }
+ }
+
+ public static class SubClass extends BaseClass {
+ public SubClass(int x) {
+ super(x);
+ }
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.java
new file mode 100644
index 000000000000..a82be5453b1e
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkPackageRedirect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+@HostSideTestWholeClassStub
+public class TinyFrameworkPackageRedirect {
+ /**
+ * A method that uses "unsupported" class. HostStubGen will redirect them to the "supported"
+ * one (because of --package-redirect), so this test will pass.
+ */
+ public static int foo(int value) {
+ // This method throws, so it's not callable as-is. But HostStubGen
+ // will rewrite it, it will actually work.
+ return new com.unsupported.UnsupportedClass(value).getValue();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/supported/UnsupportedClass.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/supported/UnsupportedClass.java
new file mode 100644
index 000000000000..fa5866451e83
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/supported/UnsupportedClass.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2023 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.supported;
+
+import android.hosttest.annotation.HostSideTestWholeClassKeep;
+
+// Used for testing --package-redirect.
+@HostSideTestWholeClassKeep
+public class UnsupportedClass {
+ private final int mValue;
+
+ public UnsupportedClass(int value) {
+ mValue = value;
+ }
+
+ public int getValue() {
+ return mValue;
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/unsupported/UnsupportedClass.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/unsupported/UnsupportedClass.java
new file mode 100644
index 000000000000..0409b02b0f5d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-framework/src/com/unsupported/UnsupportedClass.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2023 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.unsupported;
+
+import android.hosttest.annotation.HostSideTestWholeClassStub;
+
+// Used for testing --package-redirect.
+@HostSideTestWholeClassStub
+public class UnsupportedClass {
+ public UnsupportedClass(int value) {
+ throw new RuntimeException("This class is not supported");
+ }
+
+ public int getValue() {
+ throw new RuntimeException("This class is not supported");
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/LargeTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/LargeTest.java
new file mode 100644
index 000000000000..76bbcad2ab26
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/LargeTest.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * We don't want to use any android classes in this module, so we create our own copy of it here.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.TYPE})
+public @interface LargeTest {}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkBenchmark.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkBenchmark.java
new file mode 100644
index 000000000000..d57735b1987c
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkBenchmark.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import org.junit.Test;
+
+import java.text.DecimalFormat;
+
+/**
+ * Contains simple micro-benchmarks.
+ */
+@LargeTest
+public class TinyFrameworkBenchmark {
+ private static final int MINIMAL_ITERATION = 1000;
+ private static final int MEASURE_SECONDS = 1;
+
+ private static final DecimalFormat sFormatter = new DecimalFormat("#,###");
+
+ private void doBenchmark(String name, Runnable r) {
+ // Worm up
+ for (int i = 0; i < MINIMAL_ITERATION; i++) {
+ r.run();
+ }
+
+ // Start measuring.
+ final long start = System.nanoTime();
+ final long end = start + MEASURE_SECONDS * 1_000_000_000L;
+
+ double iteration = 0;
+ while (System.nanoTime() <= end) {
+ for (int i = 0; i < MINIMAL_ITERATION; i++) {
+ r.run();
+ }
+ iteration += MINIMAL_ITERATION;
+ }
+
+ final long realEnd = System.nanoTime();
+
+ System.out.println(String.format("%s\t%s", name,
+ sFormatter.format((((double) realEnd - start)) / iteration)));
+ }
+
+ /**
+ * Micro-benchmark for a method without a non-stub caller check.
+ */
+ @Test
+ public void benchNoCallerCheck() {
+ doBenchmark("No caller check", TinyFrameworkCallerCheck::getOne_noCheck);
+ }
+
+ /**
+ * Micro-benchmark for a method with a non-stub caller check.
+ */
+ @Test
+ public void benchWithCallerCheck() {
+ doBenchmark("With caller check", TinyFrameworkCallerCheck::getOne_withCheck);
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
new file mode 100644
index 000000000000..d04ca52a5682
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassTest.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.android.hoststubgen.test.tinyframework.TinyFrameworkNestedClasses.SubClass;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+import java.io.FileDescriptor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class TinyFrameworkClassTest {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testSimple() {
+ TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
+ assertThat(tfc.addOne(1)).isEqualTo(2);
+ assertThat(tfc.stub).isEqualTo(1);
+ }
+
+// @Test
+// public void testDoesntCompile() {
+// TinyFrameworkClass tfc = new TinyFrameworkClass();
+//
+// tfc.addOneInner(1); // Shouldn't compile.
+// tfc.toBeRemoved("abc"); // Shouldn't compile.
+// tfc.unsupportedMethod(); // Shouldn't compile.
+// int a = tfc.keep; // Shouldn't compile
+// int b = tfc.remove; // Shouldn't compile
+// }
+
+ @Test
+ public void testSubstitute() {
+ TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
+ assertThat(tfc.addTwo(1)).isEqualTo(3);
+ }
+
+ @Test
+ public void testSubstituteNative() {
+ TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
+ assertThat(tfc.nativeAddThree(1)).isEqualTo(4);
+ }
+
+ @Test
+ public void testVisibleButUsesUnsupportedMethod() {
+ TinyFrameworkForTextPolicy tfc = new TinyFrameworkForTextPolicy();
+
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("This method is not supported on the host side");
+ tfc.visibleButUsesUnsupportedMethod();
+ }
+
+ @Test
+ public void testNestedClass1() {
+ assertThat(new TinyFrameworkNestedClasses().mSupplier.get()).isEqualTo(1);
+ }
+
+ @Test
+ public void testNestedClass2() {
+ assertThat(TinyFrameworkNestedClasses.sSupplier.get()).isEqualTo(2);
+ }
+
+ @Test
+ public void testNestedClass3() {
+ assertThat(new TinyFrameworkNestedClasses().getSupplier().get()).isEqualTo(3);
+ }
+
+ @Test
+ public void testNestedClass4() {
+ assertThat(TinyFrameworkNestedClasses.getSupplier_static().get()).isEqualTo(4);
+ }
+
+ @Test
+ public void testNestedClass5() {
+ assertThat((new TinyFrameworkNestedClasses()).new InnerClass().value).isEqualTo(5);
+ }
+
+ @Test
+ public void testNestedClass6() {
+ assertThat(new TinyFrameworkNestedClasses.StaticNestedClass().value).isEqualTo(6);
+ }
+
+ @Test
+ public void testNestedClass7() {
+ assertThat(TinyFrameworkNestedClasses.StaticNestedClass.getSupplier_static().get())
+ .isEqualTo(7);
+ }
+
+ @Test
+ public void testLambda1() {
+ assertThat(new TinyFrameworkLambdas().mSupplier.get()).isEqualTo(1);
+ }
+
+ @Test
+ public void testLambda2() {
+ assertThat(TinyFrameworkLambdas.sSupplier.get()).isEqualTo(2);
+ }
+
+ @Test
+ public void testLambda3() {
+ assertThat(new TinyFrameworkLambdas().getSupplier().get()).isEqualTo(3);
+ }
+
+ @Test
+ public void testLambda4() {
+ assertThat(TinyFrameworkLambdas.getSupplier_static().get()).isEqualTo(4);
+ }
+
+ @Test
+ public void testLambda5() {
+ assertThat(new TinyFrameworkLambdas.Nested().mSupplier.get()).isEqualTo(5);
+ }
+
+ @Test
+ public void testLambda6() {
+ assertThat(TinyFrameworkLambdas.Nested.sSupplier.get()).isEqualTo(6);
+ }
+
+ @Test
+ public void testLambda7() {
+ assertThat(new TinyFrameworkLambdas.Nested().getSupplier().get()).isEqualTo(7);
+ }
+
+ @Test
+ public void testLambda8() {
+ assertThat(TinyFrameworkLambdas.Nested.getSupplier_static().get()).isEqualTo(8);
+ }
+
+ @Test
+ public void testNativeSubstitutionClass() {
+ assertThat(TinyFrameworkNative.nativeAddTwo(3)).isEqualTo(5);
+ }
+
+ @Test
+ public void testNativeSubstitutionClass_nonStatic() {
+ TinyFrameworkNative instance = new TinyFrameworkNative();
+ instance.setValue(5);
+ assertThat(instance.nativeNonStaticAddToValue(3)).isEqualTo(8);
+ }
+
+ @Test
+ public void testExitLog() {
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("Outer exception");
+
+ TinyFrameworkExceptionTester.testException();
+
+ }
+
+ @Test
+ public void testMethodCallBeforeSuperCall() {
+ assertThat(new SubClass(3).value).isEqualTo(3);
+ }
+
+ @Test
+ public void testClassLoadHook() {
+ assertThat(TinyFrameworkClassWithInitializerStub.sInitialized).isTrue();
+
+ // Having this line before assertThat() will ensure these class are already loaded.
+ var classes = new Class[]{
+ TinyFrameworkClassWithInitializerStub.class,
+ TinyFrameworkClassAnnotations.class,
+ TinyFrameworkForTextPolicy.class,
+ };
+
+ // The following classes have a class load hook, so they should be registered.
+ assertThat(TinyFrameworkClassLoadHook.sLoadedClasses)
+ .containsAnyIn(classes);
+
+ // This class doesn't have a class load hook, so shouldn't be included.
+ assertThat(TinyFrameworkClassLoadHook.sLoadedClasses)
+ .doesNotContain(TinyFrameworkNestedClasses.class);
+ }
+
+ @Test
+ public void testStaticInitializer_Default() {
+ assertThat(TinyFrameworkClassWithInitializerDefault.sInitialized).isFalse();
+ assertThat(TinyFrameworkClassWithInitializerDefault.sObject).isNull();
+ }
+
+ @Test
+ public void testStaticInitializer_Stub() {
+ assertThat(TinyFrameworkClassWithInitializerStub.sInitialized).isTrue();
+ assertThat(TinyFrameworkClassWithInitializerStub.sObject).isNotNull();
+ }
+
+ /**
+ * Test to try accessing JDK private fields using reflections + setAccessible(true),
+ * which is now disallowed due to Java Modules, unless you run the javacommand with.
+ * --add-opens=java.base/java.io=ALL-UNNAMED
+ *
+ * You can try it from the command line, like:
+ * $ JAVA_OPTS="--add-opens=java.base/java.io=ALL-UNNAMED" ./run-test-manually.sh
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testFileDescriptor() throws Exception {
+ var fd = FileDescriptor.out;
+
+ // Get the FD value directly from the private field.
+ // This is now prohibited due to Java Modules.
+ // It throws:
+ // java.lang.reflect.InaccessibleObjectException: Unable to make field private int java.io.FileDescriptor.fd accessible: module java.base does not "opens java.io" to unnamed module @3bb50eaa
+
+ thrown.expect(java.lang.reflect.InaccessibleObjectException.class);
+
+ // Access the private field.
+ final Field f = FileDescriptor.class.getDeclaredField("fd");
+ final Method m = FileDescriptor.class.getDeclaredMethod("set", int.class);
+ f.setAccessible(true);
+ m.setAccessible(true);
+
+ assertThat(f.get(fd)).isEqualTo(1);
+
+ // Set
+ f.set(fd, 2);
+ assertThat(f.get(fd)).isEqualTo(2);
+
+ // Call the package private method, set(int).
+ m.invoke(fd, 0);
+ assertThat(f.get(fd)).isEqualTo(0);
+ }
+
+ @Test
+ public void testPackageRedirect() throws Exception {
+ assertThat(TinyFrameworkPackageRedirect.foo(1)).isEqualTo(1);
+ }
+
+ @Test
+ public void testEnumSimple() throws Exception {
+ assertThat(TinyFrameworkEnumSimple.CAT.ordinal()).isEqualTo(0);
+ assertThat(TinyFrameworkEnumSimple.CAT.name()).isEqualTo("CAT");
+
+ assertThat(TinyFrameworkEnumSimple.DOG.ordinal()).isEqualTo(1);
+ assertThat(TinyFrameworkEnumSimple.DOG.name()).isEqualTo("DOG");
+
+ assertThat(TinyFrameworkEnumSimple.valueOf("DOG").ordinal()).isEqualTo(1);
+
+ assertThat(TinyFrameworkEnumSimple.values()).isEqualTo(
+ new TinyFrameworkEnumSimple[] {
+ TinyFrameworkEnumSimple.CAT,
+ TinyFrameworkEnumSimple.DOG,
+ }
+ );
+ }
+
+ @Test
+ public void testEnumComplex() throws Exception {
+ assertThat(TinyFrameworkEnumComplex.RED.ordinal()).isEqualTo(0);
+ assertThat(TinyFrameworkEnumComplex.RED.name()).isEqualTo("RED");
+
+ assertThat(TinyFrameworkEnumComplex.RED.getShortName()).isEqualTo("R");
+
+ assertThat(TinyFrameworkEnumComplex.GREEN.ordinal()).isEqualTo(1);
+ assertThat(TinyFrameworkEnumComplex.GREEN.name()).isEqualTo("GREEN");
+
+ assertThat(TinyFrameworkEnumComplex.valueOf("BLUE").ordinal()).isEqualTo(2);
+
+ assertThat(TinyFrameworkEnumComplex.values()).isEqualTo(
+ new TinyFrameworkEnumComplex[] {
+ TinyFrameworkEnumComplex.RED,
+ TinyFrameworkEnumComplex.GREEN,
+ TinyFrameworkEnumComplex.BLUE,
+ }
+ );
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java
new file mode 100644
index 000000000000..20cc2ec9d50d
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test-tiny-framework/tiny-test/src/com/android/hoststubgen/test/tinyframework/TinyFrameworkClassWithAnnotTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.test.tinyframework;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+public class TinyFrameworkClassWithAnnotTest {
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void testSimple() {
+ TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations();
+ assertThat(tfc.addOne(1)).isEqualTo(2);
+ assertThat(tfc.stub).isEqualTo(1);
+ }
+
+// @Test
+// public void testDoesntCompile() {
+// TinyFrameworkClassWithAnnot tfc = new TinyFrameworkClassWithAnnot();
+//
+// tfc.addOneInner(1); // Shouldn't compile.
+// tfc.toBeRemoved("abc"); // Shouldn't compile.
+// tfc.unsupportedMethod(); // Shouldn't compile.
+// int a = tfc.keep; // Shouldn't compile
+// int b = tfc.remove; // Shouldn't compile
+// }
+
+ @Test
+ public void testSubstitute() {
+ TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations();
+ assertThat(tfc.addTwo(1)).isEqualTo(3);
+ }
+
+ @Test
+ public void testSubstituteNative() {
+ TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations();
+ assertThat(tfc.nativeAddThree(1)).isEqualTo(4);
+ }
+
+ @Test
+ public void testVisibleButUsesUnsupportedMethod() {
+ TinyFrameworkClassAnnotations tfc = new TinyFrameworkClassAnnotations();
+
+ thrown.expect(RuntimeException.class);
+ thrown.expectMessage("This method is not supported on the host side");
+ tfc.visibleButUsesUnsupportedMethod();
+ }
+}
diff --git a/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt b/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt
new file mode 100644
index 000000000000..f6515142ccdb
--- /dev/null
+++ b/tools/hoststubgen/hoststubgen/test/com/android/hoststubgen/utils/ClassFilterTest.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.hoststubgen.utils
+
+import com.android.hoststubgen.ParseException
+import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.fail
+import org.junit.Test
+
+class ClassFilterTest {
+ @Test
+ fun testDefaultTrue() {
+ val f = ClassFilter.newNullFilter(true)
+ assertThat(f.matches("a/b/c")).isEqualTo(true)
+ }
+
+ @Test
+ fun testDefaultFalse() {
+ val f = ClassFilter.newNullFilter(false)
+ assertThat(f.matches("a/b/c")).isEqualTo(false)
+ }
+
+ @Test
+ fun testComplex1() {
+ val f = ClassFilter.buildFromString("""
+ # ** this is a comment **
+ a.b.c # allow
+ !a.b.d # disallow
+ * # allow all
+ """.trimIndent(), false, "X")
+ assertThat(f.getCacheSizeForTest()).isEqualTo(0)
+
+ assertThat(f.matches("a/b/c")).isEqualTo(true)
+ assertThat(f.getCacheSizeForTest()).isEqualTo(1)
+
+ assertThat(f.matches("a/b/d")).isEqualTo(false)
+ assertThat(f.matches("x")).isEqualTo(true)
+
+ assertThat(f.getCacheSizeForTest()).isEqualTo(3)
+
+ // Make sure the cache is working
+ assertThat(f.matches("x")).isEqualTo(true)
+ }
+
+ @Test
+ fun testComplex2() {
+ val f = ClassFilter.buildFromString("""
+ a.b.c # allow
+ !a.* # disallow everything else in package "a".
+ !d.e.f # disallow d.e.f.
+
+ # everything else is allowed by default
+ """.trimIndent(), true, "X")
+ assertThat(f.matches("a/b/c")).isEqualTo(true)
+ assertThat(f.matches("a/x")).isEqualTo(false)
+ assertThat(f.matches("d/e/f")).isEqualTo(false)
+ assertThat(f.matches("d/e/f/g")).isEqualTo(true)
+ assertThat(f.matches("x")).isEqualTo(true)
+ }
+
+ @Test
+ fun testBadFilter1() {
+ try {
+ ClassFilter.buildFromString("""
+ a*
+ """.trimIndent(), true, "FILENAME")
+ fail("ParseException didn't happen")
+ } catch (e: ParseException) {
+ assertThat(e.message).contains("Wildcard")
+ assertThat(e.message).contains("FILENAME")
+ assertThat(e.message).contains("line 1")
+ }
+ }
+} \ No newline at end of file
diff --git a/tools/xmlpersistence/Android.bp b/tools/hoststubgen/scripts/Android.bp
index 0b6dba626794..b1ba07ec540d 100644
--- a/tools/xmlpersistence/Android.bp
+++ b/tools/hoststubgen/scripts/Android.bp
@@ -7,14 +7,14 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
-java_binary_host {
- name: "xmlpersistence_cli",
- manifest: "manifest.txt",
- srcs: [
- "src/**/*.kt",
- ],
- static_libs: [
- "javaparser-symbol-solver",
- "javapoet",
- ],
+sh_binary_host {
+ name: "dump-jar",
+ src: "dump-jar",
+ visibility: ["//visibility:public"],
+}
+
+genrule_defaults {
+ name: "hoststubgen-jar-dump-defaults",
+ tools: ["dump-jar"],
+ cmd: "$(location dump-jar) -s -o $(out) $(in)",
}
diff --git a/tools/hoststubgen/scripts/build-framework-hostside-jars-and-extract.sh b/tools/hoststubgen/scripts/build-framework-hostside-jars-and-extract.sh
new file mode 100755
index 000000000000..72681234dad8
--- /dev/null
+++ b/tools/hoststubgen/scripts/build-framework-hostside-jars-and-extract.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+
+# Script to build `framework-host-stub` and `framework-host-impl`, and copy the
+# generated jars to $out, and unzip them. Useful for looking into the generated files.
+
+source "${0%/*}"/../common.sh
+
+out=framework-all-stub-out
+
+rm -fr $out
+mkdir -p $out
+
+# Build the jars with `m`.
+run m framework-all-hidden-api-host
+
+# Copy the jar to out/ and extract them.
+run cp \
+ $SOONG_INT/frameworks/base/tools/hoststubgen/hoststubgen/framework-all-hidden-api-host/linux_glibc_common/gen/* \
+ $out
+
+extract $out/*.jar
diff --git a/tools/hoststubgen/scripts/build-framework-hostside-jars-without-genrules.sh b/tools/hoststubgen/scripts/build-framework-hostside-jars-without-genrules.sh
new file mode 100755
index 000000000000..c3605a9ffaa5
--- /dev/null
+++ b/tools/hoststubgen/scripts/build-framework-hostside-jars-without-genrules.sh
@@ -0,0 +1,76 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+
+# Script to build hoststubgen and run it directly (without using the build rules)
+# on framework-all.jar.
+
+
+echo "THIS SCRIPT IS BROKEN DUE TO CHANGES TO FILE PATHS TO DEPENDENT FILES. FIX IT WHEN YOU NEED TO USE IT." 1>&2
+
+exit 99
+
+
+source "${0%/*}"/../common.sh
+
+out=out
+
+mkdir -p $out
+
+# Build the tool and target jar.
+run m hoststubgen framework-all
+
+base_args=(
+ @../hoststubgen/hoststubgen-standard-options.txt
+
+ --in-jar $ANDROID_BUILD_TOP/out/soong/.intermediates/frameworks/base/framework-all/android_common/combined/framework-all.jar
+ --policy-override-file ../hoststubgen/framework-policy-override.txt "${@}"
+
+ # This file will contain all classes as an annotation file, with "keep all" policy.
+ --gen-keep-all-file $out/framework-all-keep-all-policy.txt
+
+ # This file will contains dump of all classes in the input jar.
+ --gen-input-dump-file $out/framework-all-dump.txt
+)
+
+do_it() {
+ local out_file_stem="$1"
+ shift
+ local extra_args=("${@}")
+
+ run hoststubgen \
+ "${base_args[@]}" \
+ "${extra_args[@]}" \
+ --out-stub-jar ${out_file_stem}_stub.jar \
+ --out-impl-jar ${out_file_stem}_impl.jar \
+ $HOSTSTUBGEN_OPTS
+
+ # Extract the jar files, so we can look into them.
+ run extract ${out_file_stem}_*.jar
+}
+
+#-----------------------------------------------------------------------------
+# framework-all, with all hidden APIs.
+#-----------------------------------------------------------------------------
+
+# No extra args.
+do_it $out/framework-all_host
+
+#-----------------------------------------------------------------------------
+# framework-test-api, only public/system/test-APIs in the stub.
+#-----------------------------------------------------------------------------
+
+do_it $out/framework-test-api_host \
+ --intersect-stub-jar $SOONG_INT/frameworks/base/api/android_test_stubs_current/android_common/combined/*.jar
diff --git a/tools/hoststubgen/scripts/dump-jar b/tools/hoststubgen/scripts/dump-jar
new file mode 100755
index 000000000000..992665ed58ee
--- /dev/null
+++ b/tools/hoststubgen/scripts/dump-jar
@@ -0,0 +1,165 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+set -e
+
+
+help() {
+ cat <<'EOF'
+
+ dump-jar: Dump java classes in jar files
+
+ Usage:
+ dump-jar [-v] CLASS-FILE [...]
+
+ Dump a *.class file
+
+ dump-jar [-v] [-s] [-o OUTPUT-FILENAME] JAR-FILE[: filename regex] [...]
+
+ Dump a jar file.
+
+ If a filename contains a ':', then the following part
+ will be used to filter files in the jar file.
+
+ For example, "file.jar:/MyClass$" will only dump "MyClass" in file.jar.
+
+ Options:
+ -v: Enable verbose output.
+
+ -s: Simple output mode, used to check HostStubGen output jars.
+
+ -o: Write the output to a specified file.
+EOF
+}
+
+# Parse the options.
+
+verbose=0
+simple=0
+output=""
+while getopts "hvso:" opt; do
+case "$opt" in
+ h)
+ help
+ exit 0
+ ;;
+ v)
+ verbose=1
+ ;;
+ s)
+ simple=1
+ ;;
+ o)
+ output="$OPTARG"
+ ;;
+ '?')
+ help
+ exit 1
+ ;;
+esac
+done
+shift $(($OPTIND - 1))
+
+JAVAP_OPTS="${JAVAP_OPTS:--v -p -s -sysinfo -constants}"
+
+if (( $simple )) ; then
+ JAVAP_OPTS="-p -c -v"
+fi
+
+
+# Normalize a java class name.
+# Convert '.' to '/'
+# Remove the *.class suffix.
+normalize() {
+ local name="$1"
+ name="${name%.class}" # Remove the .class suffix.
+ echo "$name" | tr '.' '/'
+}
+
+# Convert the output for `-s` as needed.
+filter_output() {
+ if (( $simple )) ; then
+ # For "simple output" mode,
+ # - Normalize the constant numbers (replace with "#x")
+ # - Normalize byte code offsets and other similar numbers. (e.g. "0:" -> "x:")
+ # - Remove the constant pool
+ # - Remove the line number table
+ # - Some other transient lines
+ #
+ # `/PATTERN-1/,/PATTERN-1/{//!d}` is a trick to delete lines between two patterns, without
+ # the start and the end lines.
+ sed -e 's/#[0-9][0-9]*/#x/g' \
+ -e 's/^\( *\)[0-9][0-9]*:/\1x:/' \
+ -e '/^Constant pool:/,/^[^ ]/{//!d}' \
+ -e '/^ *line *[0-9][0-9]*: *[0-9][0-9]*$/d' \
+ -e '/SHA-256 checksum/d' \
+ -e '/Last modified/d' \
+ -e '/^Classfile jar/d'
+ else
+ cat # Print as-is.
+ fi
+}
+
+# Write to the output file (specified with -o) as needed.
+write_to_out() {
+ if [[ -n "$output" ]] ; then
+ cat >"$output"
+ echo "Wrote output to $output" 1>&2
+ else
+ cat # print to stdout
+ fi
+}
+
+for file in "${@}"; do
+
+ # *.class?
+ if echo "$file" | grep -qE '\.class$' ; then
+ echo "# Class: $file" 1>&2
+ javap $dump_code_opt $JAVAP_OPTS $file
+
+ # *.jar?
+ elif echo "$file" | grep -qE '\.jar(:.*)?$' ; then
+ # Take the regex. Remove everything up to : in $file
+ regex=""
+ if [[ "$file" =~ : ]] ; then
+ regex="$(normalize "${file##*:}")"
+ fi
+
+ # Remove everything after ':', inclusively, in $file.
+ file="${file%:*}"
+
+ # Print the filename and the regex.
+ if ! (( $simple )) ; then
+ echo -n "# Jar: $file"
+ if [[ "$regex" != "" ]] ;then
+ echo -n " (regex: $regex)"
+ fi
+ echo
+ fi
+
+ jar tf "$file" | grep '\.class$' | sort | while read -r class ; do
+ if normalize "$class" | grep -q -- "$regex" ; then
+ echo "## Class: $class"
+ javap $dump_code_opt $JAVAP_OPTS -cp $file ${class%.class}
+ else
+ (( $verbose )) && echo "## Skipping class: $class"
+ fi
+ done
+
+ else
+ echo "Unknown file type: $file" 1>&2
+ exit 1
+ fi
+done | filter_output | write_to_out
diff --git a/tools/hoststubgen/scripts/run-all-tests.sh b/tools/hoststubgen/scripts/run-all-tests.sh
new file mode 100755
index 000000000000..82faa91e2cac
--- /dev/null
+++ b/tools/hoststubgen/scripts/run-all-tests.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+# Copyright (C) 2023 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.
+
+source "${0%/*}"/../common.sh
+
+# Move to the top directory of hoststubgen
+cd ..
+
+# These tests are known to pass.
+READY_TEST_MODULES=(
+ HostStubGenTest-framework-all-test-host-test
+ hoststubgen-test-tiny-test
+ CtsUtilTestCasesRavenwood
+)
+
+MUST_BUILD_MODULES=(
+ "${NOT_READY_TEST_MODULES[*]}"
+ HostStubGenTest-framework-test
+)
+
+# First, build all the test / etc modules. This shouldn't fail.
+run m "${MUST_BUILD_MODULES[@]}"
+
+# Run the hoststubgen unittests / etc
+run atest hoststubgentest hoststubgen-invoke-test
+
+# Next, run the golden check. This should always pass too.
+# The following scripts _should_ pass too, but they depend on the internal paths to soong generated
+# files, and they may fail when something changes in the build system.
+run ./hoststubgen/test-tiny-framework/diff-and-update-golden.sh
+
+run ./hoststubgen/test-framework/run-test-without-atest.sh
+
+run ./hoststubgen/test-tiny-framework/run-test-manually.sh
+run atest tiny-framework-dump-test
+run ./scripts/build-framework-hostside-jars-and-extract.sh
+
+# This script is already broken on goog/master
+# run ./scripts/build-framework-hostside-jars-without-genrules.sh
+
+# These tests should all pass.
+run atest ${READY_TEST_MODULES[*]}
+
+echo ""${0##*/}" finished, with no unexpected failures. Ready to submit!" \ No newline at end of file
diff --git a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
index f1727b78f135..a18ed1555998 100644
--- a/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
+++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/Constants.kt
@@ -29,9 +29,10 @@ val AIDL_PERMISSION_ANNOTATIONS = listOf(
const val BINDER_CLASS = "android.os.Binder"
const val IINTERFACE_INTERFACE = "android.os.IInterface"
-const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission"
const val PERMISSION_PREFIX_LITERAL = "android.permission."
+const val AIDL_PERMISSION_HELPER_SUFFIX = "_enforcePermission"
+
/**
* If a non java (e.g. c++) backend is enabled, the @EnforcePermission
* annotation cannot be used. At time of writing, the mechanism
diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
index c7be36efd991..22f749eee36b 100644
--- a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
+++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetector.kt
@@ -53,10 +53,9 @@ class SimpleManualPermissionEnforcementDetector : AidlImplementationDetector() {
lintFix
)
- // TODO(b/265014041): turn on errors once all code that would cause one is fixed
- // if (enforcePermissionFix.errorLevel) {
- // incident.overrideSeverity(Severity.ERROR)
- // }
+ if (enforcePermissionFix.errorLevel) {
+ incident.overrideSeverity(Severity.ERROR)
+ }
context.report(incident)
}
diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
index 6b8e72cf9222..9170e752934f 100644
--- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
+++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleManualPermissionEnforcementDetectorTest.kt
@@ -51,10 +51,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:7: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:7: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
mContext.enforceCallingOrSelfPermission("android.permission.READ_CONTACTS", "foo");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -168,10 +168,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:8: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:8: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
mContext.enforceCallingOrSelfPermission(
^
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -209,10 +209,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:8: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:8: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.READ_CONTACTS, "foo");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -252,10 +252,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:10: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:10: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
mContext.enforceCallingOrSelfPermission(
^
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -414,10 +414,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:14: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:14: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
helper();
~~~~~~~~~
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -506,10 +506,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:16: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:16: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
mContext.enforceCallingOrSelfPermission("FOO", "foo");
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -558,10 +558,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:19: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:19: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
helperHelper();
~~~~~~~~~~~~~~~
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
@@ -599,10 +599,10 @@ class SimpleManualPermissionEnforcementDetectorTest : LintDetectorTest() {
.run()
.expect(
"""
- src/Foo.java:7: Warning: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
+ src/Foo.java:7: Error: ITest permission check should be converted to @EnforcePermission annotation [SimpleManualPermissionEnforcement]
if (mContext.checkCallingOrSelfPermission("android.permission.READ_CONTACTS", "foo")
^
- 0 errors, 1 warnings
+ 1 errors, 0 warnings
"""
)
.expectFixDiffs(
diff --git a/tools/streaming_proto/OWNERS b/tools/streaming_proto/OWNERS
new file mode 100644
index 000000000000..5f6e59f82c8a
--- /dev/null
+++ b/tools/streaming_proto/OWNERS
@@ -0,0 +1 @@
+mwachens@google.com
diff --git a/tools/streaming_proto/cpp/main.cpp b/tools/streaming_proto/cpp/main.cpp
index fe9a438d81d7..905ed354049b 100644
--- a/tools/streaming_proto/cpp/main.cpp
+++ b/tools/streaming_proto/cpp/main.cpp
@@ -119,9 +119,8 @@ write_message(stringstream& text, const DescriptorProto& message, const string&
text << endl;
}
-static void
-write_header_file(CodeGeneratorResponse* response, const FileDescriptorProto& file_descriptor)
-{
+static void write_header_file(const string& request_parameter, CodeGeneratorResponse* response,
+ const FileDescriptorProto& file_descriptor) {
stringstream text;
text << "// Generated by protoc-gen-cppstream. DO NOT MODIFY." << endl;
@@ -159,6 +158,9 @@ write_header_file(CodeGeneratorResponse* response, const FileDescriptorProto& fi
text << endl;
text << "#endif // " << header << endl;
+ if (request_parameter.find("experimental_allow_proto3_optional") != string::npos) {
+ response->set_supported_features(CodeGeneratorResponse::FEATURE_PROTO3_OPTIONAL);
+ }
CodeGeneratorResponse::File* file_response = response->add_file();
file_response->set_name(make_filename(file_descriptor));
file_response->set_content(text.str());
@@ -182,7 +184,7 @@ int main(int argc, char const *argv[])
for (int i=0; i<N; i++) {
const FileDescriptorProto& file_descriptor = request.proto_file(i);
if (should_generate_for_file(request, file_descriptor.name())) {
- write_header_file(&response, file_descriptor);
+ write_header_file(request.parameter(), &response, file_descriptor);
}
}
diff --git a/tools/xmlpersistence/OWNERS b/tools/xmlpersistence/OWNERS
deleted file mode 100644
index 4f4d06a32676..000000000000
--- a/tools/xmlpersistence/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-zhanghai@google.com
diff --git a/tools/xmlpersistence/manifest.txt b/tools/xmlpersistence/manifest.txt
deleted file mode 100644
index 6d9771998efc..000000000000
--- a/tools/xmlpersistence/manifest.txt
+++ /dev/null
@@ -1 +0,0 @@
-Main-class: MainKt
diff --git a/tools/xmlpersistence/src/main/kotlin/Generator.kt b/tools/xmlpersistence/src/main/kotlin/Generator.kt
deleted file mode 100644
index 8e62388c860f..000000000000
--- a/tools/xmlpersistence/src/main/kotlin/Generator.kt
+++ /dev/null
@@ -1,577 +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.
- */
-
-import com.squareup.javapoet.ClassName
-import com.squareup.javapoet.FieldSpec
-import com.squareup.javapoet.JavaFile
-import com.squareup.javapoet.MethodSpec
-import com.squareup.javapoet.NameAllocator
-import com.squareup.javapoet.ParameterSpec
-import com.squareup.javapoet.TypeSpec
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileNotFoundException
-import java.io.FileOutputStream
-import java.io.IOException
-import java.nio.charset.StandardCharsets
-import java.time.Year
-import java.util.Objects
-import javax.lang.model.element.Modifier
-
-// JavaPoet only supports line comments, and can't add a newline after file level comments.
-val FILE_HEADER = """
- /*
- * Copyright (C) ${Year.now().value} 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.
- */
-
- // Generated by xmlpersistence. DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- // @formatter:off
-""".trimIndent() + "\n\n"
-
-private val atomicFileType = ClassName.get("android.util", "AtomicFile")
-
-fun generate(persistence: PersistenceInfo): JavaFile {
- val distinctClassFields = persistence.root.allClassFields.distinctBy { it.type }
- val type = TypeSpec.classBuilder(persistence.name)
- .addJavadoc(
- """
- Generated class implementing XML persistence for${'$'}W{@link $1T}.
- <p>
- This class provides atomicity for persistence via {@link $2T}, however it does not provide
- thread safety, so please bring your own synchronization mechanism.
- """.trimIndent(), persistence.root.type, atomicFileType
- )
- .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
- .addField(generateFileField())
- .addMethod(generateConstructor())
- .addMethod(generateReadMethod(persistence.root))
- .addMethod(generateParseMethod(persistence.root))
- .addMethods(distinctClassFields.map { generateParseClassMethod(it) })
- .addMethod(generateWriteMethod(persistence.root))
- .addMethod(generateSerializeMethod(persistence.root))
- .addMethods(distinctClassFields.map { generateSerializeClassMethod(it) })
- .addMethod(generateDeleteMethod())
- .build()
- return JavaFile.builder(persistence.root.type.packageName(), type)
- .skipJavaLangImports(true)
- .indent(" ")
- .build()
-}
-
-private val nonNullType = ClassName.get("android.annotation", "NonNull")
-
-private fun generateFileField(): FieldSpec =
- FieldSpec.builder(atomicFileType, "mFile", Modifier.PRIVATE, Modifier.FINAL)
- .addAnnotation(nonNullType)
- .build()
-
-private fun generateConstructor(): MethodSpec =
- MethodSpec.constructorBuilder()
- .addJavadoc(
- """
- Create an instance of this class.
-
- @param file the XML file for persistence
- """.trimIndent()
- )
- .addModifiers(Modifier.PUBLIC)
- .addParameter(
- ParameterSpec.builder(File::class.java, "file").addAnnotation(nonNullType).build()
- )
- .addStatement("mFile = new \$1T(file)", atomicFileType)
- .build()
-
-private val nullableType = ClassName.get("android.annotation", "Nullable")
-
-private val xmlPullParserType = ClassName.get("org.xmlpull.v1", "XmlPullParser")
-
-private val xmlType = ClassName.get("android.util", "Xml")
-
-private val xmlPullParserExceptionType = ClassName.get("org.xmlpull.v1", "XmlPullParserException")
-
-private fun generateReadMethod(rootField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder("read")
- .addJavadoc(
- """
- Read${'$'}W{@link $1T}${'$'}Wfrom${'$'}Wthe${'$'}WXML${'$'}Wfile.
-
- @return the persisted${'$'}W{@link $1T},${'$'}Wor${'$'}W{@code null}${'$'}Wif${'$'}Wthe${'$'}WXML${'$'}Wfile${'$'}Wdoesn't${'$'}Wexist
- @throws IllegalArgumentException if an error occurred while reading
- """.trimIndent(), rootField.type
- )
- .addAnnotation(nullableType)
- .addModifiers(Modifier.PUBLIC)
- .returns(rootField.type)
- .addControlFlow("try (\$1T inputStream = mFile.openRead())", FileInputStream::class.java) {
- addStatement("final \$1T parser = \$2T.newPullParser()", xmlPullParserType, xmlType)
- addStatement("parser.setInput(inputStream, null)")
- addStatement("return parse(parser)")
- nextControlFlow("catch (\$1T e)", FileNotFoundException::class.java)
- addStatement("return null")
- nextControlFlow(
- "catch (\$1T | \$2T e)", IOException::class.java, xmlPullParserExceptionType
- )
- addStatement("throw new IllegalArgumentException(e)")
- }
- .build()
-
-private val ClassFieldInfo.allClassFields: List<ClassFieldInfo>
- get() =
- mutableListOf<ClassFieldInfo>().apply {
- this += this@allClassFields
- for (field in fields) {
- when (field) {
- is ClassFieldInfo -> this += field.allClassFields
- is ListFieldInfo -> this += field.element.allClassFields
- else -> {}
- }
- }
- }
-
-private fun generateParseMethod(rootField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder("parse")
- .addAnnotation(nonNullType)
- .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
- .returns(rootField.type)
- .addParameter(
- ParameterSpec.builder(xmlPullParserType, "parser").addAnnotation(nonNullType).build()
- )
- .addExceptions(listOf(ClassName.get(IOException::class.java), xmlPullParserExceptionType))
- .apply {
- addStatement("int type")
- addStatement("int depth")
- addStatement("int innerDepth = parser.getDepth() + 1")
- addControlFlow(
- "while ((type = parser.next()) != \$1T.END_DOCUMENT\$W"
- + "&& ((depth = parser.getDepth()) >= innerDepth || type != \$1T.END_TAG))",
- xmlPullParserType
- ) {
- addControlFlow(
- "if (depth > innerDepth || type != \$1T.START_TAG)", xmlPullParserType
- ) {
- addStatement("continue")
- }
- addControlFlow(
- "if (\$1T.equals(parser.getName(),\$W\$2S))", Objects::class.java,
- rootField.tagName
- ) {
- addStatement("return \$1L(parser)", rootField.parseMethodName)
- }
- }
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Missing root tag <${rootField.tagName}>"
- )
- }
- .build()
-
-private fun generateParseClassMethod(classField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder(classField.parseMethodName)
- .addAnnotation(nonNullType)
- .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
- .returns(classField.type)
- .addParameter(
- ParameterSpec.builder(xmlPullParserType, "parser").addAnnotation(nonNullType).build()
- )
- .apply {
- val (attributeFields, tagFields) = classField.fields
- .partition { it is PrimitiveFieldInfo || it is StringFieldInfo }
- if (tagFields.isNotEmpty()) {
- addExceptions(
- listOf(ClassName.get(IOException::class.java), xmlPullParserExceptionType)
- )
- }
- val nameAllocator = NameAllocator().apply {
- newName("parser")
- newName("type")
- newName("depth")
- newName("innerDepth")
- }
- for (field in attributeFields) {
- val variableName = nameAllocator.newName(field.variableName, field)
- when (field) {
- is PrimitiveFieldInfo -> {
- val stringVariableName =
- nameAllocator.newName("${field.variableName}String")
- addStatement(
- "final String \$1L =\$Wparser.getAttributeValue(null,\$W\$2S)",
- stringVariableName, field.attributeName
- )
- if (field.isRequired) {
- addControlFlow("if (\$1L == null)", stringVariableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Missing attribute \"${field.attributeName}\""
- )
- }
- }
- val boxedType = field.type.box()
- val parseTypeMethodName = if (field.type.isPrimitive) {
- "parse${field.type.toString().capitalize()}"
- } else {
- "valueOf"
- }
- if (field.isRequired) {
- addStatement(
- "final \$1T \$2L =\$W\$3T.\$4L($5L)", field.type, variableName,
- boxedType, parseTypeMethodName, stringVariableName
- )
- } else {
- addStatement(
- "final \$1T \$2L =\$W$3L != null ?\$W\$4T.\$5L($3L)\$W: null",
- field.type, variableName, stringVariableName, boxedType,
- parseTypeMethodName
- )
- }
- }
- is StringFieldInfo ->
- addStatement(
- "final String \$1L =\$Wparser.getAttributeValue(null,\$W\$2S)",
- variableName, field.attributeName
- )
- else -> error(field)
- }
- }
- if (tagFields.isNotEmpty()) {
- for (field in tagFields) {
- val variableName = nameAllocator.newName(field.variableName, field)
- when (field) {
- is ClassFieldInfo ->
- addStatement("\$1T \$2L =\$Wnull", field.type, variableName)
- is ListFieldInfo ->
- addStatement(
- "final \$1T \$2L =\$Wnew \$3T<>()", field.type, variableName,
- ArrayList::class.java
- )
- else -> error(field)
- }
- }
- addStatement("int type")
- addStatement("int depth")
- addStatement("int innerDepth = parser.getDepth() + 1")
- addControlFlow(
- "while ((type = parser.next()) != \$1T.END_DOCUMENT\$W"
- + "&& ((depth = parser.getDepth()) >= innerDepth || type != \$1T.END_TAG))",
- xmlPullParserType
- ) {
- addControlFlow(
- "if (depth > innerDepth || type != \$1T.START_TAG)", xmlPullParserType
- ) {
- addStatement("continue")
- }
- addControlFlow("switch (parser.getName())") {
- for (field in tagFields) {
- addControlFlow("case \$1S:", field.tagName) {
- val variableName = nameAllocator.get(field)
- when (field) {
- is ClassFieldInfo -> {
- addControlFlow("if (\$1L != null)", variableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Duplicate tag \"${field.tagName}\""
- )
- }
- addStatement(
- "\$1L =\$W\$2L(parser)", variableName,
- field.parseMethodName
- )
- addStatement("break")
- }
- is ListFieldInfo -> {
- val elementNameAllocator = nameAllocator.clone()
- val elementVariableName = elementNameAllocator.newName(
- field.element.xmlName!!.toLowerCamelCase()
- )
- addStatement(
- "final \$1T \$2L =\$W\$3L(parser)", field.element.type,
- elementVariableName, field.element.parseMethodName
- )
- addStatement(
- "\$1L.add(\$2L)", variableName, elementVariableName
- )
- addStatement("break")
- }
- else -> error(field)
- }
- }
- }
- }
- }
- }
- for (field in tagFields.filter { it is ClassFieldInfo && it.isRequired }) {
- addControlFlow("if ($1L == null)", nameAllocator.get(field)) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)", "Missing tag <${field.tagName}>"
- )
- }
- }
- addStatement(
- classField.fields.joinToString(",\$W", "return new \$1T(", ")") {
- nameAllocator.get(it)
- }, classField.type
- )
- }
- .build()
-
-private val ClassFieldInfo.parseMethodName: String
- get() = "parse${type.simpleName().toUpperCamelCase()}"
-
-private val xmlSerializerType = ClassName.get("org.xmlpull.v1", "XmlSerializer")
-
-private fun generateWriteMethod(rootField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder("write")
- .apply {
- val nameAllocator = NameAllocator().apply {
- newName("outputStream")
- newName("serializer")
- }
- val parameterName = nameAllocator.newName(rootField.variableName)
- addJavadoc(
- """
- Write${'$'}W{@link $1T}${'$'}Wto${'$'}Wthe${'$'}WXML${'$'}Wfile.
-
- @param $2L the${'$'}W{@link ${'$'}1T}${'$'}Wto${'$'}Wpersist
- """.trimIndent(), rootField.type, parameterName
- )
- addAnnotation(nullableType)
- addModifiers(Modifier.PUBLIC)
- addParameter(
- ParameterSpec.builder(rootField.type, parameterName)
- .addAnnotation(nonNullType)
- .build()
- )
- addStatement("\$1T outputStream = null", FileOutputStream::class.java)
- addControlFlow("try") {
- addStatement("outputStream = mFile.startWrite()")
- addStatement(
- "final \$1T serializer =\$W\$2T.newSerializer()", xmlSerializerType, xmlType
- )
- addStatement(
- "serializer.setOutput(outputStream, \$1T.UTF_8.name())",
- StandardCharsets::class.java
- )
- addStatement(
- "serializer.setFeature(\$1S, true)",
- "http://xmlpull.org/v1/doc/features.html#indent-output"
- )
- addStatement("serializer.startDocument(null, true)")
- addStatement("serialize(serializer,\$W\$1L)", parameterName)
- addStatement("serializer.endDocument()")
- addStatement("mFile.finishWrite(outputStream)")
- nextControlFlow("catch (Exception e)")
- addStatement("e.printStackTrace()")
- addStatement("mFile.failWrite(outputStream)")
- }
- }
- .build()
-
-private fun generateSerializeMethod(rootField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder("serialize")
- .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
- .addParameter(
- ParameterSpec.builder(xmlSerializerType, "serializer")
- .addAnnotation(nonNullType)
- .build()
- )
- .apply {
- val nameAllocator = NameAllocator().apply { newName("serializer") }
- val parameterName = nameAllocator.newName(rootField.variableName)
- addParameter(
- ParameterSpec.builder(rootField.type, parameterName)
- .addAnnotation(nonNullType)
- .build()
- )
- addException(IOException::class.java)
- addStatement("serializer.startTag(null, \$1S)", rootField.tagName)
- addStatement("\$1L(serializer, \$2L)", rootField.serializeMethodName, parameterName)
- addStatement("serializer.endTag(null, \$1S)", rootField.tagName)
- }
- .build()
-
-private fun generateSerializeClassMethod(classField: ClassFieldInfo): MethodSpec =
- MethodSpec.methodBuilder(classField.serializeMethodName)
- .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
- .addParameter(
- ParameterSpec.builder(xmlSerializerType, "serializer")
- .addAnnotation(nonNullType)
- .build()
- )
- .apply {
- val nameAllocator = NameAllocator().apply {
- newName("serializer")
- newName("i")
- }
- val parameterName = nameAllocator.newName(classField.serializeParameterName)
- addParameter(
- ParameterSpec.builder(classField.type, parameterName)
- .addAnnotation(nonNullType)
- .build()
- )
- addException(IOException::class.java)
- val (attributeFields, tagFields) = classField.fields
- .partition { it is PrimitiveFieldInfo || it is StringFieldInfo }
- for (field in attributeFields) {
- val variableName = "$parameterName.${field.name}"
- if (!field.isRequired) {
- beginControlFlow("if (\$1L != null)", variableName)
- }
- when (field) {
- is PrimitiveFieldInfo -> {
- if (field.isRequired && !field.type.isPrimitive) {
- addControlFlow("if (\$1L == null)", variableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Field \"${field.name}\" is null"
- )
- }
- }
- val stringVariableName =
- nameAllocator.newName("${field.variableName}String")
- addStatement(
- "final String \$1L =\$WString.valueOf(\$2L)", stringVariableName,
- variableName
- )
- addStatement(
- "serializer.attribute(null, \$1S, \$2L)", field.attributeName,
- stringVariableName
- )
- }
- is StringFieldInfo -> {
- if (field.isRequired) {
- addControlFlow("if (\$1L == null)", variableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Field \"${field.name}\" is null"
- )
- }
- }
- addStatement(
- "serializer.attribute(null, \$1S, \$2L)", field.attributeName,
- variableName
- )
- }
- else -> error(field)
- }
- if (!field.isRequired) {
- endControlFlow()
- }
- }
- for (field in tagFields) {
- val variableName = "$parameterName.${field.name}"
- if (field.isRequired) {
- addControlFlow("if (\$1L == null)", variableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S)",
- "Field \"${field.name}\" is null"
- )
- }
- }
- when (field) {
- is ClassFieldInfo -> {
- addStatement("serializer.startTag(null, \$1S)", field.tagName)
- addStatement(
- "\$1L(serializer, \$2L)", field.serializeMethodName, variableName
- )
- addStatement("serializer.endTag(null, \$1S)", field.tagName)
- }
- is ListFieldInfo -> {
- val sizeVariableName = nameAllocator.newName("${field.variableName}Size")
- addStatement(
- "final int \$1L =\$W\$2L.size()", sizeVariableName, variableName
- )
- addControlFlow("for (int i = 0;\$Wi < \$1L;\$Wi++)", sizeVariableName) {
- val elementNameAllocator = nameAllocator.clone()
- val elementVariableName = elementNameAllocator.newName(
- field.element.xmlName!!.toLowerCamelCase()
- )
- addStatement(
- "final \$1T \$2L =\$W\$3L.get(i)", field.element.type,
- elementVariableName, variableName
- )
- addControlFlow("if (\$1L == null)", elementVariableName) {
- addStatement(
- "throw new IllegalArgumentException(\$1S\$W+ i\$W+ \$2S)",
- "Field element \"${field.name}[", "]\" is null"
- )
- }
- addStatement("serializer.startTag(null, \$1S)", field.element.tagName)
- addStatement(
- "\$1L(serializer,\$W\$2L)", field.element.serializeMethodName,
- elementVariableName
- )
- addStatement("serializer.endTag(null, \$1S)", field.element.tagName)
- }
- }
- else -> error(field)
- }
- }
- }
- .build()
-
-private val ClassFieldInfo.serializeMethodName: String
- get() = "serialize${type.simpleName().toUpperCamelCase()}"
-
-private val ClassFieldInfo.serializeParameterName: String
- get() = type.simpleName().toLowerCamelCase()
-
-private val FieldInfo.variableName: String
- get() = name.toLowerCamelCase()
-
-private val FieldInfo.attributeName: String
- get() {
- check(this is PrimitiveFieldInfo || this is StringFieldInfo)
- return xmlNameOrName.toLowerCamelCase()
- }
-
-private val FieldInfo.tagName: String
- get() {
- check(this is ClassFieldInfo || this is ListFieldInfo)
- return xmlNameOrName.toLowerKebabCase()
- }
-
-private val FieldInfo.xmlNameOrName: String
- get() = xmlName ?: name
-
-private fun generateDeleteMethod(): MethodSpec =
- MethodSpec.methodBuilder("delete")
- .addJavadoc("Delete the XML file, if any.")
- .addModifiers(Modifier.PUBLIC)
- .addStatement("mFile.delete()")
- .build()
-
-private inline fun MethodSpec.Builder.addControlFlow(
- controlFlow: String,
- vararg args: Any,
- block: MethodSpec.Builder.() -> Unit
-): MethodSpec.Builder {
- beginControlFlow(controlFlow, *args)
- block()
- endControlFlow()
- return this
-}
diff --git a/tools/xmlpersistence/src/main/kotlin/Main.kt b/tools/xmlpersistence/src/main/kotlin/Main.kt
deleted file mode 100644
index e271f8cb9361..000000000000
--- a/tools/xmlpersistence/src/main/kotlin/Main.kt
+++ /dev/null
@@ -1,45 +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.
- */
-
-import java.io.File
-import java.nio.file.Files
-
-fun main(args: Array<String>) {
- val showUsage = args.isEmpty() || when (args.singleOrNull()) {
- "-h", "--help" -> true
- else -> false
- }
- if (showUsage) {
- usage()
- return
- }
-
- val files = args.flatMap {
- File(it).walk().filter { it.isFile && it.extension == "java" }.map { it.toPath() }
- }
- val persistences = parse(files)
- for (persistence in persistences) {
- val file = generate(persistence)
- Files.newBufferedWriter(persistence.path).use {
- it.write(FILE_HEADER)
- file.writeTo(it)
- }
- }
-}
-
-private fun usage() {
- println("Usage: xmlpersistence <FILES>")
-}
diff --git a/tools/xmlpersistence/src/main/kotlin/Parser.kt b/tools/xmlpersistence/src/main/kotlin/Parser.kt
deleted file mode 100644
index 3ea12a9aa389..000000000000
--- a/tools/xmlpersistence/src/main/kotlin/Parser.kt
+++ /dev/null
@@ -1,248 +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.
- */
-
-import com.github.javaparser.JavaParser
-import com.github.javaparser.ParseProblemException
-import com.github.javaparser.ParseResult
-import com.github.javaparser.ParserConfiguration
-import com.github.javaparser.ast.Node
-import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration
-import com.github.javaparser.ast.body.FieldDeclaration
-import com.github.javaparser.ast.body.TypeDeclaration
-import com.github.javaparser.ast.expr.AnnotationExpr
-import com.github.javaparser.ast.expr.Expression
-import com.github.javaparser.ast.expr.NormalAnnotationExpr
-import com.github.javaparser.ast.expr.SingleMemberAnnotationExpr
-import com.github.javaparser.ast.expr.StringLiteralExpr
-import com.github.javaparser.resolution.declarations.ResolvedReferenceTypeDeclaration
-import com.github.javaparser.resolution.types.ResolvedPrimitiveType
-import com.github.javaparser.resolution.types.ResolvedReferenceType
-import com.github.javaparser.symbolsolver.JavaSymbolSolver
-import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserClassDeclaration
-import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver
-import com.github.javaparser.symbolsolver.resolution.typesolvers.MemoryTypeSolver
-import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver
-import com.squareup.javapoet.ClassName
-import com.squareup.javapoet.ParameterizedTypeName
-import com.squareup.javapoet.TypeName
-import java.nio.file.Path
-import java.util.Optional
-
-class PersistenceInfo(
- val name: String,
- val root: ClassFieldInfo,
- val path: Path
-)
-
-sealed class FieldInfo {
- abstract val name: String
- abstract val xmlName: String?
- abstract val type: TypeName
- abstract val isRequired: Boolean
-}
-
-class PrimitiveFieldInfo(
- override val name: String,
- override val xmlName: String?,
- override val type: TypeName,
- override val isRequired: Boolean
-) : FieldInfo()
-
-class StringFieldInfo(
- override val name: String,
- override val xmlName: String?,
- override val isRequired: Boolean
-) : FieldInfo() {
- override val type: TypeName = ClassName.get(String::class.java)
-}
-
-class ClassFieldInfo(
- override val name: String,
- override val xmlName: String?,
- override val type: ClassName,
- override val isRequired: Boolean,
- val fields: List<FieldInfo>
-) : FieldInfo()
-
-class ListFieldInfo(
- override val name: String,
- override val xmlName: String?,
- override val type: ParameterizedTypeName,
- val element: ClassFieldInfo
-) : FieldInfo() {
- override val isRequired: Boolean = true
-}
-
-fun parse(files: List<Path>): List<PersistenceInfo> {
- val typeSolver = CombinedTypeSolver().apply { add(ReflectionTypeSolver()) }
- val javaParser = JavaParser(ParserConfiguration()
- .setSymbolResolver(JavaSymbolSolver(typeSolver)))
- val compilationUnits = files.map { javaParser.parse(it).getOrThrow() }
- val memoryTypeSolver = MemoryTypeSolver().apply {
- for (compilationUnit in compilationUnits) {
- for (typeDeclaration in compilationUnit.getNodesByClass<TypeDeclaration<*>>()) {
- val name = typeDeclaration.fullyQualifiedName.getOrNull() ?: continue
- addDeclaration(name, typeDeclaration.resolve())
- }
- }
- }
- typeSolver.add(memoryTypeSolver)
- return mutableListOf<PersistenceInfo>().apply {
- for (compilationUnit in compilationUnits) {
- val classDeclarations = compilationUnit
- .getNodesByClass<ClassOrInterfaceDeclaration>()
- .filter { !it.isInterface && (!it.isNestedType || it.isStatic) }
- this += classDeclarations.mapNotNull { parsePersistenceInfo(it) }
- }
- }
-}
-
-private fun parsePersistenceInfo(classDeclaration: ClassOrInterfaceDeclaration): PersistenceInfo? {
- val annotation = classDeclaration.getAnnotationByName("XmlPersistence").getOrNull()
- ?: return null
- val rootClassName = classDeclaration.nameAsString
- val name = annotation.getMemberValue("value")?.stringLiteralValue
- ?: "${rootClassName}Persistence"
- val rootXmlName = classDeclaration.getAnnotationByName("XmlName").getOrNull()
- ?.getMemberValue("value")?.stringLiteralValue
- val root = parseClassFieldInfo(
- rootXmlName ?: rootClassName, rootXmlName, true, classDeclaration
- )
- val path = classDeclaration.findCompilationUnit().get().storage.get().path
- .resolveSibling("$name.java")
- return PersistenceInfo(name, root, path)
-}
-
-private fun parseClassFieldInfo(
- name: String,
- xmlName: String?,
- isRequired: Boolean,
- classDeclaration: ClassOrInterfaceDeclaration
-): ClassFieldInfo {
- val fields = classDeclaration.fields.filterNot { it.isStatic }.map { parseFieldInfo(it) }
- val type = classDeclaration.resolve().typeName
- return ClassFieldInfo(name, xmlName, type, isRequired, fields)
-}
-
-private fun parseFieldInfo(field: FieldDeclaration): FieldInfo {
- require(field.isPublic && field.isFinal)
- val variable = field.variables.single()
- val name = variable.nameAsString
- val annotations = field.annotations + variable.type.annotations
- val annotation = annotations.getByName("XmlName")
- val xmlName = annotation?.getMemberValue("value")?.stringLiteralValue
- val isRequired = annotations.getByName("NonNull") != null
- return when (val type = variable.type.resolve()) {
- is ResolvedPrimitiveType -> {
- val primitiveType = type.typeName
- PrimitiveFieldInfo(name, xmlName, primitiveType, true)
- }
- is ResolvedReferenceType -> {
- when (type.qualifiedName) {
- Boolean::class.javaObjectType.name, Byte::class.javaObjectType.name,
- Short::class.javaObjectType.name, Char::class.javaObjectType.name,
- Integer::class.javaObjectType.name, Long::class.javaObjectType.name,
- Float::class.javaObjectType.name, Double::class.javaObjectType.name ->
- PrimitiveFieldInfo(name, xmlName, type.typeName, isRequired)
- String::class.java.name -> StringFieldInfo(name, xmlName, isRequired)
- List::class.java.name -> {
- requireNotNull(xmlName)
- val elementType = type.typeParametersValues().single()
- require(elementType is ResolvedReferenceType)
- val listType = ParameterizedTypeName.get(
- ClassName.get(List::class.java), elementType.typeName
- )
- val element = parseClassFieldInfo(
- "(element)", xmlName, true, elementType.classDeclaration
- )
- ListFieldInfo(name, xmlName, listType, element)
- }
- else -> parseClassFieldInfo(name, xmlName, isRequired, type.classDeclaration)
- }
- }
- else -> error(type)
- }
-}
-
-private fun <T> ParseResult<T>.getOrThrow(): T =
- if (isSuccessful) {
- result.get()
- } else {
- throw ParseProblemException(problems)
- }
-
-private inline fun <reified T : Node> Node.getNodesByClass(): List<T> =
- getNodesByClass(T::class.java)
-
-private fun <T : Node> Node.getNodesByClass(klass: Class<T>): List<T> = mutableListOf<T>().apply {
- if (klass.isInstance(this@getNodesByClass)) {
- this += klass.cast(this@getNodesByClass)
- }
- for (childNode in childNodes) {
- this += childNode.getNodesByClass(klass)
- }
-}
-
-private fun <T> Optional<T>.getOrNull(): T? = orElse(null)
-
-private fun List<AnnotationExpr>.getByName(name: String): AnnotationExpr? =
- find { it.name.identifier == name }
-
-private fun AnnotationExpr.getMemberValue(name: String): Expression? =
- when (this) {
- is NormalAnnotationExpr -> pairs.find { it.nameAsString == name }?.value
- is SingleMemberAnnotationExpr -> if (name == "value") memberValue else null
- else -> null
- }
-
-private val Expression.stringLiteralValue: String
- get() {
- require(this is StringLiteralExpr)
- return value
- }
-
-private val ResolvedReferenceType.classDeclaration: ClassOrInterfaceDeclaration
- get() {
- val resolvedClassDeclaration = typeDeclaration
- require(resolvedClassDeclaration is JavaParserClassDeclaration)
- return resolvedClassDeclaration.wrappedNode
- }
-
-private val ResolvedPrimitiveType.typeName: TypeName
- get() =
- when (this) {
- ResolvedPrimitiveType.BOOLEAN -> TypeName.BOOLEAN
- ResolvedPrimitiveType.BYTE -> TypeName.BYTE
- ResolvedPrimitiveType.SHORT -> TypeName.SHORT
- ResolvedPrimitiveType.CHAR -> TypeName.CHAR
- ResolvedPrimitiveType.INT -> TypeName.INT
- ResolvedPrimitiveType.LONG -> TypeName.LONG
- ResolvedPrimitiveType.FLOAT -> TypeName.FLOAT
- ResolvedPrimitiveType.DOUBLE -> TypeName.DOUBLE
- }
-
-// This doesn't support type parameters.
-private val ResolvedReferenceType.typeName: TypeName
- get() = typeDeclaration.typeName
-
-private val ResolvedReferenceTypeDeclaration.typeName: ClassName
- get() {
- val packageName = packageName
- val classNames = className.split(".")
- val topLevelClassName = classNames.first()
- val nestedClassNames = classNames.drop(1)
- return ClassName.get(packageName, topLevelClassName, *nestedClassNames.toTypedArray())
- }
diff --git a/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt b/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt
deleted file mode 100644
index b4bdbba7170b..000000000000
--- a/tools/xmlpersistence/src/main/kotlin/StringCaseExtensions.kt
+++ /dev/null
@@ -1,44 +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.
- */
-
-import java.util.Locale
-
-private val camelHumpBoundary = Regex(
- "-"
- + "|_"
- + "|(?<=[0-9])(?=[^0-9])"
- + "|(?<=[A-Z])(?=[^A-Za-z]|[A-Z][a-z])"
- + "|(?<=[a-z])(?=[^a-z])"
-)
-
-private fun String.toCamelHumps(): List<String> = split(camelHumpBoundary)
-
-fun String.toUpperCamelCase(): String =
- toCamelHumps().joinToString("") { it.toLowerCase(Locale.ROOT).capitalize(Locale.ROOT) }
-
-fun String.toLowerCamelCase(): String = toUpperCamelCase().decapitalize(Locale.ROOT)
-
-fun String.toUpperKebabCase(): String =
- toCamelHumps().joinToString("-") { it.toUpperCase(Locale.ROOT) }
-
-fun String.toLowerKebabCase(): String =
- toCamelHumps().joinToString("-") { it.toLowerCase(Locale.ROOT) }
-
-fun String.toUpperSnakeCase(): String =
- toCamelHumps().joinToString("_") { it.toUpperCase(Locale.ROOT) }
-
-fun String.toLowerSnakeCase(): String =
- toCamelHumps().joinToString("_") { it.toLowerCase(Locale.ROOT) }