summaryrefslogtreecommitdiff
path: root/libnativeloader/test
diff options
context:
space:
mode:
Diffstat (limited to 'libnativeloader/test')
-rw-r--r--libnativeloader/test/Android.bp191
-rw-r--r--libnativeloader/test/Android.mk72
-rw-r--r--libnativeloader/test/libnativeloader_e2e_tests.xml47
-rw-r--r--libnativeloader/test/library_container_app_manifest.xml (renamed from libnativeloader/test/system/AndroidManifest.xml)15
-rw-r--r--libnativeloader/test/libsystem_testlib.cc31
-rw-r--r--libnativeloader/test/loadlibrarytest_data_app_manifest.xml38
-rw-r--r--libnativeloader/test/loadlibrarytest_product_app_manifest.xml38
-rw-r--r--libnativeloader/test/loadlibrarytest_system_app_manifest.xml35
-rw-r--r--libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml35
-rw-r--r--libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml35
-rw-r--r--libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml38
-rw-r--r--libnativeloader/test/public.libraries-oem1.txt2
-rw-r--r--libnativeloader/test/public.libraries-oem2.txt2
-rw-r--r--libnativeloader/test/public.libraries-product1.txt2
-rwxr-xr-xlibnativeloader/test/runtest.sh11
-rw-r--r--libnativeloader/test/src/android/test/app/DataAppTest.java112
-rw-r--r--libnativeloader/test/src/android/test/app/ProductAppTest.java111
-rw-r--r--libnativeloader/test/src/android/test/app/SystemAppTest.java106
-rw-r--r--libnativeloader/test/src/android/test/app/TestActivity.java44
-rw-r--r--libnativeloader/test/src/android/test/app/VendorAppTest.java111
-rw-r--r--libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java388
-rw-r--r--libnativeloader/test/src/android/test/lib/TestUtils.java41
-rw-r--r--libnativeloader/test/src/android/test/productsharedlib/ProductSharedLib.java (renamed from libnativeloader/test/test.cpp)10
-rw-r--r--libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java (renamed from libnativeloader/test/vendor/AndroidManifest.xml)24
-rw-r--r--libnativeloader/test/src/android/test/systemsharedlib/SystemSharedLib.java21
-rw-r--r--libnativeloader/test/src/android/test/vendorsharedlib/VendorSharedLib.java21
26 files changed, 1378 insertions, 203 deletions
diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp
index fb9ae0d9d3..95b9b886dd 100644
--- a/libnativeloader/test/Android.bp
+++ b/libnativeloader/test/Android.bp
@@ -23,58 +23,179 @@ package {
default_applicable_licenses: ["art_license"],
}
+// A native library that goes into /system or /system_ext and that depends on
+// a non-public library that is linked from the system namespace.
cc_library {
- name: "libfoo.oem1",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libfoo.oem1.so\""],
- shared_libs: [
- "libbase",
- ],
+ name: "libsystem_testlib",
+ min_sdk_version: "31",
+ stl: "libc++_static",
+ shared_libs: ["liblog"],
+ // It's difficult to add a shared_lib dependency on a non-public library
+ // here, so it dlopens one instead.
+ srcs: ["libsystem_testlib.cc"],
}
+// A native library that goes into /product.
cc_library {
- name: "libbar.oem1",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libbar.oem1.so\""],
- shared_libs: [
- "libbase",
- ],
+ name: "libproduct_testlib",
+ min_sdk_version: "31",
+ stl: "none",
+ srcs: [],
}
+// A native library that goes into /vendor.
cc_library {
- name: "libfoo.oem2",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libfoo.oem2.so\""],
- shared_libs: [
- "libbase",
+ name: "libvendor_testlib",
+ min_sdk_version: "31",
+ stl: "none",
+ srcs: [],
+}
+
+// This app is just an intermediate container to be able to include the .so
+// library in the host test. It's not actually installed or started.
+android_test_helper_app {
+ name: "library_container_app",
+ defaults: ["art_module_source_build_java_defaults"],
+ min_sdk_version: "31",
+ manifest: "library_container_app_manifest.xml",
+ compile_multilib: "both",
+ jni_libs: [
+ "libsystem_testlib",
+ "libproduct_testlib",
+ "libvendor_testlib",
],
}
-cc_library {
- name: "libbar.oem2",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libbar.oem2.so\""],
- shared_libs: [
- "libbase",
+java_library {
+ name: "loadlibrarytest_test_utils",
+ sdk_version: "31",
+ static_libs: [
+ "androidx.test.ext.junit",
+ "androidx.test.ext.truth",
],
+ srcs: ["src/android/test/lib/TestUtils.java"],
}
-cc_library {
- name: "libfoo.product1",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libfoo.product1.so\""],
+// Test fixture that represents a shared library in /system/framework.
+java_library {
+ name: "libnativeloader_system_shared_lib",
+ sdk_version: "31",
+ installable: true,
+ srcs: ["src/android/test/systemsharedlib/SystemSharedLib.java"],
+}
+
+// Test fixture that represents a shared library in /system_ext/framework.
+java_library {
+ name: "libnativeloader_system_ext_shared_lib",
+ sdk_version: "31",
+ installable: true,
+ srcs: ["src/android/test/systemextsharedlib/SystemExtSharedLib.java"],
+}
+
+// Test fixture that represents a shared library in /product/framework.
+java_library {
+ name: "libnativeloader_product_shared_lib",
product_specific: true,
- shared_libs: [
- "libbase",
+ sdk_version: "31",
+ installable: true,
+ srcs: ["src/android/test/productsharedlib/ProductSharedLib.java"],
+}
+
+// Test fixture that represents a shared library in /vendor/framework.
+java_library {
+ name: "libnativeloader_vendor_shared_lib",
+ vendor: true,
+ sdk_version: "31",
+ installable: true,
+ srcs: ["src/android/test/vendorsharedlib/VendorSharedLib.java"],
+}
+
+java_defaults {
+ name: "loadlibrarytest_app_defaults",
+ defaults: ["art_module_source_build_java_defaults"],
+ sdk_version: "31",
+ static_libs: [
+ "androidx.test.ext.junit",
+ "androidx.test.rules",
+ "loadlibrarytest_test_utils",
+ ],
+ libs: [
+ "libnativeloader_system_shared_lib",
+ "libnativeloader_system_ext_shared_lib",
+ "libnativeloader_product_shared_lib",
+ "libnativeloader_vendor_shared_lib",
],
}
-cc_library {
- name: "libbar.product1",
- srcs: ["test.cpp"],
- cflags: ["-DLIBNAME=\"libbar.product1.so\""],
+android_test_helper_app {
+ name: "loadlibrarytest_system_priv_app",
+ defaults: ["loadlibrarytest_app_defaults"],
+ manifest: "loadlibrarytest_system_priv_app_manifest.xml",
+ // /system/priv-app currently reuses the same test as /system/app.
+ srcs: ["src/android/test/app/SystemAppTest.java"],
+}
+
+android_test_helper_app {
+ name: "loadlibrarytest_system_app",
+ defaults: ["loadlibrarytest_app_defaults"],
+ manifest: "loadlibrarytest_system_app_manifest.xml",
+ srcs: ["src/android/test/app/SystemAppTest.java"],
+}
+
+android_test_helper_app {
+ name: "loadlibrarytest_system_ext_app",
+ defaults: ["loadlibrarytest_app_defaults"],
+ system_ext_specific: true,
+ manifest: "loadlibrarytest_system_ext_app_manifest.xml",
+ // /system_ext should behave the same as /system, so use the same test class there.
+ srcs: ["src/android/test/app/SystemAppTest.java"],
+}
+
+android_test_helper_app {
+ name: "loadlibrarytest_product_app",
+ defaults: ["loadlibrarytest_app_defaults"],
product_specific: true,
- shared_libs: [
- "libbase",
+ manifest: "loadlibrarytest_product_app_manifest.xml",
+ srcs: ["src/android/test/app/ProductAppTest.java"],
+}
+
+android_test_helper_app {
+ name: "loadlibrarytest_vendor_app",
+ defaults: ["loadlibrarytest_app_defaults"],
+ vendor: true,
+ manifest: "loadlibrarytest_vendor_app_manifest.xml",
+ srcs: ["src/android/test/app/VendorAppTest.java"],
+}
+
+// A normal app installed in /data.
+android_test_helper_app {
+ name: "loadlibrarytest_data_app",
+ defaults: ["loadlibrarytest_app_defaults"],
+ manifest: "loadlibrarytest_data_app_manifest.xml",
+ srcs: ["src/android/test/app/DataAppTest.java"],
+}
+
+java_test_host {
+ name: "libnativeloader_e2e_tests",
+ defaults: ["art_module_source_build_java_defaults"],
+ srcs: ["src/android/test/hostside/*.java"],
+ libs: [
+ "compatibility-tradefed",
+ "tradefed",
+ ],
+ data: [
+ ":library_container_app",
+ ":libnativeloader_system_shared_lib",
+ ":libnativeloader_system_ext_shared_lib",
+ ":libnativeloader_product_shared_lib",
+ ":libnativeloader_vendor_shared_lib",
+ ":loadlibrarytest_system_priv_app",
+ ":loadlibrarytest_system_app",
+ ":loadlibrarytest_system_ext_app",
+ ":loadlibrarytest_product_app",
+ ":loadlibrarytest_vendor_app",
+ ":loadlibrarytest_data_app",
],
+ test_config: "libnativeloader_e2e_tests.xml",
+ test_suites: ["general-tests"],
}
diff --git a/libnativeloader/test/Android.mk b/libnativeloader/test/Android.mk
deleted file mode 100644
index 95fa68af68..0000000000
--- a/libnativeloader/test/Android.mk
+++ /dev/null
@@ -1,72 +0,0 @@
-#
-# Copyright (C) 2017 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := public.libraries-oem1.txt
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-LOCAL_SRC_FILES:= $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := public.libraries-oem2.txt
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-LOCAL_SRC_FILES:= $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := public.libraries-product1.txt
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-LOCAL_SRC_FILES:= $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT_ETC)
-include $(BUILD_PREBUILT)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := oemlibrarytest-system
-LOCAL_MODULE_TAGS := tests
-LOCAL_MANIFEST_FILE := system/AndroidManifest.xml
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_MODULE_PATH := $(TARGET_OUT_APPS)
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-include $(BUILD_PACKAGE)
-
-include $(CLEAR_VARS)
-LOCAL_PACKAGE_NAME := oemlibrarytest-vendor
-LOCAL_MODULE_TAGS := tests
-LOCAL_MANIFEST_FILE := vendor/AndroidManifest.xml
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_SDK_VERSION := current
-LOCAL_PROGUARD_ENABLED := disabled
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_APPS)
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../../NOTICE
-include $(BUILD_PACKAGE)
diff --git a/libnativeloader/test/libnativeloader_e2e_tests.xml b/libnativeloader/test/libnativeloader_e2e_tests.xml
new file mode 100644
index 0000000000..d4f6348886
--- /dev/null
+++ b/libnativeloader/test/libnativeloader_e2e_tests.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<configuration description="Config for libnativeloader e2e test cases">
+ <option name="test-suite-tag" value="libnativeloader_e2e_tests" />
+ <option name="test-suite-tag" value="apct" />
+ <option name="config-descriptor:metadata" key="mainline-param" value="com.google.android.art.apex" />
+
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer" />
+
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <!-- We push all files in LibnativeloaderTest.java, but use this
+ preparer to make partitions writable. That since remounting may
+ require a device reboot, and then it's important that the
+ `setenforce 0` from DisableSELinuxTargetPreparer occurs after that. -->
+ <option name="remount-system" value="true" />
+ <option name="remount-vendor" value="true" />
+ </target_preparer>
+
+ <!-- Vendor native libraries aren't accessible by any apps by sepolicy
+ rules. For that they need to be labelled same_process_hal_file in a
+ vendor specific file_contexts file (see
+ https://source.android.com/docs/core/permissions/namespaces_libraries#adding-additional-native-libraries).
+ To avoid setting that up to test loading libvendor_private*.so, disable
+ sepolicy checks while running the tests. It's libnativeloader logic we
+ want to test here. -->
+ <target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer"/>
+
+ <test class="com.android.tradefed.testtype.HostTest" >
+ <option name="jar" value="libnativeloader_e2e_tests.jar" />
+ </test>
+
+ <!-- Only run tests if the device under test is SDK version 31 (Android 12) or above. -->
+ <object type="module_controller" class="com.android.tradefed.testtype.suite.module.Sdk31ModuleController" />
+</configuration>
diff --git a/libnativeloader/test/system/AndroidManifest.xml b/libnativeloader/test/library_container_app_manifest.xml
index c3048891a8..20030de7eb 100644
--- a/libnativeloader/test/system/AndroidManifest.xml
+++ b/libnativeloader/test/library_container_app_manifest.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -16,16 +16,5 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.test.app.system">
-
- <application>
- <activity android:name="android.test.app.TestActivity" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
+ package="android.test.app.container">
</manifest>
-
diff --git a/libnativeloader/test/libsystem_testlib.cc b/libnativeloader/test/libsystem_testlib.cc
new file mode 100644
index 0000000000..97d32237b4
--- /dev/null
+++ b/libnativeloader/test/libsystem_testlib.cc
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dlfcn.h>
+
+#include "log/log.h"
+
+static void __attribute__((constructor)) ctor() {
+ // Load a library that should be available to system libraries through a
+ // linked namespace (i.e. is not directly in /system/${LIB}), and that is not
+ // in public.libraries.txt. We use a real one to avoid having to set up an
+ // APEX test fixture and rerun linkerconfig.
+ void* h = dlopen("libandroidicu.so", RTLD_NOW);
+ if (h == nullptr) {
+ LOG_ALWAYS_FATAL("Failed to load dependency: %s", dlerror());
+ }
+ dlclose(h);
+}
diff --git a/libnativeloader/test/loadlibrarytest_data_app_manifest.xml b/libnativeloader/test/loadlibrarytest_data_app_manifest.xml
new file mode 100644
index 0000000000..4be78f84f9
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_data_app_manifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2022 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.data">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.data" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem2.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub1.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub2.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub3.oem1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/loadlibrarytest_product_app_manifest.xml b/libnativeloader/test/loadlibrarytest_product_app_manifest.xml
new file mode 100644
index 0000000000..9061c396e1
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_product_app_manifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.product">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.product" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem2.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub1.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub2.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub3.oem1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/loadlibrarytest_system_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_app_manifest.xml
new file mode 100644
index 0000000000..7ee7532d1c
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_system_app_manifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.system">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.system" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <!-- System apps get a shared classloader namespace, so they don't need
+ uses-native-library entries for anything in /system or /system_ext. -->
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml
new file mode 100644
index 0000000000..a2c1a2c8db
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_system_ext_app_manifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.system_ext">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.system_ext" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <!-- System apps get a shared classloader namespace, so they don't need
+ uses-native-library entries for anything in /system or /system_ext. -->
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml b/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml
new file mode 100644
index 0000000000..87a30cec12
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_system_priv_app_manifest.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.system_priv">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.system_priv" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <!-- System apps get a shared classloader namespace, so they don't need
+ uses-native-library entries for anything in /system or /system_ext. -->
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml b/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml
new file mode 100644
index 0000000000..b3434fb930
--- /dev/null
+++ b/libnativeloader/test/loadlibrarytest_vendor_app_manifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="android.test.app.vendor">
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="android.test.app.vendor" />
+ <application>
+ <uses-library android:required="false" android:name="android.test.systemsharedlib" />
+ <uses-library android:required="false" android:name="android.test.systemextsharedlib" />
+ <uses-library android:required="false" android:name="android.test.productsharedlib" />
+ <uses-library android:required="false" android:name="android.test.vendorsharedlib" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub.oem2.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub1.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub2.oem1.so" />
+ <uses-native-library android:required="false" android:name="libsystem_extpub3.oem1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub1.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub2.product1.so" />
+ <uses-native-library android:required="false" android:name="libproduct_extpub3.product1.so" />
+ </application>
+</manifest>
+
diff --git a/libnativeloader/test/public.libraries-oem1.txt b/libnativeloader/test/public.libraries-oem1.txt
deleted file mode 100644
index f9433e2a04..0000000000
--- a/libnativeloader/test/public.libraries-oem1.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-libfoo.oem1.so
-libbar.oem1.so
diff --git a/libnativeloader/test/public.libraries-oem2.txt b/libnativeloader/test/public.libraries-oem2.txt
deleted file mode 100644
index de6bdb08e0..0000000000
--- a/libnativeloader/test/public.libraries-oem2.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-libfoo.oem2.so
-libbar.oem2.so
diff --git a/libnativeloader/test/public.libraries-product1.txt b/libnativeloader/test/public.libraries-product1.txt
deleted file mode 100644
index 358154c626..0000000000
--- a/libnativeloader/test/public.libraries-product1.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-libfoo.product1.so
-libbar.product1.so
diff --git a/libnativeloader/test/runtest.sh b/libnativeloader/test/runtest.sh
deleted file mode 100755
index 40beb5b4d5..0000000000
--- a/libnativeloader/test/runtest.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/bash
-adb root
-adb remount
-adb sync
-adb shell stop
-adb shell start
-sleep 5 # wait until device reboots
-adb logcat -c;
-adb shell am start -n android.test.app.system/android.test.app.TestActivity
-adb shell am start -n android.test.app.vendor/android.test.app.TestActivity
-adb logcat | grep android.test.app
diff --git a/libnativeloader/test/src/android/test/app/DataAppTest.java b/libnativeloader/test/src/android/test/app/DataAppTest.java
new file mode 100644
index 0000000000..9403494df6
--- /dev/null
+++ b/libnativeloader/test/src/android/test/app/DataAppTest.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2022 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.app;
+
+import android.test.lib.TestUtils;
+import android.test.productsharedlib.ProductSharedLib;
+import android.test.systemextsharedlib.SystemExtSharedLib;
+import android.test.systemsharedlib.SystemSharedLib;
+import android.test.vendorsharedlib.VendorSharedLib;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class DataAppTest {
+ @Test
+ public void testLoadExtendedPublicLibraries() {
+ System.loadLibrary("system_extpub.oem1");
+ System.loadLibrary("system_extpub.oem2");
+ System.loadLibrary("system_extpub1.oem1");
+ TestUtils.assertLinkerNamespaceError( // Missing <uses-native-library>.
+ () -> System.loadLibrary("system_extpub_nouses.oem2"));
+ System.loadLibrary("product_extpub.product1");
+ System.loadLibrary("product_extpub1.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibraries() {
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesViaSystemSharedLib() {
+ SystemSharedLib.loadLibrary("system_extpub2.oem1");
+ SystemSharedLib.loadLibrary("product_extpub2.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemSharedLib.loadLibrary("system_private2");
+ // SystemSharedLib.loadLibrary("systemext_private2");
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemExtSharedLib.loadLibrary("system_private3");
+ // SystemExtSharedLib.loadLibrary("systemext_private3");
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaProductSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> ProductSharedLib.loadLibrary("system_private4"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> ProductSharedLib.loadLibrary("systemext_private4"));
+ ProductSharedLib.loadLibrary("product_private4");
+ TestUtils.assertLibraryNotFound(() -> ProductSharedLib.loadLibrary("vendor_private4"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaVendorSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> VendorSharedLib.loadLibrary("system_private5"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> VendorSharedLib.loadLibrary("systemext_private5"));
+ TestUtils.assertLibraryNotFound(() -> VendorSharedLib.loadLibrary("product_private5"));
+ VendorSharedLib.loadLibrary("vendor_private5");
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesWithAbsolutePaths() {
+ System.load(TestUtils.libPath("/system", "system_extpub3.oem1"));
+ System.load(TestUtils.libPath("/product", "product_extpub3.product1"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesWithAbsolutePaths() {
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system", "system_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system_ext", "systemext_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/product", "product_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/vendor", "vendor_private6")));
+ }
+}
diff --git a/libnativeloader/test/src/android/test/app/ProductAppTest.java b/libnativeloader/test/src/android/test/app/ProductAppTest.java
new file mode 100644
index 0000000000..7ec817b642
--- /dev/null
+++ b/libnativeloader/test/src/android/test/app/ProductAppTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.app;
+
+import android.test.lib.TestUtils;
+import android.test.productsharedlib.ProductSharedLib;
+import android.test.systemextsharedlib.SystemExtSharedLib;
+import android.test.systemsharedlib.SystemSharedLib;
+import android.test.vendorsharedlib.VendorSharedLib;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class ProductAppTest {
+ @Test
+ public void testLoadExtendedPublicLibraries() {
+ System.loadLibrary("system_extpub.oem1");
+ System.loadLibrary("system_extpub.oem2");
+ System.loadLibrary("system_extpub1.oem1");
+ TestUtils.assertLinkerNamespaceError( // Missing <uses-native-library>.
+ () -> System.loadLibrary("system_extpub_nouses.oem2"));
+ System.loadLibrary("product_extpub.product1");
+ System.loadLibrary("product_extpub1.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibraries() {
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
+ System.loadLibrary("product_private1");
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesViaSystemSharedLib() {
+ SystemSharedLib.loadLibrary("system_extpub2.oem1");
+ SystemSharedLib.loadLibrary("product_extpub2.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemSharedLib.loadLibrary("system_private2");
+ // SystemSharedLib.loadLibrary("systemext_private2");
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemExtSharedLib.loadLibrary("system_private3");
+ // SystemExtSharedLib.loadLibrary("systemext_private3");
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaProductSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> ProductSharedLib.loadLibrary("system_private4"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> ProductSharedLib.loadLibrary("systemext_private4"));
+ ProductSharedLib.loadLibrary("product_private4");
+ TestUtils.assertLibraryNotFound(() -> ProductSharedLib.loadLibrary("vendor_private4"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaVendorSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> VendorSharedLib.loadLibrary("system_private5"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> VendorSharedLib.loadLibrary("systemext_private5"));
+ TestUtils.assertLibraryNotFound(() -> VendorSharedLib.loadLibrary("product_private5"));
+ VendorSharedLib.loadLibrary("vendor_private5");
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesWithAbsolutePaths() {
+ System.load(TestUtils.libPath("/system", "system_extpub3.oem1"));
+ System.load(TestUtils.libPath("/product", "product_extpub3.product1"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesWithAbsolutePaths() {
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system", "system_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system_ext", "systemext_private6")));
+ System.load(TestUtils.libPath("/product", "product_private6"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/vendor", "vendor_private6")));
+ }
+}
diff --git a/libnativeloader/test/src/android/test/app/SystemAppTest.java b/libnativeloader/test/src/android/test/app/SystemAppTest.java
new file mode 100644
index 0000000000..cabdfb7e75
--- /dev/null
+++ b/libnativeloader/test/src/android/test/app/SystemAppTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2022 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.app;
+
+import android.test.lib.TestUtils;
+import android.test.productsharedlib.ProductSharedLib;
+import android.test.systemextsharedlib.SystemExtSharedLib;
+import android.test.systemsharedlib.SystemSharedLib;
+import android.test.vendorsharedlib.VendorSharedLib;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+// These tests are run from /system/app, /system/priv-app, and /system_ext/app.
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class SystemAppTest {
+ @Test
+ public void testLoadExtendedPublicLibraries() {
+ System.loadLibrary("system_extpub.oem1");
+ System.loadLibrary("system_extpub.oem2");
+ System.loadLibrary("system_extpub1.oem1");
+ // Missing <uses-native-library> not relevant for system apps, which have shared classloader
+ // namespaces.
+ System.loadLibrary("system_extpub_nouses.oem2");
+ System.loadLibrary("product_extpub.product1");
+ System.loadLibrary("product_extpub1.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibraries() {
+ System.loadLibrary("system_private1");
+ System.loadLibrary("systemext_private1");
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("vendor_private1"));
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesViaSystemSharedLib() {
+ SystemSharedLib.loadLibrary("system_extpub2.oem1");
+ SystemSharedLib.loadLibrary("product_extpub2.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemSharedLib() {
+ SystemSharedLib.loadLibrary("system_private2");
+ SystemSharedLib.loadLibrary("systemext_private2");
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
+ SystemExtSharedLib.loadLibrary("system_private3");
+ SystemExtSharedLib.loadLibrary("systemext_private3");
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaProductSharedLib() {
+ ProductSharedLib.loadLibrary("system_private4");
+ ProductSharedLib.loadLibrary("systemext_private4");
+ TestUtils.assertLibraryNotFound(() -> ProductSharedLib.loadLibrary("product_private4"));
+ TestUtils.assertLibraryNotFound(() -> ProductSharedLib.loadLibrary("vendor_private4"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaVendorSharedLib() {
+ VendorSharedLib.loadLibrary("system_private5");
+ VendorSharedLib.loadLibrary("systemext_private5");
+ TestUtils.assertLibraryNotFound(() -> VendorSharedLib.loadLibrary("product_private5"));
+ TestUtils.assertLibraryNotFound(() -> VendorSharedLib.loadLibrary("vendor_private5"));
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesWithAbsolutePaths() {
+ System.load(TestUtils.libPath("/system", "system_extpub3.oem1"));
+ System.load(TestUtils.libPath("/product", "product_extpub3.product1"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesWithAbsolutePaths() {
+ System.load(TestUtils.libPath("/system", "system_private6"));
+ System.load(TestUtils.libPath("/system_ext", "systemext_private6"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/product", "product_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/vendor", "vendor_private6")));
+ }
+}
diff --git a/libnativeloader/test/src/android/test/app/TestActivity.java b/libnativeloader/test/src/android/test/app/TestActivity.java
deleted file mode 100644
index a7a455d33d..0000000000
--- a/libnativeloader/test/src/android/test/app/TestActivity.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.test.app;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-
-public class TestActivity extends Activity {
-
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- tryLoadingLib("foo.oem1");
- tryLoadingLib("bar.oem1");
- tryLoadingLib("foo.oem2");
- tryLoadingLib("bar.oem2");
- tryLoadingLib("foo.product1");
- tryLoadingLib("bar.product1");
- }
-
- private void tryLoadingLib(String name) {
- try {
- System.loadLibrary(name);
- Log.d(getPackageName(), "library " + name + " is successfully loaded");
- } catch (UnsatisfiedLinkError e) {
- Log.d(getPackageName(), "failed to load libarary " + name, e);
- }
- }
-}
diff --git a/libnativeloader/test/src/android/test/app/VendorAppTest.java b/libnativeloader/test/src/android/test/app/VendorAppTest.java
new file mode 100644
index 0000000000..10d0ea04ee
--- /dev/null
+++ b/libnativeloader/test/src/android/test/app/VendorAppTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2022 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.app;
+
+import android.test.lib.TestUtils;
+import android.test.productsharedlib.ProductSharedLib;
+import android.test.systemextsharedlib.SystemExtSharedLib;
+import android.test.systemsharedlib.SystemSharedLib;
+import android.test.vendorsharedlib.VendorSharedLib;
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@MediumTest
+@RunWith(AndroidJUnit4.class)
+public class VendorAppTest {
+ @Test
+ public void testLoadExtendedPublicLibraries() {
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_extpub.oem1"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_extpub.oem2"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_extpub1.oem1"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_extpub_nouses.oem2"));
+ System.loadLibrary("product_extpub.product1");
+ System.loadLibrary("product_extpub1.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibraries() {
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("system_private1"));
+ TestUtils.assertLinkerNamespaceError(() -> System.loadLibrary("systemext_private1"));
+ TestUtils.assertLibraryNotFound(() -> System.loadLibrary("product_private1"));
+ System.loadLibrary("vendor_private1");
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesViaSystemSharedLib() {
+ SystemSharedLib.loadLibrary("system_extpub2.oem1");
+ SystemSharedLib.loadLibrary("product_extpub2.product1");
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemSharedLib.loadLibrary("system_private2");
+ // SystemSharedLib.loadLibrary("systemext_private2");
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("product_private2"));
+ TestUtils.assertLibraryNotFound(() -> SystemSharedLib.loadLibrary("vendor_private2"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaSystemExtSharedLib() {
+ // TODO(b/237577392): Loading a private native system library via a shared system library
+ // ought to work.
+ // SystemExtSharedLib.loadLibrary("system_private3");
+ // SystemExtSharedLib.loadLibrary("systemext_private3");
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("product_private3"));
+ TestUtils.assertLibraryNotFound(() -> SystemExtSharedLib.loadLibrary("vendor_private3"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaProductSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> ProductSharedLib.loadLibrary("system_private4"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> ProductSharedLib.loadLibrary("systemext_private4"));
+ ProductSharedLib.loadLibrary("product_private4");
+ TestUtils.assertLibraryNotFound(() -> ProductSharedLib.loadLibrary("vendor_private4"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesViaVendorSharedLib() {
+ TestUtils.assertLinkerNamespaceError(() -> VendorSharedLib.loadLibrary("system_private5"));
+ TestUtils.assertLinkerNamespaceError(
+ () -> VendorSharedLib.loadLibrary("systemext_private5"));
+ TestUtils.assertLibraryNotFound(() -> VendorSharedLib.loadLibrary("product_private5"));
+ VendorSharedLib.loadLibrary("vendor_private5");
+ }
+
+ @Test
+ public void testLoadExtendedPublicLibrariesWithAbsolutePaths() {
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system", "system_extpub3.oem1")));
+ System.load(TestUtils.libPath("/product", "product_extpub3.product1"));
+ }
+
+ @Test
+ public void testLoadPrivateLibrariesWithAbsolutePaths() {
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system", "system_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/system_ext", "systemext_private6")));
+ TestUtils.assertLinkerNamespaceError(
+ () -> System.load(TestUtils.libPath("/product", "product_private6")));
+ System.load(TestUtils.libPath("/vendor", "vendor_private6"));
+ }
+}
diff --git a/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java b/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java
new file mode 100644
index 0000000000..55a6dd27b3
--- /dev/null
+++ b/libnativeloader/test/src/android/test/hostside/LibnativeloaderTest.java
@@ -0,0 +1,388 @@
+/*
+ * Copyright (C) 2022 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.hostside;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.IInvocationContext;
+import com.android.tradefed.invoker.TestInformation;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
+import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
+import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
+import com.android.tradefed.util.CommandResult;
+
+import com.google.common.io.ByteStreams;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * Test libnativeloader behavior for apps and libs in various partitions by overlaying them over
+ * the system partitions. Requires root.
+ */
+@RunWith(DeviceJUnit4ClassRunner.class)
+public class LibnativeloaderTest extends BaseHostJUnit4Test {
+ private static final String TAG = "LibnativeloaderTest";
+ private static final String CLEANUP_PATHS_KEY = TAG + ":CLEANUP_PATHS";
+ private static final String LOG_FILE_NAME = "TestActivity.log";
+
+ @BeforeClassWithInfo
+ public static void beforeClassWithDevice(TestInformation testInfo) throws Exception {
+ DeviceContext ctx = new DeviceContext(testInfo);
+
+ // A soft reboot is slow, so do setup for all tests and reboot once.
+
+ File libContainerApk = ctx.mBuildHelper.getTestFile("library_container_app.apk");
+ try (ZipFile libApk = new ZipFile(libContainerApk)) {
+ ctx.pushExtendedPublicSystemOemLibs(libApk);
+ ctx.pushExtendedPublicProductLibs(libApk);
+ ctx.pushPrivateLibs(libApk);
+ }
+ ctx.pushSharedLib(
+ "/system", "android.test.systemsharedlib", "libnativeloader_system_shared_lib.jar");
+ ctx.pushSharedLib("/system_ext", "android.test.systemextsharedlib",
+ "libnativeloader_system_ext_shared_lib.jar");
+ ctx.pushSharedLib("/product", "android.test.productsharedlib",
+ "libnativeloader_product_shared_lib.jar");
+ ctx.pushSharedLib(
+ "/vendor", "android.test.vendorsharedlib", "libnativeloader_vendor_shared_lib.jar");
+
+ // "Install" apps in various partitions through plain adb push followed by a soft reboot. We
+ // need them in these locations to test library loading restrictions, so for all except
+ // loadlibrarytest_data_app we cannot use ITestDevice.installPackage for it since it only
+ // installs in /data.
+
+ // For testSystemPrivApp
+ ctx.pushApk("loadlibrarytest_system_priv_app", "/system/priv-app");
+
+ // For testSystemApp
+ ctx.pushApk("loadlibrarytest_system_app", "/system/app");
+
+ // For testSystemExtApp
+ ctx.pushApk("loadlibrarytest_system_ext_app", "/system_ext/app");
+
+ // For testProductApp
+ ctx.pushApk("loadlibrarytest_product_app", "/product/app");
+
+ // For testVendorApp
+ ctx.pushApk("loadlibrarytest_vendor_app", "/vendor/app");
+
+ ctx.softReboot();
+
+ // For testDataApp. Install this the normal way after the system server restart.
+ ctx.installPackage("loadlibrarytest_data_app");
+
+ testInfo.properties().put(CLEANUP_PATHS_KEY, ctx.mCleanup.getPathList());
+ }
+
+ @AfterClassWithInfo
+ public static void afterClassWithDevice(TestInformation testInfo) throws Exception {
+ DeviceContext ctx = new DeviceContext(testInfo);
+
+ // Uninstall loadlibrarytest_data_app.
+ ctx.mDevice.uninstallPackage("android.test.app.data");
+
+ String cleanupPathList = testInfo.properties().get(CLEANUP_PATHS_KEY);
+ CleanupPaths cleanup = new CleanupPaths(ctx.mDevice, cleanupPathList);
+ cleanup.cleanup();
+ }
+
+ @Test
+ public void testSystemPrivApp() throws Exception {
+ // There's currently no difference in the tests between /system/priv-app and /system/app, so
+ // let's reuse the same one.
+ runTests("android.test.app.system_priv", "android.test.app.SystemAppTest");
+ }
+
+ @Test
+ public void testSystemApp() throws Exception {
+ runTests("android.test.app.system", "android.test.app.SystemAppTest");
+ }
+
+ @Test
+ public void testSystemExtApp() throws Exception {
+ // /system_ext should behave the same as /system, so run the same test class there.
+ runTests("android.test.app.system_ext", "android.test.app.SystemAppTest");
+ }
+
+ @Test
+ public void testProductApp() throws Exception {
+ runTests("android.test.app.product", "android.test.app.ProductAppTest");
+ }
+
+ @Test
+ public void testVendorApp() throws Exception {
+ runTests("android.test.app.vendor", "android.test.app.VendorAppTest");
+ }
+
+ @Test
+ public void testDataApp() throws Exception {
+ runTests("android.test.app.data", "android.test.app.DataAppTest");
+ }
+
+ private void runTests(String pkgName, String testClassName) throws Exception {
+ DeviceContext ctx = new DeviceContext(getTestInformation());
+ var options = new DeviceTestRunOptions(pkgName)
+ .setTestClassName(testClassName)
+ .addInstrumentationArg("libDirName", ctx.libDirName());
+ runDeviceTests(options);
+ }
+
+ // Utility class that keeps track of a set of paths the need to be deleted after testing.
+ private static class CleanupPaths {
+ private ITestDevice mDevice;
+ private List<String> mCleanupPaths;
+
+ CleanupPaths(ITestDevice device) {
+ mDevice = device;
+ mCleanupPaths = new ArrayList<String>();
+ }
+
+ CleanupPaths(ITestDevice device, String pathList) {
+ mDevice = device;
+ mCleanupPaths = Arrays.asList(pathList.split(":"));
+ }
+
+ String getPathList() { return String.join(":", mCleanupPaths); }
+
+ // Adds the given path, or its topmost nonexisting parent directory, to the list of paths to
+ // clean up.
+ void addPath(String devicePath) throws DeviceNotAvailableException {
+ File path = new File(devicePath);
+ while (true) {
+ File parentPath = path.getParentFile();
+ if (parentPath == null || mDevice.doesFileExist(parentPath.toString())) {
+ break;
+ }
+ path = parentPath;
+ }
+ String nonExistingPath = path.toString();
+ if (!mCleanupPaths.contains(nonExistingPath)) {
+ mCleanupPaths.add(nonExistingPath);
+ }
+ }
+
+ void cleanup() throws DeviceNotAvailableException {
+ // Clean up in reverse order in case several pushed files were in the same nonexisting
+ // directory.
+ for (int i = mCleanupPaths.size() - 1; i >= 0; --i) {
+ mDevice.deleteFile(mCleanupPaths.get(i));
+ }
+ }
+ }
+
+ // Class for code that needs an ITestDevice. It may be instantiated both in tests and in
+ // (Before|After)ClassWithInfo.
+ private static class DeviceContext implements AutoCloseable {
+ IInvocationContext mContext;
+ ITestDevice mDevice;
+ CompatibilityBuildHelper mBuildHelper;
+ CleanupPaths mCleanup;
+ private String mTestArch;
+
+ DeviceContext(TestInformation testInfo) {
+ mContext = testInfo.getContext();
+ mDevice = testInfo.getDevice();
+ mBuildHelper = new CompatibilityBuildHelper(testInfo.getBuildInfo());
+ mCleanup = new CleanupPaths(mDevice);
+ }
+
+ public void close() throws DeviceNotAvailableException { mCleanup.cleanup(); }
+
+ // Helper class to both push a library to device and record it in a public.libraries-xxx.txt
+ // file.
+ class PublicLibs {
+ private ZipFile mLibApk;
+ private List<String> mPublicLibs = new ArrayList<String>();
+
+ PublicLibs(ZipFile libApk) {
+ mLibApk = libApk;
+ }
+
+ void addLib(String libName, String destDir, String destName) throws Exception {
+ pushNativeTestLib(mLibApk, libName, destDir + "/" + destName);
+ mPublicLibs.add(destName);
+ }
+
+ void pushPublicLibrariesFile(String path) throws DeviceNotAvailableException {
+ pushString(mPublicLibs.stream().collect(Collectors.joining("\n")) + "\n", path);
+ }
+ }
+
+ void pushExtendedPublicSystemOemLibs(ZipFile libApk) throws Exception {
+ var oem1Libs = new PublicLibs(libApk);
+ // Push libsystem_extpub<n>.oem1.so for each test. Since we cannot unload them, we need
+ // a fresh never-before-loaded library in each loadLibrary call.
+ for (int i = 1; i <= 3; ++i) {
+ oem1Libs.addLib("libsystem_testlib.so", "/system/${LIB}",
+ "libsystem_extpub" + i + ".oem1.so");
+ }
+ oem1Libs.addLib("libsystem_testlib.so", "/system/${LIB}", "libsystem_extpub.oem1.so");
+ oem1Libs.pushPublicLibrariesFile("/system/etc/public.libraries-oem1.txt");
+
+ var oem2Libs = new PublicLibs(libApk);
+ oem2Libs.addLib("libsystem_testlib.so", "/system/${LIB}", "libsystem_extpub.oem2.so");
+ // libextpub_nouses.oem2.so is a library that the test apps don't have
+ // <uses-native-library> dependencies for.
+ oem2Libs.addLib(
+ "libsystem_testlib.so", "/system/${LIB}", "libsystem_extpub_nouses.oem2.so");
+ oem2Libs.pushPublicLibrariesFile("/system/etc/public.libraries-oem2.txt");
+ }
+
+ void pushExtendedPublicProductLibs(ZipFile libApk) throws Exception {
+ var product1Libs = new PublicLibs(libApk);
+ // Push libproduct_extpub<n>.product1.so for each test. Since we cannot unload them, we
+ // need a fresh never-before-loaded library in each loadLibrary call.
+ for (int i = 1; i <= 3; ++i) {
+ product1Libs.addLib("libproduct_testlib.so", "/product/${LIB}",
+ "libproduct_extpub" + i + ".product1.so");
+ }
+ product1Libs.addLib(
+ "libproduct_testlib.so", "/product/${LIB}", "libproduct_extpub.product1.so");
+ product1Libs.pushPublicLibrariesFile("/product/etc/public.libraries-product1.txt");
+ }
+
+ void pushPrivateLibs(ZipFile libApk) throws Exception {
+ // Push the libraries once for each test. Since we cannot unload them, we need a fresh
+ // never-before-loaded library in each loadLibrary call.
+ for (int i = 1; i <= 6; ++i) {
+ pushNativeTestLib(libApk, "libsystem_testlib.so",
+ "/system/${LIB}/libsystem_private" + i + ".so");
+ pushNativeTestLib(libApk, "libsystem_testlib.so",
+ "/system_ext/${LIB}/libsystemext_private" + i + ".so");
+ pushNativeTestLib(libApk, "libproduct_testlib.so",
+ "/product/${LIB}/libproduct_private" + i + ".so");
+ pushNativeTestLib(libApk, "libvendor_testlib.so",
+ "/vendor/${LIB}/libvendor_private" + i + ".so");
+ }
+ }
+
+ void pushSharedLib(String partitionDir, String packageName, String buildJarName)
+ throws Exception {
+ String path = partitionDir + "/framework/" + packageName + ".jar";
+ pushFile(buildJarName, path);
+ // This permissions xml file is necessary to make it possible to depend on the shared
+ // library from the test app, even if it's in the same partition. It makes the library
+ // public to apps in other partitions as well, which is more than we need, but that
+ // being the case we test all shared libraries from all apps.
+ pushString("<permissions>\n"
+ + "<library name=\"" + packageName + "\" file=\"" + path + "\" />\n"
+ + "</permissions>\n",
+ partitionDir + "/etc/permissions/" + packageName + ".xml");
+ }
+
+ void softReboot() throws DeviceNotAvailableException {
+ assertCommandSucceeds("setprop dev.bootcomplete 0");
+ assertCommandSucceeds("stop");
+ assertCommandSucceeds("start");
+ mDevice.waitForDeviceAvailable();
+ }
+
+ String getTestArch() throws DeviceNotAvailableException {
+ if (mTestArch == null) {
+ IAbi abi = mContext.getConfigurationDescriptor().getAbi();
+ mTestArch = abi != null ? abi.getName()
+ : assertCommandSucceeds("getprop ro.product.cpu.abi");
+ }
+ return mTestArch;
+ }
+
+ String libDirName() throws DeviceNotAvailableException {
+ return getTestArch().contains("64") ? "lib64" : "lib";
+ }
+
+ // Pushes the given file contents to the device at the given destination path. destPath is
+ // assumed to have no risk of overlapping with existing files, and is deleted in tearDown(),
+ // along with any directory levels that had to be created.
+ void pushString(String fileContents, String destPath) throws DeviceNotAvailableException {
+ mCleanup.addPath(destPath);
+ assertThat(mDevice.pushString(fileContents, destPath)).isTrue();
+ }
+
+ // Like pushString, but pushes a data file included in the host test.
+ void pushFile(String fileName, String destPath) throws Exception {
+ mCleanup.addPath(destPath);
+ assertThat(mDevice.pushFile(mBuildHelper.getTestFile(fileName), destPath)).isTrue();
+ }
+
+ void pushApk(String apkBaseName, String destPath) throws Exception {
+ pushFile(apkBaseName + ".apk",
+ destPath + "/" + apkBaseName + "/" + apkBaseName + ".apk");
+ }
+
+ // Like pushString, but extracts libnativeloader_testlib.so from the library_container_app
+ // APK and pushes it to destPath. "${LIB}" is replaced with "lib" or "lib64" as appropriate.
+ void pushNativeTestLib(ZipFile libApk, String libName, String destPath) throws Exception {
+ String libApkPath = "lib/" + getTestArch() + "/" + libName;
+ ZipEntry entry = libApk.getEntry(libApkPath);
+ assertWithMessage("Failed to find " + libApkPath + " in library_container_app.apk")
+ .that(entry)
+ .isNotNull();
+
+ File libraryTempFile;
+ try (InputStream inStream = libApk.getInputStream(entry)) {
+ libraryTempFile = writeStreamToTempFile(libName, inStream);
+ }
+
+ destPath = destPath.replace("${LIB}", libDirName());
+
+ mCleanup.addPath(destPath);
+ assertThat(mDevice.pushFile(libraryTempFile, destPath)).isTrue();
+ }
+
+ void installPackage(String apkBaseName) throws Exception {
+ assertThat(mDevice.installPackage(mBuildHelper.getTestFile(apkBaseName + ".apk"),
+ false /* reinstall */))
+ .isNull();
+ }
+
+ String assertCommandSucceeds(String command) throws DeviceNotAvailableException {
+ CommandResult result = mDevice.executeShellV2Command(command);
+ assertWithMessage(result.toString()).that(result.getExitCode()).isEqualTo(0);
+ // Remove trailing \n's.
+ return result.getStdout().trim();
+ }
+ }
+
+ static private File writeStreamToTempFile(String tempFileBaseName, InputStream inStream)
+ throws Exception {
+ File hostTempFile = File.createTempFile(tempFileBaseName, null);
+ try (FileOutputStream outStream = new FileOutputStream(hostTempFile)) {
+ ByteStreams.copy(inStream, outStream);
+ }
+ return hostTempFile;
+ }
+}
diff --git a/libnativeloader/test/src/android/test/lib/TestUtils.java b/libnativeloader/test/src/android/test/lib/TestUtils.java
new file mode 100644
index 0000000000..1dd917f89f
--- /dev/null
+++ b/libnativeloader/test/src/android/test/lib/TestUtils.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2022 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.lib;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import org.junit.function.ThrowingRunnable;
+
+public final class TestUtils {
+ public static void assertLibraryNotFound(ThrowingRunnable loadLibrary) {
+ Throwable t = assertThrows(UnsatisfiedLinkError.class, loadLibrary);
+ assertThat(t.getMessage()).containsMatch("dlopen failed: library .* not found");
+ }
+
+ public static void assertLinkerNamespaceError(ThrowingRunnable loadLibrary) {
+ Throwable t = assertThrows(UnsatisfiedLinkError.class, loadLibrary);
+ assertThat(t.getMessage())
+ .containsMatch("dlopen failed: .* is not accessible for the namespace");
+ }
+
+ public static String libPath(String dir, String libName) {
+ String libDirName = InstrumentationRegistry.getArguments().getString("libDirName");
+ return dir + "/" + libDirName + "/lib" + libName + ".so";
+ }
+}
diff --git a/libnativeloader/test/test.cpp b/libnativeloader/test/src/android/test/productsharedlib/ProductSharedLib.java
index b166928f0e..a500d2a976 100644
--- a/libnativeloader/test/test.cpp
+++ b/libnativeloader/test/src/android/test/productsharedlib/ProductSharedLib.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2022 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.
@@ -13,9 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "oemlib"
-#include <android-base/logging.h>
-static __attribute__((constructor)) void test_lib_init() {
- LOG(DEBUG) << LIBNAME << " loaded";
+package android.test.productsharedlib;
+
+public final class ProductSharedLib {
+ public static void loadLibrary(String name) { System.loadLibrary(name); }
}
diff --git a/libnativeloader/test/vendor/AndroidManifest.xml b/libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java
index c4c1a9c210..1240e12e55 100644
--- a/libnativeloader/test/vendor/AndroidManifest.xml
+++ b/libnativeloader/test/src/android/test/systemextsharedlib/SystemExtSharedLib.java
@@ -1,6 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2018 The Android Open Source Project
+/*
+ * Copyright (C) 2022 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.
@@ -13,19 +12,10 @@
* 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.
- -->
+ */
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="android.test.app.vendor">
-
- <application>
- <activity android:name="android.test.app.TestActivity" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
-
-</manifest>
+package android.test.systemextsharedlib;
+public final class SystemExtSharedLib {
+ public static void loadLibrary(String name) { System.loadLibrary(name); }
+}
diff --git a/libnativeloader/test/src/android/test/systemsharedlib/SystemSharedLib.java b/libnativeloader/test/src/android/test/systemsharedlib/SystemSharedLib.java
new file mode 100644
index 0000000000..8e2af9f79c
--- /dev/null
+++ b/libnativeloader/test/src/android/test/systemsharedlib/SystemSharedLib.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2022 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.systemsharedlib;
+
+public final class SystemSharedLib {
+ public static void loadLibrary(String name) { System.loadLibrary(name); }
+}
diff --git a/libnativeloader/test/src/android/test/vendorsharedlib/VendorSharedLib.java b/libnativeloader/test/src/android/test/vendorsharedlib/VendorSharedLib.java
new file mode 100644
index 0000000000..8859b63db4
--- /dev/null
+++ b/libnativeloader/test/src/android/test/vendorsharedlib/VendorSharedLib.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2022 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.vendorsharedlib;
+
+public final class VendorSharedLib {
+ public static void loadLibrary(String name) { System.loadLibrary(name); }
+}