diff --git a/libnativebridge/.clang-format b/libnativebridge/.clang-format deleted file mode 120000 index fd0645fdf..000000000 --- a/libnativebridge/.clang-format +++ /dev/null @@ -1 +0,0 @@ -../.clang-format-2 \ No newline at end of file diff --git a/libnativebridge/Android.bp b/libnativebridge/Android.bp deleted file mode 100644 index c97845d16..000000000 --- a/libnativebridge/Android.bp +++ /dev/null @@ -1,65 +0,0 @@ -cc_defaults { - name: "libnativebridge-defaults", - cflags: [ - "-Werror", - "-Wall", - ], - cppflags: [ - "-fvisibility=protected", - ], - header_libs: ["libnativebridge-headers"], - export_header_lib_headers: ["libnativebridge-headers"], -} - -cc_library_headers { - name: "libnativebridge-headers", - - host_supported: true, - export_include_dirs: ["include"], -} - -cc_library { - name: "libnativebridge", - defaults: ["libnativebridge-defaults"], - // TODO(oth): remove after moving under art/ (b/137364733) - visibility: ["//visibility:public"], - - host_supported: true, - srcs: ["native_bridge.cc"], - header_libs: [ - "libbase_headers", - ], - shared_libs: [ - "liblog", - ], - // TODO(jiyong): remove this line after aosp/885921 lands - export_include_dirs: ["include"], - - target: { - android: { - version_script: "libnativebridge.map.txt", - }, - linux: { - version_script: "libnativebridge.map.txt", - }, - }, - - stubs: { - symbol_file: "libnativebridge.map.txt", - versions: ["1"], - }, -} - -// TODO(b/124250621): eliminate the need for this library -cc_library { - name: "libnativebridge_lazy", - defaults: ["libnativebridge-defaults"], - // TODO(oth): remove after moving under art/ (b/137364733) - visibility: ["//visibility:public"], - - host_supported: false, - srcs: ["native_bridge_lazy.cc"], - required: ["libnativebridge"], -} - -subdirs = ["tests"] diff --git a/libnativebridge/CPPLINT.cfg b/libnativebridge/CPPLINT.cfg deleted file mode 100644 index 578047ba1..000000000 --- a/libnativebridge/CPPLINT.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -filter=-build/header_guard -filter=-whitespace/comments -filter=-whitespace/parens diff --git a/libnativebridge/OWNERS b/libnativebridge/OWNERS deleted file mode 100644 index daf87f47b..000000000 --- a/libnativebridge/OWNERS +++ /dev/null @@ -1,4 +0,0 @@ -dimitry@google.com -eaeltsin@google.com -ngeoffray@google.com -oth@google.com diff --git a/libnativebridge/include/nativebridge/native_bridge.h b/libnativebridge/include/nativebridge/native_bridge.h deleted file mode 100644 index e9c950025..000000000 --- a/libnativebridge/include/nativebridge/native_bridge.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * 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. - */ - -#ifndef NATIVE_BRIDGE_H_ -#define NATIVE_BRIDGE_H_ - -#include -#include -#include -#include - -#include "jni.h" - -#ifdef __cplusplus -namespace android { -extern "C" { -#endif // __cplusplus - -struct NativeBridgeRuntimeCallbacks; -struct NativeBridgeRuntimeValues; - -// Function pointer type for sigaction. This is mostly the signature of a signal handler, except -// for the return type. The runtime needs to know whether the signal was handled or should be given -// to the chain. -typedef bool (*NativeBridgeSignalHandlerFn)(int, siginfo_t*, void*); - -// Open the native bridge, if any. Should be called by Runtime::Init(). A null library filename -// signals that we do not want to load a native bridge. -bool LoadNativeBridge(const char* native_bridge_library_filename, - const struct NativeBridgeRuntimeCallbacks* runtime_callbacks); - -// Quick check whether a native bridge will be needed. This is based off of the instruction set -// of the process. -bool NeedsNativeBridge(const char* instruction_set); - -// Do the early initialization part of the native bridge, if necessary. This should be done under -// high privileges. -bool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set); - -// Initialize the native bridge, if any. Should be called by Runtime::DidForkFromZygote. The JNIEnv* -// will be used to modify the app environment for the bridge. -bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set); - -// Unload the native bridge, if any. Should be called by Runtime::DidForkFromZygote. -void UnloadNativeBridge(); - -// Check whether a native bridge is available (opened or initialized). Requires a prior call to -// LoadNativeBridge. -bool NativeBridgeAvailable(); - -// Check whether a native bridge is available (initialized). Requires a prior call to -// LoadNativeBridge & InitializeNativeBridge. -bool NativeBridgeInitialized(); - -// Load a shared library that is supported by the native bridge. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Use NativeBridgeLoadLibraryExt() instead in namespace scenario. -void* NativeBridgeLoadLibrary(const char* libpath, int flag); - -// Get a native bridge trampoline for specified native method. -void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len); - -// True if native library paths are valid and is for an ABI that is supported by native bridge. -// The *libpath* must point to a library. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Use NativeBridgeIsPathSupported() instead in namespace scenario. -bool NativeBridgeIsSupported(const char* libpath); - -// Returns the version number of the native bridge. This information is available after a -// successful LoadNativeBridge() and before closing it, that is, as long as NativeBridgeAvailable() -// returns true. Returns 0 otherwise. -uint32_t NativeBridgeGetVersion(); - -// Returns a signal handler that the bridge would like to be managed. Only valid for a native -// bridge supporting the version 2 interface. Will return null if the bridge does not support -// version 2, or if it doesn't have a signal handler it wants to be known. -NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal); - -// Returns whether we have seen a native bridge error. This could happen because the library -// was not found, rejected, could not be initialized and so on. -// -// This functionality is mainly for testing. -bool NativeBridgeError(); - -// Returns whether a given string is acceptable as a native bridge library filename. -// -// This functionality is exposed mainly for testing. -bool NativeBridgeNameAcceptable(const char* native_bridge_library_filename); - -// Decrements the reference count on the dynamic library handler. If the reference count drops -// to zero then the dynamic library is unloaded. Returns 0 on success and non-zero on error. -int NativeBridgeUnloadLibrary(void* handle); - -// Get last error message of native bridge when fail to load library or search symbol. -// This is reflection of dlerror() for native bridge. -const char* NativeBridgeGetError(); - -struct native_bridge_namespace_t; - -// True if native library paths are valid and is for an ABI that is supported by native bridge. -// Different from NativeBridgeIsSupported(), the *path* here must be a directory containing -// libraries of an ABI. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Use NativeBridgeIsSupported() instead in non-namespace scenario. -bool NativeBridgeIsPathSupported(const char* path); - -// Initializes anonymous namespace. -// NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker. -// -// The anonymous namespace is used in the case when a NativeBridge implementation -// cannot identify the caller of dlopen/dlsym which happens for the code not loaded -// by dynamic linker; for example calls from the mono-compiled code. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Should not use in non-namespace scenario. -bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, - const char* anon_ns_library_path); - -// Create new namespace in which native libraries will be loaded. -// NativeBridge's peer of android_create_namespace() of dynamic linker. -// -// The libraries in the namespace are searched by folowing order: -// 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH) -// 2. In directories specified by DT_RUNPATH of the "needed by" binary. -// 3. deault_library_path (This of this as namespace-local default library path) -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Should not use in non-namespace scenario. -struct native_bridge_namespace_t* NativeBridgeCreateNamespace( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent_ns); - -// Creates a link which shares some libraries from one namespace to another. -// NativeBridge's peer of android_link_namespaces() of dynamic linker. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Should not use in non-namespace scenario. -bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from, - struct native_bridge_namespace_t* to, - const char* shared_libs_sonames); - -// Load a shared library with namespace key that is supported by the native bridge. -// NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace -// extension. -// -// Starting with v3, NativeBridge has two scenarios: with/without namespace. -// Use NativeBridgeLoadLibrary() instead in non-namespace scenario. -void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, - struct native_bridge_namespace_t* ns); - -// Returns exported namespace by the name. This is a reflection of -// android_get_exported_namespace function. Introduced in v5. -struct native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name); - -// Native bridge interfaces to runtime. -struct NativeBridgeCallbacks { - // Version number of the interface. - uint32_t version; - - // Initialize native bridge. Native bridge's internal implementation must ensure MT safety and - // that the native bridge is initialized only once. Thus it is OK to call this interface for an - // already initialized native bridge. - // - // Parameters: - // runtime_cbs [IN] the pointer to NativeBridgeRuntimeCallbacks. - // Returns: - // true if initialization was successful. - bool (*initialize)(const struct NativeBridgeRuntimeCallbacks* runtime_cbs, - const char* private_dir, const char* instruction_set); - - // Load a shared library that is supported by the native bridge. - // - // Parameters: - // libpath [IN] path to the shared library - // flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h - // Returns: - // The opaque handle of the shared library if sucessful, otherwise NULL - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Use loadLibraryExt instead in namespace scenario. - void* (*loadLibrary)(const char* libpath, int flag); - - // Get a native bridge trampoline for specified native method. The trampoline has same - // sigature as the native method. - // - // Parameters: - // handle [IN] the handle returned from loadLibrary - // shorty [IN] short descriptor of native method - // len [IN] length of shorty - // Returns: - // address of trampoline if successful, otherwise NULL - void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len); - - // Check whether native library is valid and is for an ABI that is supported by native bridge. - // - // Parameters: - // libpath [IN] path to the shared library - // Returns: - // TRUE if library is supported by native bridge, FALSE otherwise - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Use isPathSupported instead in namespace scenario. - bool (*isSupported)(const char* libpath); - - // Provide environment values required by the app running with native bridge according to the - // instruction set. - // - // Parameters: - // instruction_set [IN] the instruction set of the app - // Returns: - // NULL if not supported by native bridge. - // Otherwise, return all environment values to be set after fork. - const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set); - - // Added callbacks in version 2. - - // Check whether the bridge is compatible with the given version. A bridge may decide not to be - // forwards- or backwards-compatible, and libnativebridge will then stop using it. - // - // Parameters: - // bridge_version [IN] the version of libnativebridge. - // Returns: - // true if the native bridge supports the given version of libnativebridge. - bool (*isCompatibleWith)(uint32_t bridge_version); - - // A callback to retrieve a native bridge's signal handler for the specified signal. The runtime - // will ensure that the signal handler is being called after the runtime's own handler, but before - // all chained handlers. The native bridge should not try to install the handler by itself, as - // that will potentially lead to cycles. - // - // Parameters: - // signal [IN] the signal for which the handler is asked for. Currently, only SIGSEGV is - // supported by the runtime. - // Returns: - // NULL if the native bridge doesn't use a handler or doesn't want it to be managed by the - // runtime. - // Otherwise, a pointer to the signal handler. - NativeBridgeSignalHandlerFn (*getSignalHandler)(int signal); - - // Added callbacks in version 3. - - // Decrements the reference count on the dynamic library handler. If the reference count drops - // to zero then the dynamic library is unloaded. - // - // Parameters: - // handle [IN] the handler of a dynamic library. - // - // Returns: - // 0 on success, and nonzero on error. - int (*unloadLibrary)(void* handle); - - // Dump the last failure message of native bridge when fail to load library or search symbol. - // - // Parameters: - // - // Returns: - // A string describing the most recent error that occurred when load library - // or lookup symbol via native bridge. - const char* (*getError)(); - - // Check whether library paths are supported by native bridge. - // - // Parameters: - // library_path [IN] search paths for native libraries (directories separated by ':') - // Returns: - // TRUE if libraries within search paths are supported by native bridge, FALSE otherwise - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Use isSupported instead in non-namespace scenario. - bool (*isPathSupported)(const char* library_path); - - // Initializes anonymous namespace at native bridge side. - // NativeBridge's peer of android_init_anonymous_namespace() of dynamic linker. - // - // The anonymous namespace is used in the case when a NativeBridge implementation - // cannot identify the caller of dlopen/dlsym which happens for the code not loaded - // by dynamic linker; for example calls from the mono-compiled code. - // - // Parameters: - // public_ns_sonames [IN] the name of "public" libraries. - // anon_ns_library_path [IN] the library search path of (anonymous) namespace. - // Returns: - // true if the pass is ok. - // Otherwise, false. - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Should not use in non-namespace scenario. - bool (*initAnonymousNamespace)(const char* public_ns_sonames, const char* anon_ns_library_path); - - // Create new namespace in which native libraries will be loaded. - // NativeBridge's peer of android_create_namespace() of dynamic linker. - // - // Parameters: - // name [IN] the name of the namespace. - // ld_library_path [IN] the first set of library search paths of the namespace. - // default_library_path [IN] the second set of library search path of the namespace. - // type [IN] the attribute of the namespace. - // permitted_when_isolated_path [IN] the permitted path for isolated namespace(if it is). - // parent_ns [IN] the pointer of the parent namespace to be inherited from. - // Returns: - // native_bridge_namespace_t* for created namespace or nullptr in the case of error. - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Should not use in non-namespace scenario. - struct native_bridge_namespace_t* (*createNamespace)(const char* name, - const char* ld_library_path, - const char* default_library_path, - uint64_t type, - const char* permitted_when_isolated_path, - struct native_bridge_namespace_t* parent_ns); - - // Creates a link which shares some libraries from one namespace to another. - // NativeBridge's peer of android_link_namespaces() of dynamic linker. - // - // Parameters: - // from [IN] the namespace where libraries are accessed. - // to [IN] the namespace where libraries are loaded. - // shared_libs_sonames [IN] the libraries to be shared. - // - // Returns: - // Whether successed or not. - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Should not use in non-namespace scenario. - bool (*linkNamespaces)(struct native_bridge_namespace_t* from, - struct native_bridge_namespace_t* to, const char* shared_libs_sonames); - - // Load a shared library within a namespace. - // NativeBridge's peer of android_dlopen_ext() of dynamic linker, only supports namespace - // extension. - // - // Parameters: - // libpath [IN] path to the shared library - // flag [IN] the stardard RTLD_XXX defined in bionic dlfcn.h - // ns [IN] the pointer of the namespace in which the library should be loaded. - // Returns: - // The opaque handle of the shared library if sucessful, otherwise NULL - // - // Starting with v3, NativeBridge has two scenarios: with/without namespace. - // Use loadLibrary instead in non-namespace scenario. - void* (*loadLibraryExt)(const char* libpath, int flag, struct native_bridge_namespace_t* ns); - - // Get native bridge version of vendor namespace. - // The vendor namespace is the namespace used to load vendor public libraries. - // With O release this namespace can be different from the default namespace. - // For the devices without enable vendor namespaces this function should return null - // - // Returns: - // vendor namespace or null if it was not set up for the device - // - // Starting with v5 (Android Q) this function is no longer used. - // Use getExportedNamespace() below. - struct native_bridge_namespace_t* (*getVendorNamespace)(); - - // Get native bridge version of exported namespace. Peer of - // android_get_exported_namespace(const char*) function. - // - // Returns: - // exported namespace or null if it was not set up for the device - struct native_bridge_namespace_t* (*getExportedNamespace)(const char* name); -}; - -// Runtime interfaces to native bridge. -struct NativeBridgeRuntimeCallbacks { - // Get shorty of a Java method. The shorty is supposed to be persistent in memory. - // - // Parameters: - // env [IN] pointer to JNIenv. - // mid [IN] Java methodID. - // Returns: - // short descriptor for method. - const char* (*getMethodShorty)(JNIEnv* env, jmethodID mid); - - // Get number of native methods for specified class. - // - // Parameters: - // env [IN] pointer to JNIenv. - // clazz [IN] Java class object. - // Returns: - // number of native methods. - uint32_t (*getNativeMethodCount)(JNIEnv* env, jclass clazz); - - // Get at most 'method_count' native methods for specified class 'clazz'. Results are outputed - // via 'methods' [OUT]. The signature pointer in JNINativeMethod is reused as the method shorty. - // - // Parameters: - // env [IN] pointer to JNIenv. - // clazz [IN] Java class object. - // methods [OUT] array of method with the name, shorty, and fnPtr. - // method_count [IN] max number of elements in methods. - // Returns: - // number of method it actually wrote to methods. - uint32_t (*getNativeMethods)(JNIEnv* env, jclass clazz, JNINativeMethod* methods, - uint32_t method_count); -}; - -#ifdef __cplusplus -} // extern "C" -} // namespace android -#endif // __cplusplus - -#endif // NATIVE_BRIDGE_H_ diff --git a/libnativebridge/libnativebridge.map.txt b/libnativebridge/libnativebridge.map.txt deleted file mode 100644 index a6841a3a8..000000000 --- a/libnativebridge/libnativebridge.map.txt +++ /dev/null @@ -1,45 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# TODO(b/122710865): Most of these uses come from libnativeloader, which should be bundled -# together with libnativebridge in the APEX. Once this happens, prune this list. -LIBNATIVEBRIDGE_1 { - global: - NativeBridgeIsSupported; - NativeBridgeLoadLibrary; - NativeBridgeUnloadLibrary; - NativeBridgeGetError; - NativeBridgeIsPathSupported; - NativeBridgeCreateNamespace; - NativeBridgeGetExportedNamespace; - NativeBridgeLinkNamespaces; - NativeBridgeLoadLibraryExt; - NativeBridgeInitAnonymousNamespace; - NativeBridgeInitialized; - NativeBridgeGetTrampoline; - LoadNativeBridge; - PreInitializeNativeBridge; - InitializeNativeBridge; - NativeBridgeGetVersion; - NativeBridgeGetSignalHandler; - UnloadNativeBridge; - NativeBridgeAvailable; - NeedsNativeBridge; - NativeBridgeError; - NativeBridgeNameAcceptable; - local: - *; -}; diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc deleted file mode 100644 index 9adba9a50..000000000 --- a/libnativebridge/native_bridge.cc +++ /dev/null @@ -1,646 +0,0 @@ -/* - * 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. - */ - -#define LOG_TAG "nativebridge" - -#include "nativebridge/native_bridge.h" - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -namespace android { - -#ifdef __APPLE__ -template -void UNUSED(const T&) {} -#endif - -extern "C" { - -// Environment values required by the apps running with native bridge. -struct NativeBridgeRuntimeValues { - const char* os_arch; - const char* cpu_abi; - const char* cpu_abi2; - const char* *supported_abis; - int32_t abi_count; -}; - -// The symbol name exposed by native-bridge with the type of NativeBridgeCallbacks. -static constexpr const char* kNativeBridgeInterfaceSymbol = "NativeBridgeItf"; - -enum class NativeBridgeState { - kNotSetup, // Initial state. - kOpened, // After successful dlopen. - kPreInitialized, // After successful pre-initialization. - kInitialized, // After successful initialization. - kClosed // Closed or errors. -}; - -static constexpr const char* kNotSetupString = "kNotSetup"; -static constexpr const char* kOpenedString = "kOpened"; -static constexpr const char* kPreInitializedString = "kPreInitialized"; -static constexpr const char* kInitializedString = "kInitialized"; -static constexpr const char* kClosedString = "kClosed"; - -static const char* GetNativeBridgeStateString(NativeBridgeState state) { - switch (state) { - case NativeBridgeState::kNotSetup: - return kNotSetupString; - - case NativeBridgeState::kOpened: - return kOpenedString; - - case NativeBridgeState::kPreInitialized: - return kPreInitializedString; - - case NativeBridgeState::kInitialized: - return kInitializedString; - - case NativeBridgeState::kClosed: - return kClosedString; - } -} - -// Current state of the native bridge. -static NativeBridgeState state = NativeBridgeState::kNotSetup; - -// The version of NativeBridge implementation. -// Different Nativebridge interface needs the service of different version of -// Nativebridge implementation. -// Used by isCompatibleWith() which is introduced in v2. -enum NativeBridgeImplementationVersion { - // first version, not used. - DEFAULT_VERSION = 1, - // The version which signal semantic is introduced. - SIGNAL_VERSION = 2, - // The version which namespace semantic is introduced. - NAMESPACE_VERSION = 3, - // The version with vendor namespaces - VENDOR_NAMESPACE_VERSION = 4, - // The version with runtime namespaces - RUNTIME_NAMESPACE_VERSION = 5, -}; - -// Whether we had an error at some point. -static bool had_error = false; - -// Handle of the loaded library. -static void* native_bridge_handle = nullptr; -// Pointer to the callbacks. Available as soon as LoadNativeBridge succeeds, but only initialized -// later. -static const NativeBridgeCallbacks* callbacks = nullptr; -// Callbacks provided by the environment to the bridge. Passed to LoadNativeBridge. -static const NativeBridgeRuntimeCallbacks* runtime_callbacks = nullptr; - -// The app's code cache directory. -static char* app_code_cache_dir = nullptr; - -// Code cache directory (relative to the application private directory) -// Ideally we'd like to call into framework to retrieve this name. However that's considered an -// implementation detail and will require either hacks or consistent refactorings. We compromise -// and hard code the directory name again here. -static constexpr const char* kCodeCacheDir = "code_cache"; - -// Characters allowed in a native bridge filename. The first character must -// be in [a-zA-Z] (expected 'l' for "libx"). The rest must be in [a-zA-Z0-9._-]. -static bool CharacterAllowed(char c, bool first) { - if (first) { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); - } else { - return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || - (c == '.') || (c == '_') || (c == '-'); - } -} - -static void ReleaseAppCodeCacheDir() { - if (app_code_cache_dir != nullptr) { - delete[] app_code_cache_dir; - app_code_cache_dir = nullptr; - } -} - -// We only allow simple names for the library. It is supposed to be a file in -// /system/lib or /vendor/lib. Only allow a small range of characters, that is -// names consisting of [a-zA-Z0-9._-] and starting with [a-zA-Z]. -bool NativeBridgeNameAcceptable(const char* nb_library_filename) { - const char* ptr = nb_library_filename; - if (*ptr == 0) { - // Emptry string. Allowed, means no native bridge. - return true; - } else { - // First character must be [a-zA-Z]. - if (!CharacterAllowed(*ptr, true)) { - // Found an invalid fist character, don't accept. - ALOGE("Native bridge library %s has been rejected for first character %c", - nb_library_filename, - *ptr); - return false; - } else { - // For the rest, be more liberal. - ptr++; - while (*ptr != 0) { - if (!CharacterAllowed(*ptr, false)) { - // Found an invalid character, don't accept. - ALOGE("Native bridge library %s has been rejected for %c", nb_library_filename, *ptr); - return false; - } - ptr++; - } - } - return true; - } -} - -// The policy of invoking Nativebridge changed in v3 with/without namespace. -// Suggest Nativebridge implementation not maintain backward-compatible. -static bool isCompatibleWith(const uint32_t version) { - // Libnativebridge is now designed to be forward-compatible. So only "0" is an unsupported - // version. - if (callbacks == nullptr || callbacks->version == 0 || version == 0) { - return false; - } - - // If this is a v2+ bridge, it may not be forwards- or backwards-compatible. Check. - if (callbacks->version >= SIGNAL_VERSION) { - return callbacks->isCompatibleWith(version); - } - - return true; -} - -static void CloseNativeBridge(bool with_error) { - state = NativeBridgeState::kClosed; - had_error |= with_error; - ReleaseAppCodeCacheDir(); -} - -bool LoadNativeBridge(const char* nb_library_filename, - const NativeBridgeRuntimeCallbacks* runtime_cbs) { - // We expect only one place that calls LoadNativeBridge: Runtime::Init. At that point we are not - // multi-threaded, so we do not need locking here. - - if (state != NativeBridgeState::kNotSetup) { - // Setup has been called before. Ignore this call. - if (nb_library_filename != nullptr) { // Avoids some log-spam for dalvikvm. - ALOGW("Called LoadNativeBridge for an already set up native bridge. State is %s.", - GetNativeBridgeStateString(state)); - } - // Note: counts as an error, even though the bridge may be functional. - had_error = true; - return false; - } - - if (nb_library_filename == nullptr || *nb_library_filename == 0) { - CloseNativeBridge(false); - return false; - } else { - if (!NativeBridgeNameAcceptable(nb_library_filename)) { - CloseNativeBridge(true); - } else { - // Try to open the library. - void* handle = dlopen(nb_library_filename, RTLD_LAZY); - if (handle != nullptr) { - callbacks = reinterpret_cast(dlsym(handle, - kNativeBridgeInterfaceSymbol)); - if (callbacks != nullptr) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - // Store the handle for later. - native_bridge_handle = handle; - } else { - callbacks = nullptr; - dlclose(handle); - ALOGW("Unsupported native bridge interface."); - } - } else { - dlclose(handle); - } - } - - // Two failure conditions: could not find library (dlopen failed), or could not find native - // bridge interface (dlsym failed). Both are an error and close the native bridge. - if (callbacks == nullptr) { - CloseNativeBridge(true); - } else { - runtime_callbacks = runtime_cbs; - state = NativeBridgeState::kOpened; - } - } - return state == NativeBridgeState::kOpened; - } -} - -bool NeedsNativeBridge(const char* instruction_set) { - if (instruction_set == nullptr) { - ALOGE("Null instruction set in NeedsNativeBridge."); - return false; - } - return strncmp(instruction_set, ABI_STRING, strlen(ABI_STRING) + 1) != 0; -} - -bool PreInitializeNativeBridge(const char* app_data_dir_in, const char* instruction_set) { - if (state != NativeBridgeState::kOpened) { - ALOGE("Invalid state: native bridge is expected to be opened."); - CloseNativeBridge(true); - return false; - } - - if (app_data_dir_in == nullptr) { - ALOGE("Application private directory cannot be null."); - CloseNativeBridge(true); - return false; - } - - // Create the path to the application code cache directory. - // The memory will be release after Initialization or when the native bridge is closed. - const size_t len = strlen(app_data_dir_in) + strlen(kCodeCacheDir) + 2; // '\0' + '/' - app_code_cache_dir = new char[len]; - snprintf(app_code_cache_dir, len, "%s/%s", app_data_dir_in, kCodeCacheDir); - - // Bind-mount /system/lib{,64}//cpuinfo to /proc/cpuinfo. - // Failure is not fatal and will keep the native bridge in kPreInitialized. - state = NativeBridgeState::kPreInitialized; - -#ifndef __APPLE__ - if (instruction_set == nullptr) { - return true; - } - size_t isa_len = strlen(instruction_set); - if (isa_len > 10) { - // 10 is a loose upper bound on the currently known instruction sets (a tight bound is 7 for - // x86_64 [including the trailing \0]). This is so we don't have to change here if there will - // be another instruction set in the future. - ALOGW("Instruction set %s is malformed, must be less than or equal to 10 characters.", - instruction_set); - return true; - } - - // If the file does not exist, the mount command will fail, - // so we save the extra file existence check. - char cpuinfo_path[1024]; - -#if defined(__ANDROID__) - snprintf(cpuinfo_path, sizeof(cpuinfo_path), "/system/lib" -#ifdef __LP64__ - "64" -#endif // __LP64__ - "/%s/cpuinfo", instruction_set); -#else // !__ANDROID__ - // To be able to test on the host, we hardwire a relative path. - snprintf(cpuinfo_path, sizeof(cpuinfo_path), "./cpuinfo"); -#endif - - // Bind-mount. - if (TEMP_FAILURE_RETRY(mount(cpuinfo_path, // Source. - "/proc/cpuinfo", // Target. - nullptr, // FS type. - MS_BIND, // Mount flags: bind mount. - nullptr)) == -1) { // "Data." - ALOGW("Failed to bind-mount %s as /proc/cpuinfo: %s", cpuinfo_path, strerror(errno)); - } -#else // __APPLE__ - UNUSED(instruction_set); - ALOGW("Mac OS does not support bind-mounting. Host simulation of native bridge impossible."); -#endif - - return true; -} - -static void SetCpuAbi(JNIEnv* env, jclass build_class, const char* field, const char* value) { - if (value != nullptr) { - jfieldID field_id = env->GetStaticFieldID(build_class, field, "Ljava/lang/String;"); - if (field_id == nullptr) { - env->ExceptionClear(); - ALOGW("Could not find %s field.", field); - return; - } - - jstring str = env->NewStringUTF(value); - if (str == nullptr) { - env->ExceptionClear(); - ALOGW("Could not create string %s.", value); - return; - } - - env->SetStaticObjectField(build_class, field_id, str); - } -} - -// Set up the environment for the bridged app. -static void SetupEnvironment(const NativeBridgeCallbacks* callbacks, JNIEnv* env, const char* isa) { - // Need a JNIEnv* to do anything. - if (env == nullptr) { - ALOGW("No JNIEnv* to set up app environment."); - return; - } - - // Query the bridge for environment values. - const struct NativeBridgeRuntimeValues* env_values = callbacks->getAppEnv(isa); - if (env_values == nullptr) { - return; - } - - // Keep the JNIEnv clean. - jint success = env->PushLocalFrame(16); // That should be small and large enough. - if (success < 0) { - // Out of memory, really borked. - ALOGW("Out of memory while setting up app environment."); - env->ExceptionClear(); - return; - } - - // Reset CPU_ABI & CPU_ABI2 to values required by the apps running with native bridge. - if (env_values->cpu_abi != nullptr || env_values->cpu_abi2 != nullptr || - env_values->abi_count >= 0) { - jclass bclass_id = env->FindClass("android/os/Build"); - if (bclass_id != nullptr) { - SetCpuAbi(env, bclass_id, "CPU_ABI", env_values->cpu_abi); - SetCpuAbi(env, bclass_id, "CPU_ABI2", env_values->cpu_abi2); - } else { - // For example in a host test environment. - env->ExceptionClear(); - ALOGW("Could not find Build class."); - } - } - - if (env_values->os_arch != nullptr) { - jclass sclass_id = env->FindClass("java/lang/System"); - if (sclass_id != nullptr) { - jmethodID set_prop_id = env->GetStaticMethodID(sclass_id, "setUnchangeableSystemProperty", - "(Ljava/lang/String;Ljava/lang/String;)V"); - if (set_prop_id != nullptr) { - // Init os.arch to the value reqired by the apps running with native bridge. - env->CallStaticVoidMethod(sclass_id, set_prop_id, env->NewStringUTF("os.arch"), - env->NewStringUTF(env_values->os_arch)); - } else { - env->ExceptionClear(); - ALOGW("Could not find System#setUnchangeableSystemProperty."); - } - } else { - env->ExceptionClear(); - ALOGW("Could not find System class."); - } - } - - // Make it pristine again. - env->PopLocalFrame(nullptr); -} - -bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set) { - // We expect only one place that calls InitializeNativeBridge: Runtime::DidForkFromZygote. At that - // point we are not multi-threaded, so we do not need locking here. - - if (state == NativeBridgeState::kPreInitialized) { - // Check for code cache: if it doesn't exist try to create it. - struct stat st; - if (stat(app_code_cache_dir, &st) == -1) { - if (errno == ENOENT) { - if (mkdir(app_code_cache_dir, S_IRWXU | S_IRWXG | S_IXOTH) == -1) { - ALOGW("Cannot create code cache directory %s: %s.", app_code_cache_dir, strerror(errno)); - ReleaseAppCodeCacheDir(); - } - } else { - ALOGW("Cannot stat code cache directory %s: %s.", app_code_cache_dir, strerror(errno)); - ReleaseAppCodeCacheDir(); - } - } else if (!S_ISDIR(st.st_mode)) { - ALOGW("Code cache is not a directory %s.", app_code_cache_dir); - ReleaseAppCodeCacheDir(); - } - - // If we're still PreInitialized (dind't fail the code cache checks) try to initialize. - if (state == NativeBridgeState::kPreInitialized) { - if (callbacks->initialize(runtime_callbacks, app_code_cache_dir, instruction_set)) { - SetupEnvironment(callbacks, env, instruction_set); - state = NativeBridgeState::kInitialized; - // We no longer need the code cache path, release the memory. - ReleaseAppCodeCacheDir(); - } else { - // Unload the library. - dlclose(native_bridge_handle); - CloseNativeBridge(true); - } - } - } else { - CloseNativeBridge(true); - } - - return state == NativeBridgeState::kInitialized; -} - -void UnloadNativeBridge() { - // We expect only one place that calls UnloadNativeBridge: Runtime::DidForkFromZygote. At that - // point we are not multi-threaded, so we do not need locking here. - - switch(state) { - case NativeBridgeState::kOpened: - case NativeBridgeState::kPreInitialized: - case NativeBridgeState::kInitialized: - // Unload. - dlclose(native_bridge_handle); - CloseNativeBridge(false); - break; - - case NativeBridgeState::kNotSetup: - // Not even set up. Error. - CloseNativeBridge(true); - break; - - case NativeBridgeState::kClosed: - // Ignore. - break; - } -} - -bool NativeBridgeError() { - return had_error; -} - -bool NativeBridgeAvailable() { - return state == NativeBridgeState::kOpened - || state == NativeBridgeState::kPreInitialized - || state == NativeBridgeState::kInitialized; -} - -bool NativeBridgeInitialized() { - // Calls of this are supposed to happen in a state where the native bridge is stable, i.e., after - // Runtime::DidForkFromZygote. In that case we do not need a lock. - return state == NativeBridgeState::kInitialized; -} - -void* NativeBridgeLoadLibrary(const char* libpath, int flag) { - if (NativeBridgeInitialized()) { - return callbacks->loadLibrary(libpath, flag); - } - return nullptr; -} - -void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, - uint32_t len) { - if (NativeBridgeInitialized()) { - return callbacks->getTrampoline(handle, name, shorty, len); - } - return nullptr; -} - -bool NativeBridgeIsSupported(const char* libpath) { - if (NativeBridgeInitialized()) { - return callbacks->isSupported(libpath); - } - return false; -} - -uint32_t NativeBridgeGetVersion() { - if (NativeBridgeAvailable()) { - return callbacks->version; - } - return 0; -} - -NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(SIGNAL_VERSION)) { - return callbacks->getSignalHandler(signal); - } else { - ALOGE("not compatible with version %d, cannot get signal handler", SIGNAL_VERSION); - } - } - return nullptr; -} - -int NativeBridgeUnloadLibrary(void* handle) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->unloadLibrary(handle); - } else { - ALOGE("not compatible with version %d, cannot unload library", NAMESPACE_VERSION); - } - } - return -1; -} - -const char* NativeBridgeGetError() { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->getError(); - } else { - return "native bridge implementation is not compatible with version 3, cannot get message"; - } - } - return "native bridge is not initialized"; -} - -bool NativeBridgeIsPathSupported(const char* path) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->isPathSupported(path); - } else { - ALOGE("not compatible with version %d, cannot check via library path", NAMESPACE_VERSION); - } - } - return false; -} - -bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, - const char* anon_ns_library_path) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->initAnonymousNamespace(public_ns_sonames, anon_ns_library_path); - } else { - ALOGE("not compatible with version %d, cannot init namespace", NAMESPACE_VERSION); - } - } - - return false; -} - -native_bridge_namespace_t* NativeBridgeCreateNamespace(const char* name, - const char* ld_library_path, - const char* default_library_path, - uint64_t type, - const char* permitted_when_isolated_path, - native_bridge_namespace_t* parent_ns) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->createNamespace(name, - ld_library_path, - default_library_path, - type, - permitted_when_isolated_path, - parent_ns); - } else { - ALOGE("not compatible with version %d, cannot create namespace %s", NAMESPACE_VERSION, name); - } - } - - return nullptr; -} - -bool NativeBridgeLinkNamespaces(native_bridge_namespace_t* from, native_bridge_namespace_t* to, - const char* shared_libs_sonames) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->linkNamespaces(from, to, shared_libs_sonames); - } else { - ALOGE("not compatible with version %d, cannot init namespace", NAMESPACE_VERSION); - } - } - - return false; -} - -native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name) { - if (!NativeBridgeInitialized()) { - return nullptr; - } - - if (isCompatibleWith(RUNTIME_NAMESPACE_VERSION)) { - return callbacks->getExportedNamespace(name); - } - - // sphal is vendor namespace name -> use v4 callback in the case NB callbacks - // are not compatible with v5 - if (isCompatibleWith(VENDOR_NAMESPACE_VERSION) && name != nullptr && strcmp("sphal", name) == 0) { - return callbacks->getVendorNamespace(); - } - - return nullptr; -} - -void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, native_bridge_namespace_t* ns) { - if (NativeBridgeInitialized()) { - if (isCompatibleWith(NAMESPACE_VERSION)) { - return callbacks->loadLibraryExt(libpath, flag, ns); - } else { - ALOGE("not compatible with version %d, cannot load library in namespace", NAMESPACE_VERSION); - } - } - return nullptr; -} - -} // extern "C" - -} // namespace android diff --git a/libnativebridge/native_bridge_lazy.cc b/libnativebridge/native_bridge_lazy.cc deleted file mode 100644 index 94c80848e..000000000 --- a/libnativebridge/native_bridge_lazy.cc +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "nativebridge/native_bridge.h" -#define LOG_TAG "nativebridge" - -#include -#include -#include - -#include - -namespace android { - -namespace { - -void* GetLibHandle() { - static void* handle = dlopen("libnativebridge.so", RTLD_NOW); - LOG_FATAL_IF(handle == nullptr, "Failed to load libnativebridge.so: %s", dlerror()); - return handle; -} - -template -FuncPtr GetFuncPtr(const char* function_name) { - auto f = reinterpret_cast(dlsym(GetLibHandle(), function_name)); - LOG_FATAL_IF(f == nullptr, "Failed to get address of %s: %s", function_name, dlerror()); - return f; -} - -#define GET_FUNC_PTR(name) GetFuncPtr(#name) - -} // namespace - -bool LoadNativeBridge(const char* native_bridge_library_filename, - const struct NativeBridgeRuntimeCallbacks* runtime_callbacks) { - static auto f = GET_FUNC_PTR(LoadNativeBridge); - return f(native_bridge_library_filename, runtime_callbacks); -} - -bool NeedsNativeBridge(const char* instruction_set) { - static auto f = GET_FUNC_PTR(NeedsNativeBridge); - return f(instruction_set); -} - -bool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set) { - static auto f = GET_FUNC_PTR(PreInitializeNativeBridge); - return f(app_data_dir, instruction_set); -} - -bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set) { - static auto f = GET_FUNC_PTR(InitializeNativeBridge); - return f(env, instruction_set); -} - -void UnloadNativeBridge() { - static auto f = GET_FUNC_PTR(UnloadNativeBridge); - return f(); -} - -bool NativeBridgeAvailable() { - static auto f = GET_FUNC_PTR(NativeBridgeAvailable); - return f(); -} - -bool NativeBridgeInitialized() { - static auto f = GET_FUNC_PTR(NativeBridgeInitialized); - return f(); -} - -void* NativeBridgeLoadLibrary(const char* libpath, int flag) { - static auto f = GET_FUNC_PTR(NativeBridgeLoadLibrary); - return f(libpath, flag); -} - -void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len) { - static auto f = GET_FUNC_PTR(NativeBridgeGetTrampoline); - return f(handle, name, shorty, len); -} - -bool NativeBridgeIsSupported(const char* libpath) { - static auto f = GET_FUNC_PTR(NativeBridgeIsSupported); - return f(libpath); -} - -uint32_t NativeBridgeGetVersion() { - static auto f = GET_FUNC_PTR(NativeBridgeGetVersion); - return f(); -} - -NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal) { - static auto f = GET_FUNC_PTR(NativeBridgeGetSignalHandler); - return f(signal); -} - -bool NativeBridgeError() { - static auto f = GET_FUNC_PTR(NativeBridgeError); - return f(); -} - -bool NativeBridgeNameAcceptable(const char* native_bridge_library_filename) { - static auto f = GET_FUNC_PTR(NativeBridgeNameAcceptable); - return f(native_bridge_library_filename); -} - -int NativeBridgeUnloadLibrary(void* handle) { - static auto f = GET_FUNC_PTR(NativeBridgeUnloadLibrary); - return f(handle); -} - -const char* NativeBridgeGetError() { - static auto f = GET_FUNC_PTR(NativeBridgeGetError); - return f(); -} - -bool NativeBridgeIsPathSupported(const char* path) { - static auto f = GET_FUNC_PTR(NativeBridgeIsPathSupported); - return f(path); -} - -bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, - const char* anon_ns_library_path) { - static auto f = GET_FUNC_PTR(NativeBridgeInitAnonymousNamespace); - return f(public_ns_sonames, anon_ns_library_path); -} - -struct native_bridge_namespace_t* NativeBridgeCreateNamespace( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent_ns) { - static auto f = GET_FUNC_PTR(NativeBridgeCreateNamespace); - return f(name, ld_library_path, default_library_path, type, permitted_when_isolated_path, - parent_ns); -} - -bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from, - struct native_bridge_namespace_t* to, - const char* shared_libs_sonames) { - static auto f = GET_FUNC_PTR(NativeBridgeLinkNamespaces); - return f(from, to, shared_libs_sonames); -} - -void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, - struct native_bridge_namespace_t* ns) { - static auto f = GET_FUNC_PTR(NativeBridgeLoadLibraryExt); - return f(libpath, flag, ns); -} - -struct native_bridge_namespace_t* NativeBridgeGetVendorNamespace() { - static auto f = GET_FUNC_PTR(NativeBridgeGetVendorNamespace); - return f(); -} - -#undef GET_FUNC_PTR - -} // namespace android diff --git a/libnativebridge/tests/Android.bp b/libnativebridge/tests/Android.bp deleted file mode 100644 index 2bb846738..000000000 --- a/libnativebridge/tests/Android.bp +++ /dev/null @@ -1,110 +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. -// - -cc_defaults { - name: "libnativebridge-dummy-defaults", - - host_supported: true, - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - ], - header_libs: ["libnativebridge-headers"], - cppflags: ["-fvisibility=protected"], -} - -cc_library_shared { - name: "libnativebridge-dummy", - srcs: ["DummyNativeBridge.cpp"], - defaults: ["libnativebridge-dummy-defaults"], -} - -cc_library_shared { - name: "libnativebridge2-dummy", - srcs: ["DummyNativeBridge2.cpp"], - defaults: ["libnativebridge-dummy-defaults"], -} - -cc_library_shared { - name: "libnativebridge3-dummy", - srcs: ["DummyNativeBridge3.cpp"], - defaults: ["libnativebridge-dummy-defaults"], -} - -// Build the unit tests. -cc_defaults { - name: "libnativebridge-tests-defaults", - test_per_src: true, - - cflags: [ - "-Wall", - "-Werror", - ], - - srcs: [ - "CodeCacheCreate_test.cpp", - "CodeCacheExists_test.cpp", - "CodeCacheStatFail_test.cpp", - "CompleteFlow_test.cpp", - "InvalidCharsNativeBridge_test.cpp", - "NativeBridge2Signal_test.cpp", - "NativeBridgeVersion_test.cpp", - "NeedsNativeBridge_test.cpp", - "PreInitializeNativeBridge_test.cpp", - "PreInitializeNativeBridgeFail1_test.cpp", - "PreInitializeNativeBridgeFail2_test.cpp", - "ReSetupNativeBridge_test.cpp", - "UnavailableNativeBridge_test.cpp", - "ValidNameNativeBridge_test.cpp", - "NativeBridge3UnloadLibrary_test.cpp", - "NativeBridge3GetError_test.cpp", - "NativeBridge3IsPathSupported_test.cpp", - "NativeBridge3InitAnonymousNamespace_test.cpp", - "NativeBridge3CreateNamespace_test.cpp", - "NativeBridge3LoadLibraryExt_test.cpp", - ], - - shared_libs: [ - "liblog", - "libnativebridge-dummy", - ], - header_libs: ["libbase_headers"], -} - -cc_test { - name: "libnativebridge-tests", - defaults: ["libnativebridge-tests-defaults"], - host_supported: true, - shared_libs: ["libnativebridge"], -} - -cc_test { - name: "libnativebridge-lazy-tests", - defaults: ["libnativebridge-tests-defaults"], - shared_libs: ["libnativebridge_lazy"], -} - -// Build the test for the C API. -cc_test { - name: "libnativebridge-api-tests", - host_supported: true, - test_per_src: true, - srcs: [ - "NativeBridgeApi.c", - ], - header_libs: ["libnativebridge-headers"], -} diff --git a/libnativebridge/tests/CodeCacheCreate_test.cpp b/libnativebridge/tests/CodeCacheCreate_test.cpp deleted file mode 100644 index 58270c43d..000000000 --- a/libnativebridge/tests/CodeCacheCreate_test.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include -#include -#include - -namespace android { - -// Tests that the bridge initialization creates the code_cache if it doesn't -// exists. -TEST_F(NativeBridgeTest, CodeCacheCreate) { - // Make sure that code_cache does not exists - struct stat st; - ASSERT_EQ(-1, stat(kCodeCache, &st)); - ASSERT_EQ(ENOENT, errno); - - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_FALSE(NativeBridgeError()); - - // Check that code_cache was created - ASSERT_EQ(0, stat(kCodeCache, &st)); - ASSERT_TRUE(S_ISDIR(st.st_mode)); - - // Clean up - UnloadNativeBridge(); - ASSERT_EQ(0, rmdir(kCodeCache)); - - ASSERT_FALSE(NativeBridgeError()); -} - -} // namespace android diff --git a/libnativebridge/tests/CodeCacheExists_test.cpp b/libnativebridge/tests/CodeCacheExists_test.cpp deleted file mode 100644 index 8ba01586b..000000000 --- a/libnativebridge/tests/CodeCacheExists_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include -#include -#include - -namespace android { - -// Tests that the bridge is initialized without errors if the code_cache already -// exists. -TEST_F(NativeBridgeTest, CodeCacheExists) { - // Make sure that code_cache does not exists - struct stat st; - ASSERT_EQ(-1, stat(kCodeCache, &st)); - ASSERT_EQ(ENOENT, errno); - - // Create the code_cache - ASSERT_EQ(0, mkdir(kCodeCache, S_IRWXU | S_IRWXG | S_IXOTH)); - - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_FALSE(NativeBridgeError()); - - // Check that the code cache is still there - ASSERT_EQ(0, stat(kCodeCache, &st)); - ASSERT_TRUE(S_ISDIR(st.st_mode)); - - // Clean up - UnloadNativeBridge(); - ASSERT_EQ(0, rmdir(kCodeCache)); - - ASSERT_FALSE(NativeBridgeError()); -} - -} // namespace android diff --git a/libnativebridge/tests/CodeCacheStatFail_test.cpp b/libnativebridge/tests/CodeCacheStatFail_test.cpp deleted file mode 100644 index 4ea519ee9..000000000 --- a/libnativebridge/tests/CodeCacheStatFail_test.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include -#include -#include -#include - -namespace android { - -// Tests that the bridge is initialized without errors if the code_cache is -// existed as a file. -TEST_F(NativeBridgeTest, CodeCacheStatFail) { - int fd = creat(kCodeCache, O_RDWR); - ASSERT_NE(-1, fd); - close(fd); - - struct stat st; - ASSERT_EQ(-1, stat(kCodeCacheStatFail, &st)); - ASSERT_EQ(ENOTDIR, errno); - - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(PreInitializeNativeBridge(kCodeCacheStatFail, "isa")); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_FALSE(NativeBridgeError()); - - // Clean up - UnloadNativeBridge(); - - ASSERT_FALSE(NativeBridgeError()); - unlink(kCodeCache); -} - -} // namespace android diff --git a/libnativebridge/tests/CompleteFlow_test.cpp b/libnativebridge/tests/CompleteFlow_test.cpp deleted file mode 100644 index b03379230..000000000 --- a/libnativebridge/tests/CompleteFlow_test.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include - -namespace android { - -TEST_F(NativeBridgeTest, CompleteFlow) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - // Basic calls to check that nothing crashes - ASSERT_FALSE(NativeBridgeIsSupported(nullptr)); - ASSERT_EQ(nullptr, NativeBridgeLoadLibrary(nullptr, 0)); - ASSERT_EQ(nullptr, NativeBridgeGetTrampoline(nullptr, nullptr, nullptr, 0)); - - // Unload - UnloadNativeBridge(); - - ASSERT_FALSE(NativeBridgeAvailable()); - ASSERT_FALSE(NativeBridgeError()); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/DummyNativeBridge.cpp b/libnativebridge/tests/DummyNativeBridge.cpp deleted file mode 100644 index b9894f6b9..000000000 --- a/libnativebridge/tests/DummyNativeBridge.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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. - */ - -// A dummy implementation of the native-bridge interface. - -#include "nativebridge/native_bridge.h" - -// NativeBridgeCallbacks implementations -extern "C" bool native_bridge_initialize(const android::NativeBridgeRuntimeCallbacks* /* art_cbs */, - const char* /* app_code_cache_dir */, - const char* /* isa */) { - return true; -} - -extern "C" void* native_bridge_loadLibrary(const char* /* libpath */, int /* flag */) { - return nullptr; -} - -extern "C" void* native_bridge_getTrampoline(void* /* handle */, const char* /* name */, - const char* /* shorty */, uint32_t /* len */) { - return nullptr; -} - -extern "C" bool native_bridge_isSupported(const char* /* libpath */) { - return false; -} - -extern "C" const struct android::NativeBridgeRuntimeValues* native_bridge_getAppEnv( - const char* /* abi */) { - return nullptr; -} - -android::NativeBridgeCallbacks NativeBridgeItf { - .version = 1, - .initialize = &native_bridge_initialize, - .loadLibrary = &native_bridge_loadLibrary, - .getTrampoline = &native_bridge_getTrampoline, - .isSupported = &native_bridge_isSupported, - .getAppEnv = &native_bridge_getAppEnv -}; diff --git a/libnativebridge/tests/DummyNativeBridge2.cpp b/libnativebridge/tests/DummyNativeBridge2.cpp deleted file mode 100644 index 6920c7482..000000000 --- a/libnativebridge/tests/DummyNativeBridge2.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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. - */ - -// A dummy implementation of the native-bridge interface. - -#include "nativebridge/native_bridge.h" - -#include - -// NativeBridgeCallbacks implementations -extern "C" bool native_bridge2_initialize(const android::NativeBridgeRuntimeCallbacks* /* art_cbs */, - const char* /* app_code_cache_dir */, - const char* /* isa */) { - return true; -} - -extern "C" void* native_bridge2_loadLibrary(const char* /* libpath */, int /* flag */) { - return nullptr; -} - -extern "C" void* native_bridge2_getTrampoline(void* /* handle */, const char* /* name */, - const char* /* shorty */, uint32_t /* len */) { - return nullptr; -} - -extern "C" bool native_bridge2_isSupported(const char* /* libpath */) { - return false; -} - -extern "C" const struct android::NativeBridgeRuntimeValues* native_bridge2_getAppEnv( - const char* /* abi */) { - return nullptr; -} - -extern "C" bool native_bridge2_is_compatible_compatible_with(uint32_t version) { - // For testing, allow 1 and 2, but disallow 3+. - return version <= 2; -} - -static bool native_bridge2_dummy_signal_handler(int, siginfo_t*, void*) { - // TODO: Implement something here. We'd either have to have a death test with a log here, or - // we'd have to be able to resume after the faulting instruction... - return true; -} - -extern "C" android::NativeBridgeSignalHandlerFn native_bridge2_get_signal_handler(int signal) { - if (signal == SIGSEGV) { - return &native_bridge2_dummy_signal_handler; - } - return nullptr; -} - -android::NativeBridgeCallbacks NativeBridgeItf { - .version = 2, - .initialize = &native_bridge2_initialize, - .loadLibrary = &native_bridge2_loadLibrary, - .getTrampoline = &native_bridge2_getTrampoline, - .isSupported = &native_bridge2_isSupported, - .getAppEnv = &native_bridge2_getAppEnv, - .isCompatibleWith = &native_bridge2_is_compatible_compatible_with, - .getSignalHandler = &native_bridge2_get_signal_handler -}; - diff --git a/libnativebridge/tests/DummyNativeBridge3.cpp b/libnativebridge/tests/DummyNativeBridge3.cpp deleted file mode 100644 index 4ef1c8273..000000000 --- a/libnativebridge/tests/DummyNativeBridge3.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * 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. - */ - -// A dummy implementation of the native-bridge interface. - -#include "nativebridge/native_bridge.h" - -#include - -// NativeBridgeCallbacks implementations -extern "C" bool native_bridge3_initialize( - const android::NativeBridgeRuntimeCallbacks* /* art_cbs */, - const char* /* app_code_cache_dir */, - const char* /* isa */) { - return true; -} - -extern "C" void* native_bridge3_loadLibrary(const char* /* libpath */, int /* flag */) { - return nullptr; -} - -extern "C" void* native_bridge3_getTrampoline(void* /* handle */, const char* /* name */, - const char* /* shorty */, uint32_t /* len */) { - return nullptr; -} - -extern "C" bool native_bridge3_isSupported(const char* /* libpath */) { - return false; -} - -extern "C" const struct android::NativeBridgeRuntimeValues* native_bridge3_getAppEnv( - const char* /* abi */) { - return nullptr; -} - -extern "C" bool native_bridge3_isCompatibleWith(uint32_t version) { - // For testing, allow 1-3, but disallow 4+. - return version <= 3; -} - -static bool native_bridge3_dummy_signal_handler(int, siginfo_t*, void*) { - // TODO: Implement something here. We'd either have to have a death test with a log here, or - // we'd have to be able to resume after the faulting instruction... - return true; -} - -extern "C" android::NativeBridgeSignalHandlerFn native_bridge3_getSignalHandler(int signal) { - if (signal == SIGSEGV) { - return &native_bridge3_dummy_signal_handler; - } - return nullptr; -} - -extern "C" int native_bridge3_unloadLibrary(void* /* handle */) { - return 0; -} - -extern "C" const char* native_bridge3_getError() { - return nullptr; -} - -extern "C" bool native_bridge3_isPathSupported(const char* /* path */) { - return true; -} - -extern "C" bool native_bridge3_initAnonymousNamespace(const char* /* public_ns_sonames */, - const char* /* anon_ns_library_path */) { - return true; -} - -extern "C" android::native_bridge_namespace_t* -native_bridge3_createNamespace(const char* /* name */, - const char* /* ld_library_path */, - const char* /* default_library_path */, - uint64_t /* type */, - const char* /* permitted_when_isolated_path */, - android::native_bridge_namespace_t* /* parent_ns */) { - return nullptr; -} - -extern "C" bool native_bridge3_linkNamespaces(android::native_bridge_namespace_t* /* from */, - android::native_bridge_namespace_t* /* to */, - const char* /* shared_libs_soname */) { - return true; -} - -extern "C" void* native_bridge3_loadLibraryExt(const char* /* libpath */, - int /* flag */, - android::native_bridge_namespace_t* /* ns */) { - return nullptr; -} - -android::NativeBridgeCallbacks NativeBridgeItf{ - // v1 - .version = 3, - .initialize = &native_bridge3_initialize, - .loadLibrary = &native_bridge3_loadLibrary, - .getTrampoline = &native_bridge3_getTrampoline, - .isSupported = &native_bridge3_isSupported, - .getAppEnv = &native_bridge3_getAppEnv, - // v2 - .isCompatibleWith = &native_bridge3_isCompatibleWith, - .getSignalHandler = &native_bridge3_getSignalHandler, - // v3 - .unloadLibrary = &native_bridge3_unloadLibrary, - .getError = &native_bridge3_getError, - .isPathSupported = &native_bridge3_isPathSupported, - .initAnonymousNamespace = &native_bridge3_initAnonymousNamespace, - .createNamespace = &native_bridge3_createNamespace, - .linkNamespaces = &native_bridge3_linkNamespaces, - .loadLibraryExt = &native_bridge3_loadLibraryExt}; diff --git a/libnativebridge/tests/InvalidCharsNativeBridge_test.cpp b/libnativebridge/tests/InvalidCharsNativeBridge_test.cpp deleted file mode 100644 index 8f7973df0..000000000 --- a/libnativebridge/tests/InvalidCharsNativeBridge_test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -static const char* kTestName = "../librandom$@-bridge_not.existing.so"; - -TEST_F(NativeBridgeTest, InvalidChars) { - // Do one test actually calling setup. - EXPECT_EQ(false, NativeBridgeError()); - LoadNativeBridge(kTestName, nullptr); - // This should lead to an error for invalid characters. - EXPECT_EQ(true, NativeBridgeError()); - - // Further tests need to use NativeBridgeNameAcceptable, as the error - // state can't be changed back. - EXPECT_EQ(false, NativeBridgeNameAcceptable(".")); - EXPECT_EQ(false, NativeBridgeNameAcceptable("..")); - EXPECT_EQ(false, NativeBridgeNameAcceptable("_")); - EXPECT_EQ(false, NativeBridgeNameAcceptable("-")); - EXPECT_EQ(false, NativeBridgeNameAcceptable("lib@.so")); - EXPECT_EQ(false, NativeBridgeNameAcceptable("lib$.so")); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge2Signal_test.cpp b/libnativebridge/tests/NativeBridge2Signal_test.cpp deleted file mode 100644 index 44e45e362..000000000 --- a/libnativebridge/tests/NativeBridge2Signal_test.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include -#include - -namespace android { - -constexpr const char* kNativeBridgeLibrary2 = "libnativebridge2-dummy.so"; - -TEST_F(NativeBridgeTest, V2_Signal) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary2, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(2U, NativeBridgeGetVersion()); - ASSERT_NE(nullptr, NativeBridgeGetSignalHandler(SIGSEGV)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp b/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp deleted file mode 100644 index 668d9428a..000000000 --- a/libnativebridge/tests/NativeBridge3CreateNamespace_test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_CreateNamespace) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(nullptr, NativeBridgeCreateNamespace(nullptr, nullptr, nullptr, - 0, nullptr, nullptr)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3GetError_test.cpp b/libnativebridge/tests/NativeBridge3GetError_test.cpp deleted file mode 100644 index 0b9f5821f..000000000 --- a/libnativebridge/tests/NativeBridge3GetError_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_GetError) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(nullptr, NativeBridgeGetError()); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp b/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp deleted file mode 100644 index b0d6b09d1..000000000 --- a/libnativebridge/tests/NativeBridge3InitAnonymousNamespace_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_InitAnonymousNamespace) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(true, NativeBridgeInitAnonymousNamespace(nullptr, nullptr)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp b/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp deleted file mode 100644 index 325e40b40..000000000 --- a/libnativebridge/tests/NativeBridge3IsPathSupported_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_IsPathSupported) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(true, NativeBridgeIsPathSupported(nullptr)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp b/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp deleted file mode 100644 index 4caeb4481..000000000 --- a/libnativebridge/tests/NativeBridge3LoadLibraryExt_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_LoadLibraryExt) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(nullptr, NativeBridgeLoadLibraryExt(nullptr, 0, nullptr)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp b/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp deleted file mode 100644 index 93a979c0a..000000000 --- a/libnativebridge/tests/NativeBridge3UnloadLibrary_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -TEST_F(NativeBridgeTest, V3_UnloadLibrary) { - // Init - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary3, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(PreInitializeNativeBridge(".", "isa")); - ASSERT_TRUE(NativeBridgeAvailable()); - ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr)); - ASSERT_TRUE(NativeBridgeAvailable()); - - ASSERT_EQ(3U, NativeBridgeGetVersion()); - ASSERT_EQ(0, NativeBridgeUnloadLibrary(nullptr)); - - // Clean-up code_cache - ASSERT_EQ(0, rmdir(kCodeCache)); -} - -} // namespace android diff --git a/libnativebridge/tests/NativeBridgeApi.c b/libnativebridge/tests/NativeBridgeApi.c deleted file mode 100644 index 7ab71fe81..000000000 --- a/libnativebridge/tests/NativeBridgeApi.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The main purpose of this test is to ensure this C header compiles in C, so - * that no C++ features inadvertently leak into the C ABI. */ -#include "nativebridge/native_bridge.h" - -int main(int argc, char** argv) { - (void)argc; - (void)argv; - return 0; -} diff --git a/libnativebridge/tests/NativeBridgeTest.h b/libnativebridge/tests/NativeBridgeTest.h deleted file mode 100644 index 0f99816c9..000000000 --- a/libnativebridge/tests/NativeBridgeTest.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#ifndef NATIVE_BRIDGE_TEST_H_ -#define NATIVE_BRIDGE_TEST_H_ - -#define LOG_TAG "NativeBridge_test" - -#include -#include - -constexpr const char* kNativeBridgeLibrary = "libnativebridge-dummy.so"; -constexpr const char* kCodeCache = "./code_cache"; -constexpr const char* kCodeCacheStatFail = "./code_cache/temp"; -constexpr const char* kNativeBridgeLibrary2 = "libnativebridge2-dummy.so"; -constexpr const char* kNativeBridgeLibrary3 = "libnativebridge3-dummy.so"; - -namespace android { - -class NativeBridgeTest : public testing::Test { -}; - -}; // namespace android - -#endif // NATIVE_BRIDGE_H_ - diff --git a/libnativebridge/tests/NativeBridgeVersion_test.cpp b/libnativebridge/tests/NativeBridgeVersion_test.cpp deleted file mode 100644 index d3f9a80fc..000000000 --- a/libnativebridge/tests/NativeBridgeVersion_test.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include - -namespace android { - -TEST_F(NativeBridgeTest, Version) { - // When a bridge isn't loaded, we expect 0. - EXPECT_EQ(NativeBridgeGetVersion(), 0U); - - // After our dummy bridge has been loaded, we expect 1. - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - EXPECT_EQ(NativeBridgeGetVersion(), 1U); - - // Unload - UnloadNativeBridge(); - - // Version information is gone. - EXPECT_EQ(NativeBridgeGetVersion(), 0U); -} - -} // namespace android diff --git a/libnativebridge/tests/NeedsNativeBridge_test.cpp b/libnativebridge/tests/NeedsNativeBridge_test.cpp deleted file mode 100644 index c8ff743b0..000000000 --- a/libnativebridge/tests/NeedsNativeBridge_test.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include - -namespace android { - -static const char* kISAs[] = { "arm", "arm64", "mips", "mips64", "x86", "x86_64", "random", "64arm", - "64_x86", "64_x86_64", "", "reallylongstringabcd", nullptr }; - -TEST_F(NativeBridgeTest, NeedsNativeBridge) { - EXPECT_EQ(false, NeedsNativeBridge(ABI_STRING)); - - const size_t kISACount = sizeof(kISAs) / sizeof(kISAs[0]); - for (size_t i = 0; i < kISACount; i++) { - EXPECT_EQ(kISAs[i] == nullptr ? false : strcmp(kISAs[i], ABI_STRING) != 0, - NeedsNativeBridge(kISAs[i])); - } -} - -} // namespace android diff --git a/libnativebridge/tests/PreInitializeNativeBridgeFail1_test.cpp b/libnativebridge/tests/PreInitializeNativeBridgeFail1_test.cpp deleted file mode 100644 index 5a2b0a150..000000000 --- a/libnativebridge/tests/PreInitializeNativeBridgeFail1_test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -namespace android { - -TEST_F(NativeBridgeTest, PreInitializeNativeBridgeFail1) { - // Needs a valid application directory. - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); - ASSERT_FALSE(PreInitializeNativeBridge(nullptr, "isa")); - ASSERT_TRUE(NativeBridgeError()); -} - -} // namespace android diff --git a/libnativebridge/tests/PreInitializeNativeBridgeFail2_test.cpp b/libnativebridge/tests/PreInitializeNativeBridgeFail2_test.cpp deleted file mode 100644 index af976b174..000000000 --- a/libnativebridge/tests/PreInitializeNativeBridgeFail2_test.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "NativeBridgeTest.h" - -namespace android { - -TEST_F(NativeBridgeTest, PreInitializeNativeBridgeFail2) { - // Needs LoadNativeBridge() first - ASSERT_FALSE(PreInitializeNativeBridge(nullptr, "isa")); - ASSERT_TRUE(NativeBridgeError()); -} - -} // namespace android diff --git a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp b/libnativebridge/tests/PreInitializeNativeBridge_test.cpp deleted file mode 100644 index cd5a8e24b..000000000 --- a/libnativebridge/tests/PreInitializeNativeBridge_test.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "NativeBridgeTest.h" - -namespace android { - -TEST_F(NativeBridgeTest, PreInitializeNativeBridge) { - ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr)); -#if !defined(__APPLE__) // Mac OS does not support bind-mount. -#if !defined(__ANDROID__) // Cannot write into the hard-wired location. - static constexpr const char* kTestData = "PreInitializeNativeBridge test."; - - // Try to create our mount namespace. - if (unshare(CLONE_NEWNS) != -1) { - // Create a dummy file. - FILE* cpuinfo = fopen("./cpuinfo", "w"); - ASSERT_NE(nullptr, cpuinfo) << strerror(errno); - fprintf(cpuinfo, kTestData); - fclose(cpuinfo); - - ASSERT_TRUE(PreInitializeNativeBridge("does not matter 1", "short 2")); - - // Read /proc/cpuinfo - FILE* proc_cpuinfo = fopen("/proc/cpuinfo", "r"); - ASSERT_NE(nullptr, proc_cpuinfo) << strerror(errno); - char buf[1024]; - EXPECT_NE(nullptr, fgets(buf, sizeof(buf), proc_cpuinfo)) << "Error reading."; - fclose(proc_cpuinfo); - - EXPECT_EQ(0, strcmp(buf, kTestData)); - - // Delete the file. - ASSERT_EQ(0, unlink("./cpuinfo")) << "Error unlinking temporary file."; - // Ending the test will tear down the mount namespace. - } else { - GTEST_LOG_(WARNING) << "Could not create mount namespace. Are you running this as root?"; - } -#endif -#endif -} - -} // namespace android diff --git a/libnativebridge/tests/ReSetupNativeBridge_test.cpp b/libnativebridge/tests/ReSetupNativeBridge_test.cpp deleted file mode 100644 index 944e5d7e9..000000000 --- a/libnativebridge/tests/ReSetupNativeBridge_test.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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. - */ - -#include "NativeBridgeTest.h" - -namespace android { - -TEST_F(NativeBridgeTest, ReSetup) { - EXPECT_EQ(false, NativeBridgeError()); - LoadNativeBridge("", nullptr); - EXPECT_EQ(false, NativeBridgeError()); - LoadNativeBridge("", nullptr); - // This should lead to an error for trying to re-setup a native bridge. - EXPECT_EQ(true, NativeBridgeError()); -} - -} // namespace android diff --git a/libnativebridge/tests/UnavailableNativeBridge_test.cpp b/libnativebridge/tests/UnavailableNativeBridge_test.cpp deleted file mode 100644 index ad374a5e9..000000000 --- a/libnativebridge/tests/UnavailableNativeBridge_test.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2011 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 "NativeBridgeTest.h" - -namespace android { - -TEST_F(NativeBridgeTest, NoNativeBridge) { - EXPECT_EQ(false, NativeBridgeAvailable()); - // Try to initialize. This should fail as we are not set up. - EXPECT_EQ(false, InitializeNativeBridge(nullptr, nullptr)); - EXPECT_EQ(true, NativeBridgeError()); - EXPECT_EQ(false, NativeBridgeAvailable()); -} - -} // namespace android diff --git a/libnativebridge/tests/ValidNameNativeBridge_test.cpp b/libnativebridge/tests/ValidNameNativeBridge_test.cpp deleted file mode 100644 index 690be4a30..000000000 --- a/libnativebridge/tests/ValidNameNativeBridge_test.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2011 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 - -namespace android { - -static const char* kTestName = "librandom-bridge_not.existing.so"; - -TEST_F(NativeBridgeTest, ValidName) { - // Check that the name is acceptable. - EXPECT_EQ(true, NativeBridgeNameAcceptable(kTestName)); - - // Now check what happens on LoadNativeBridge. - EXPECT_EQ(false, NativeBridgeError()); - LoadNativeBridge(kTestName, nullptr); - // This will lead to an error as the library doesn't exist. - EXPECT_EQ(true, NativeBridgeError()); - EXPECT_EQ(false, NativeBridgeAvailable()); -} - -} // namespace android diff --git a/libnativeloader/.clang-format b/libnativeloader/.clang-format deleted file mode 120000 index fd0645fdf..000000000 --- a/libnativeloader/.clang-format +++ /dev/null @@ -1 +0,0 @@ -../.clang-format-2 \ No newline at end of file diff --git a/libnativeloader/Android.bp b/libnativeloader/Android.bp deleted file mode 100644 index 2ee9d2827..000000000 --- a/libnativeloader/Android.bp +++ /dev/null @@ -1,97 +0,0 @@ -// Shared library for target -// ======================================================== -cc_defaults { - name: "libnativeloader-defaults", - cflags: [ - "-Werror", - "-Wall", - ], - cppflags: [ - "-fvisibility=hidden", - ], - header_libs: ["libnativeloader-headers"], - export_header_lib_headers: ["libnativeloader-headers"], -} - -cc_library { - name: "libnativeloader", - defaults: ["libnativeloader-defaults"], - // TODO(oth): remove after moving under art/ (b/137364733) - visibility: ["//visibility:public"], - host_supported: true, - srcs: [ - "native_loader.cpp", - ], - shared_libs: [ - "libnativehelper", - "liblog", - "libnativebridge", - "libbase", - ], - target: { - android: { - srcs: [ - "library_namespaces.cpp", - "native_loader_namespace.cpp", - "public_libraries.cpp", - ], - shared_libs: [ - "libdl_android", - ], - }, - }, - required: [ - "llndk.libraries.txt", - "vndksp.libraries.txt", - ], - stubs: { - symbol_file: "libnativeloader.map.txt", - versions: ["1"], - }, -} - -// TODO(b/124250621) eliminate the need for this library -cc_library { - name: "libnativeloader_lazy", - defaults: ["libnativeloader-defaults"], - // TODO(oth): remove after moving under art/ (b/137364733) - visibility: ["//visibility:public"], - host_supported: false, - srcs: ["native_loader_lazy.cpp"], - required: ["libnativeloader"], -} - -cc_library_headers { - name: "libnativeloader-headers", - // TODO(oth): remove after moving under art/ (b/137364733) - visibility: ["//visibility:public"], - host_supported: true, - export_include_dirs: ["include"], -} - -cc_test { - name: "libnativeloader_test", - srcs: [ - "native_loader_test.cpp", - "native_loader.cpp", - "library_namespaces.cpp", - "native_loader_namespace.cpp", - "public_libraries.cpp", - ], - cflags: ["-DANDROID"], - static_libs: [ - "libbase", - "liblog", - "libnativehelper", - "libgmock", - ], - header_libs: [ - "libnativebridge-headers", - "libnativeloader-headers", - ], - system_shared_libs: [ - "libc", - "libm", - ], - test_suites: ["device-tests"], -} diff --git a/libnativeloader/CPPLINT.cfg b/libnativeloader/CPPLINT.cfg deleted file mode 100644 index db98533fc..000000000 --- a/libnativeloader/CPPLINT.cfg +++ /dev/null @@ -1,19 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -filter=-build/header_guard -filter=-readability/check -filter=-build/namespaces diff --git a/libnativeloader/OWNERS b/libnativeloader/OWNERS deleted file mode 100644 index f7356530a..000000000 --- a/libnativeloader/OWNERS +++ /dev/null @@ -1,6 +0,0 @@ -dimitry@google.com -jiyong@google.com -ngeoffray@google.com -oth@google.com -mast@google.com -rpl@google.com diff --git a/libnativeloader/README.md b/libnativeloader/README.md deleted file mode 100644 index 57b90019e..000000000 --- a/libnativeloader/README.md +++ /dev/null @@ -1,84 +0,0 @@ -libnativeloader -=============================================================================== - -Overview -------------------------------------------------------------------------------- -libnativeloader is responsible for loading native shared libraries (`*.so` -files) inside the Android Runtime (ART). The native shared libraries could be -app-provided JNI libraries or public native libraries like `libc.so` provided -by the platform. - -The most typical use case of this library is calling `System.loadLibrary(name)`. -When the method is called, the ART runtime delegates the call to this library -along with the reference to the classloader where the call was made. Then this -library finds the linker namespace (named `classloader-namespace`) that is -associated with the given classloader, and tries to load the requested library -from the namespace. The actual searching, loading, and linking of the library -is performed by the dynamic linker. - -The linker namespace is created when an APK is loaded into the process, and is -associated with the classloader that loaded the APK. The linker namespace is -configured so that only the JNI libraries embedded in the APK is accessible -from the namespace, thus preventing an APK from loading JNI libraries of other -APKs. - -The linker namespace is also configured differently depending on other -characteristics of the APK such as whether or not the APK is bundled with the -platform. In case of the unbundled, i.e., downloaded or updated APK, only the -public native libraries that is listed in `/system/etc/public.libraries.txt` -are available from the platform, whereas in case of the bundled, all libraries -under `/system/lib` are available (i.e. shared). In case when the unbundled -app is from `/vendor` or `/product` partition, the app is additionally provided -with the [VNDK-SP](https://source.android.com/devices/architecture/vndk#sp-hal) -libraries. As the platform is getting modularized with -[APEX](https://android.googlesource.com/platform/system/apex/+/refs/heads/master/docs/README.md), -some libraries are no longer provided from platform, but from the APEXes which -have their own linker namespaces. For example, ICU libraries `libicuuc.so` and -`libicui18n.so` are from the runtime APEX. - -The list of public native libraries is not static. The default set of libraries -are defined in AOSP, but partners can extend it to include their own libraries. -Currently, following extensions are available: - -- `/vendor/etc/public.libraries.txt`: libraries in `/vendor/lib` that are -specific to the underlying SoC, e.g. GPU, DSP, etc. -- `/{system|product}/etc/public.libraries-.txt`: libraries in -`/{system|product}/lib` that a device manufacturer has newly added. The -libraries should be named as `lib..so` as in -`libFoo.acme.so`. - -Note that, due to the naming constraint requiring `..so` suffix, it -is prohibited for a device manufacturer to expose an AOSP-defined private -library, e.g. libgui.so, libart.so, etc., to APKs. - -Lastly, libnativeloader is responsible for abstracting the two types of the -dynamic linker interface: `libdl.so` and `libnativebridge.so`. The former is -for non-translated, e.g. ARM-on-ARM, libraries, while the latter is for -loading libraries in a translated environment such as ARM-on-x86. - -Implementation -------------------------------------------------------------------------------- -Implementation wise, libnativeloader consists of four parts: - -- `native_loader.cpp` -- `library_namespaces.cpp` -- `native_loader_namespace.cpp` -- `public_libraries.cpp` - -`native_loader.cpp` implements the public interface of this library. It is just -a thin wrapper around `library_namespaces.cpp` and `native_loader_namespace.cpp`. - -`library_namespaces.cpp` implements the singleton class `LibraryNamespaces` which -is a manager-like entity that is responsible for creating and configuring -linker namespaces and finding an already created linker namespace for a given -classloader. - -`native_loader_namespace.cpp` implements the class `NativeLoaderNamespace` that -models a linker namespace. Its main job is to abstract the two types of the -dynamic linker interface so that other parts of this library do not have to know -the differences of the interfaces. - -`public_libraries.cpp` is responsible for reading `*.txt` files for the public -native libraries from the various partitions. It can be considered as a part of -`LibraryNamespaces` but is separated from it to hide the details of the parsing -routines. diff --git a/libnativeloader/TEST_MAPPING b/libnativeloader/TEST_MAPPING deleted file mode 100644 index 7becb7791..000000000 --- a/libnativeloader/TEST_MAPPING +++ /dev/null @@ -1,12 +0,0 @@ -{ - "presubmit": [ - { - "name": "libnativeloader_test" - } - ], - "imports": [ - { - "path": "cts/tests/tests/jni" - } - ] -} diff --git a/libnativeloader/include/nativeloader/dlext_namespaces.h b/libnativeloader/include/nativeloader/dlext_namespaces.h deleted file mode 100644 index 8937636cf..000000000 --- a/libnativeloader/include/nativeloader/dlext_namespaces.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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. - */ - -#ifndef __ANDROID_DLEXT_NAMESPACES_H__ -#define __ANDROID_DLEXT_NAMESPACES_H__ - -#include -#include - -__BEGIN_DECLS - -enum { - /* A regular namespace is the namespace with a custom search path that does - * not impose any restrictions on the location of native libraries. - */ - ANDROID_NAMESPACE_TYPE_REGULAR = 0, - - /* An isolated namespace requires all the libraries to be on the search path - * or under permitted_when_isolated_path. The search path is the union of - * ld_library_path and default_library_path. - */ - ANDROID_NAMESPACE_TYPE_ISOLATED = 1, - - /* The shared namespace clones the list of libraries of the caller namespace upon creation - * which means that they are shared between namespaces - the caller namespace and the new one - * will use the same copy of a library if it was loaded prior to android_create_namespace call. - * - * Note that libraries loaded after the namespace is created will not be shared. - * - * Shared namespaces can be isolated or regular. Note that they do not inherit the search path nor - * permitted_path from the caller's namespace. - */ - ANDROID_NAMESPACE_TYPE_SHARED = 2, - - /* This flag instructs linker to enable grey-list workaround for the namespace. - * See http://b/26394120 for details. - */ - ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000, - - /* This flag instructs linker to use this namespace as the anonymous - * namespace. The anonymous namespace is used in the case when linker cannot - * identify the caller of dlopen/dlsym. This happens for the code not loaded - * by dynamic linker; for example calls from the mono-compiled code. There can - * be only one anonymous namespace in a process. If there already is an - * anonymous namespace in the process, using this flag when creating a new - * namespace causes an error. - */ - ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS = 0x10000000, - - ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = - ANDROID_NAMESPACE_TYPE_SHARED | ANDROID_NAMESPACE_TYPE_ISOLATED, -}; - -/* - * Creates new linker namespace. - * ld_library_path and default_library_path represent the search path - * for the libraries in the namespace. - * - * The libraries in the namespace are searched by folowing order: - * 1. ld_library_path (Think of this as namespace-local LD_LIBRARY_PATH) - * 2. In directories specified by DT_RUNPATH of the "needed by" binary. - * 3. deault_library_path (This of this as namespace-local default library path) - * - * When type is ANDROID_NAMESPACE_TYPE_ISOLATED the resulting namespace requires all of - * the libraries to be on the search path or under the permitted_when_isolated_path; - * the search_path is ld_library_path:default_library_path. Note that the - * permitted_when_isolated_path path is not part of the search_path and - * does not affect the search order. It is a way to allow loading libraries from specific - * locations when using absolute path. - * If a library or any of its dependencies are outside of the permitted_when_isolated_path - * and search_path, and it is not part of the public namespace dlopen will fail. - */ -extern struct android_namespace_t* android_create_namespace( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct android_namespace_t* parent); - -/* - * Creates a link between namespaces. Every link has list of sonames of - * shared libraries. These are the libraries which are accessible from - * namespace 'from' but loaded within namespace 'to' context. - * When to namespace is nullptr this function establishes a link between - * 'from' namespace and the default namespace. - * - * The lookup order of the libraries in namespaces with links is following: - * 1. Look inside current namespace using 'this' namespace search path. - * 2. Look in linked namespaces - * 2.1. Perform soname check - if library soname is not in the list of shared - * libraries sonames skip this link, otherwise - * 2.2. Search library using linked namespace search path. Note that this - * step will not go deeper into linked namespaces for this library but - * will do so for DT_NEEDED libraries. - */ -extern bool android_link_namespaces(struct android_namespace_t* from, - struct android_namespace_t* to, - const char* shared_libs_sonames); - -extern struct android_namespace_t* android_get_exported_namespace(const char* name); - -__END_DECLS - -#endif /* __ANDROID_DLEXT_NAMESPACES_H__ */ diff --git a/libnativeloader/include/nativeloader/native_loader.h b/libnativeloader/include/nativeloader/native_loader.h deleted file mode 100644 index 51fb875f6..000000000 --- a/libnativeloader/include/nativeloader/native_loader.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - */ - -#ifndef NATIVE_LOADER_H_ -#define NATIVE_LOADER_H_ - -#include -#include -#include "jni.h" -#if defined(__ANDROID__) -#include -#endif - -#ifdef __cplusplus -namespace android { -extern "C" { -#endif // __cplusplus - -// README: the char** error message parameter being passed -// to the methods below need to be freed through calling NativeLoaderFreeErrorMessage. -// It's the caller's responsibility to call that method. - -__attribute__((visibility("default"))) -void InitializeNativeLoader(); - -__attribute__((visibility("default"))) jstring CreateClassLoaderNamespace( - JNIEnv* env, int32_t target_sdk_version, jobject class_loader, bool is_shared, jstring dex_path, - jstring library_path, jstring permitted_path); - -__attribute__((visibility("default"))) void* OpenNativeLibrary( - JNIEnv* env, int32_t target_sdk_version, const char* path, jobject class_loader, - const char* caller_location, jstring library_path, bool* needs_native_bridge, char** error_msg); - -__attribute__((visibility("default"))) bool CloseNativeLibrary(void* handle, - const bool needs_native_bridge, - char** error_msg); - -__attribute__((visibility("default"))) void NativeLoaderFreeErrorMessage(char* msg); - -#if defined(__ANDROID__) -// Look up linker namespace by class_loader. Returns nullptr if -// there is no namespace associated with the class_loader. -// TODO(b/79940628): move users to FindNativeLoaderNamespaceByClassLoader and remove this function. -__attribute__((visibility("default"))) struct android_namespace_t* FindNamespaceByClassLoader( - JNIEnv* env, jobject class_loader); -// That version works with native bridge namespaces, but requires use of OpenNativeLibrary. -struct NativeLoaderNamespace; -__attribute__((visibility("default"))) struct NativeLoaderNamespace* -FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, jobject class_loader); -// Load library. Unlinke OpenNativeLibrary above couldn't create namespace on demand, but does -// not require access to JNIEnv either. -__attribute__((visibility("default"))) void* OpenNativeLibraryInNamespace( - struct NativeLoaderNamespace* ns, const char* path, bool* needs_native_bridge, - char** error_msg); -#endif - -__attribute__((visibility("default"))) -void ResetNativeLoader(); - -#ifdef __cplusplus -} // extern "C" -} // namespace android -#endif // __cplusplus - -#endif // NATIVE_BRIDGE_H_ diff --git a/libnativeloader/libnativeloader.map.txt b/libnativeloader/libnativeloader.map.txt deleted file mode 100644 index 40c30bd4a..000000000 --- a/libnativeloader/libnativeloader.map.txt +++ /dev/null @@ -1,31 +0,0 @@ -# -# Copyright (C) 2019 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# TODO(b/122710865): Prune these uses once the runtime APEX is complete. -LIBNATIVELOADER_1 { - global: - OpenNativeLibrary; - InitializeNativeLoader; - ResetNativeLoader; - CloseNativeLibrary; - OpenNativeLibraryInNamespace; - FindNamespaceByClassLoader; - FindNativeLoaderNamespaceByClassLoader; - CreateClassLoaderNamespace; - NativeLoaderFreeErrorMessage; - local: - *; -}; diff --git a/libnativeloader/library_namespaces.cpp b/libnativeloader/library_namespaces.cpp deleted file mode 100644 index 7246b9764..000000000 --- a/libnativeloader/library_namespaces.cpp +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "library_namespaces.h" - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "nativeloader/dlext_namespaces.h" -#include "public_libraries.h" -#include "utils.h" - -using android::base::Error; - -namespace android::nativeloader { - -namespace { -// The device may be configured to have the vendor libraries loaded to a separate namespace. -// For historical reasons this namespace was named sphal but effectively it is intended -// to use to load vendor libraries to separate namespace with controlled interface between -// vendor and system namespaces. -constexpr const char* kVendorNamespaceName = "sphal"; -constexpr const char* kVndkNamespaceName = "vndk"; -constexpr const char* kArtNamespaceName = "art"; -constexpr const char* kNeuralNetworksNamespaceName = "neuralnetworks"; - -// classloader-namespace is a linker namespace that is created for the loaded -// app. To be specific, it is created for the app classloader. When -// System.load() is called from a Java class that is loaded from the -// classloader, the classloader-namespace namespace associated with that -// classloader is selected for dlopen. The namespace is configured so that its -// search path is set to the app-local JNI directory and it is linked to the -// platform namespace with the names of libs listed in the public.libraries.txt. -// This way an app can only load its own JNI libraries along with the public libs. -constexpr const char* kClassloaderNamespaceName = "classloader-namespace"; -// Same thing for vendor APKs. -constexpr const char* kVendorClassloaderNamespaceName = "vendor-classloader-namespace"; - -// (http://b/27588281) This is a workaround for apps using custom classloaders and calling -// System.load() with an absolute path which is outside of the classloader library search path. -// This list includes all directories app is allowed to access this way. -constexpr const char* kWhitelistedDirectories = "/data:/mnt/expand"; - -constexpr const char* kVendorLibPath = "/vendor/" LIB; -constexpr const char* kProductLibPath = "/product/" LIB ":/system/product/" LIB; - -const std::regex kVendorDexPathRegex("(^|:)/vendor/"); -const std::regex kProductDexPathRegex("(^|:)(/system)?/product/"); - -// Define origin of APK if it is from vendor partition or product partition -typedef enum { - APK_ORIGIN_DEFAULT = 0, - APK_ORIGIN_VENDOR = 1, - APK_ORIGIN_PRODUCT = 2, -} ApkOrigin; - -jobject GetParentClassLoader(JNIEnv* env, jobject class_loader) { - jclass class_loader_class = env->FindClass("java/lang/ClassLoader"); - jmethodID get_parent = - env->GetMethodID(class_loader_class, "getParent", "()Ljava/lang/ClassLoader;"); - - return env->CallObjectMethod(class_loader, get_parent); -} - -ApkOrigin GetApkOriginFromDexPath(JNIEnv* env, jstring dex_path) { - ApkOrigin apk_origin = APK_ORIGIN_DEFAULT; - - if (dex_path != nullptr) { - ScopedUtfChars dex_path_utf_chars(env, dex_path); - - if (std::regex_search(dex_path_utf_chars.c_str(), kVendorDexPathRegex)) { - apk_origin = APK_ORIGIN_VENDOR; - } - - if (std::regex_search(dex_path_utf_chars.c_str(), kProductDexPathRegex)) { - LOG_ALWAYS_FATAL_IF(apk_origin == APK_ORIGIN_VENDOR, - "Dex path contains both vendor and product partition : %s", - dex_path_utf_chars.c_str()); - - apk_origin = APK_ORIGIN_PRODUCT; - } - } - return apk_origin; -} - -} // namespace - -void LibraryNamespaces::Initialize() { - // Once public namespace is initialized there is no - // point in running this code - it will have no effect - // on the current list of public libraries. - if (initialized_) { - return; - } - - // android_init_namespaces() expects all the public libraries - // to be loaded so that they can be found by soname alone. - // - // TODO(dimitry): this is a bit misleading since we do not know - // if the vendor public library is going to be opened from /vendor/lib - // we might as well end up loading them from /system/lib or /product/lib - // For now we rely on CTS test to catch things like this but - // it should probably be addressed in the future. - for (const auto& soname : android::base::Split(preloadable_public_libraries(), ":")) { - LOG_ALWAYS_FATAL_IF(dlopen(soname.c_str(), RTLD_NOW | RTLD_NODELETE) == nullptr, - "Error preloading public library %s: %s", soname.c_str(), dlerror()); - } -} - -Result LibraryNamespaces::Create(JNIEnv* env, uint32_t target_sdk_version, - jobject class_loader, bool is_shared, - jstring dex_path, - jstring java_library_path, - jstring java_permitted_path) { - std::string library_path; // empty string by default. - - if (java_library_path != nullptr) { - ScopedUtfChars library_path_utf_chars(env, java_library_path); - library_path = library_path_utf_chars.c_str(); - } - - ApkOrigin apk_origin = GetApkOriginFromDexPath(env, dex_path); - - // (http://b/27588281) This is a workaround for apps using custom - // classloaders and calling System.load() with an absolute path which - // is outside of the classloader library search path. - // - // This part effectively allows such a classloader to access anything - // under /data and /mnt/expand - std::string permitted_path = kWhitelistedDirectories; - - if (java_permitted_path != nullptr) { - ScopedUtfChars path(env, java_permitted_path); - if (path.c_str() != nullptr && path.size() > 0) { - permitted_path = permitted_path + ":" + path.c_str(); - } - } - - LOG_ALWAYS_FATAL_IF(FindNamespaceByClassLoader(env, class_loader) != nullptr, - "There is already a namespace associated with this classloader"); - - std::string system_exposed_libraries = default_public_libraries(); - const char* namespace_name = kClassloaderNamespaceName; - bool unbundled_vendor_or_product_app = false; - if ((apk_origin == APK_ORIGIN_VENDOR || - (apk_origin == APK_ORIGIN_PRODUCT && target_sdk_version > 29)) && - !is_shared) { - unbundled_vendor_or_product_app = true; - // For vendor / product apks, give access to the vendor / product lib even though - // they are treated as unbundled; the libs and apks are still bundled - // together in the vendor / product partition. - const char* origin_partition; - const char* origin_lib_path; - - switch (apk_origin) { - case APK_ORIGIN_VENDOR: - origin_partition = "vendor"; - origin_lib_path = kVendorLibPath; - break; - case APK_ORIGIN_PRODUCT: - origin_partition = "product"; - origin_lib_path = kProductLibPath; - break; - default: - origin_partition = "unknown"; - origin_lib_path = ""; - } - library_path = library_path + ":" + origin_lib_path; - permitted_path = permitted_path + ":" + origin_lib_path; - - // Also give access to LLNDK libraries since they are available to vendors - system_exposed_libraries = system_exposed_libraries + ":" + llndk_libraries().c_str(); - - // Different name is useful for debugging - namespace_name = kVendorClassloaderNamespaceName; - ALOGD("classloader namespace configured for unbundled %s apk. library_path=%s", - origin_partition, library_path.c_str()); - } else { - // extended public libraries are NOT available to vendor apks, otherwise it - // would be system->vendor violation. - if (!extended_public_libraries().empty()) { - system_exposed_libraries = system_exposed_libraries + ':' + extended_public_libraries(); - } - } - - // Create the app namespace - NativeLoaderNamespace* parent_ns = FindParentNamespaceByClassLoader(env, class_loader); - // Heuristic: the first classloader with non-empty library_path is assumed to - // be the main classloader for app - // TODO(b/139178525) remove this heuristic by determining this in LoadedApk (or its - // friends) and then passing it down to here. - bool is_main_classloader = app_main_namespace_ == nullptr && !library_path.empty(); - // Policy: the namespace for the main classloader is also used as the - // anonymous namespace. - bool also_used_as_anonymous = is_main_classloader; - // Note: this function is executed with g_namespaces_mutex held, thus no - // racing here. - auto app_ns = NativeLoaderNamespace::Create( - namespace_name, library_path, permitted_path, parent_ns, is_shared, - target_sdk_version < 24 /* is_greylist_enabled */, also_used_as_anonymous); - if (!app_ns) { - return app_ns.error(); - } - // ... and link to other namespaces to allow access to some public libraries - bool is_bridged = app_ns->IsBridged(); - - auto platform_ns = NativeLoaderNamespace::GetPlatformNamespace(is_bridged); - if (!platform_ns) { - return platform_ns.error(); - } - - auto linked = app_ns->Link(*platform_ns, system_exposed_libraries); - if (!linked) { - return linked.error(); - } - - auto art_ns = NativeLoaderNamespace::GetExportedNamespace(kArtNamespaceName, is_bridged); - // ART APEX does not exist on host, and under certain build conditions. - if (art_ns) { - linked = app_ns->Link(*art_ns, art_public_libraries()); - if (!linked) { - return linked.error(); - } - } - - // Give access to NNAPI libraries (apex-updated LLNDK library). - auto nnapi_ns = - NativeLoaderNamespace::GetExportedNamespace(kNeuralNetworksNamespaceName, is_bridged); - if (nnapi_ns) { - linked = app_ns->Link(*nnapi_ns, neuralnetworks_public_libraries()); - if (!linked) { - return linked.error(); - } - } - - // Give access to VNDK-SP libraries from the 'vndk' namespace. - if (unbundled_vendor_or_product_app && !vndksp_libraries().empty()) { - auto vndk_ns = NativeLoaderNamespace::GetExportedNamespace(kVndkNamespaceName, is_bridged); - if (vndk_ns) { - linked = app_ns->Link(*vndk_ns, vndksp_libraries()); - if (!linked) { - return linked.error(); - } - } - } - - if (!vendor_public_libraries().empty()) { - auto vendor_ns = NativeLoaderNamespace::GetExportedNamespace(kVendorNamespaceName, is_bridged); - // when vendor_ns is not configured, link to the platform namespace - auto target_ns = vendor_ns ? vendor_ns : platform_ns; - if (target_ns) { - linked = app_ns->Link(*target_ns, vendor_public_libraries()); - if (!linked) { - return linked.error(); - } - } - } - - namespaces_.push_back(std::make_pair(env->NewWeakGlobalRef(class_loader), *app_ns)); - if (is_main_classloader) { - app_main_namespace_ = &(*app_ns); - } - - return &(namespaces_.back().second); -} - -NativeLoaderNamespace* LibraryNamespaces::FindNamespaceByClassLoader(JNIEnv* env, - jobject class_loader) { - auto it = std::find_if(namespaces_.begin(), namespaces_.end(), - [&](const std::pair& value) { - return env->IsSameObject(value.first, class_loader); - }); - if (it != namespaces_.end()) { - return &it->second; - } - - return nullptr; -} - -NativeLoaderNamespace* LibraryNamespaces::FindParentNamespaceByClassLoader(JNIEnv* env, - jobject class_loader) { - jobject parent_class_loader = GetParentClassLoader(env, class_loader); - - while (parent_class_loader != nullptr) { - NativeLoaderNamespace* ns; - if ((ns = FindNamespaceByClassLoader(env, parent_class_loader)) != nullptr) { - return ns; - } - - parent_class_loader = GetParentClassLoader(env, parent_class_loader); - } - - return nullptr; -} - -} // namespace android::nativeloader diff --git a/libnativeloader/library_namespaces.h b/libnativeloader/library_namespaces.h deleted file mode 100644 index 7b3efff4d..000000000 --- a/libnativeloader/library_namespaces.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#if !defined(__ANDROID__) -#error "Not available for host" -#endif - -#define LOG_TAG "nativeloader" - -#include "native_loader_namespace.h" - -#include -#include - -#include -#include - -namespace android::nativeloader { - -using android::base::Result; - -// LibraryNamespaces is a singleton object that manages NativeLoaderNamespace -// objects for an app process. Its main job is to create (and configure) a new -// NativeLoaderNamespace object for a Java ClassLoader, and to find an existing -// object for a given ClassLoader. -class LibraryNamespaces { - public: - LibraryNamespaces() : initialized_(false), app_main_namespace_(nullptr) {} - - LibraryNamespaces(LibraryNamespaces&&) = default; - LibraryNamespaces(const LibraryNamespaces&) = delete; - LibraryNamespaces& operator=(const LibraryNamespaces&) = delete; - - void Initialize(); - void Reset() { - namespaces_.clear(); - initialized_ = false; - app_main_namespace_ = nullptr; - } - Result Create(JNIEnv* env, uint32_t target_sdk_version, - jobject class_loader, bool is_shared, jstring dex_path, - jstring java_library_path, jstring java_permitted_path); - NativeLoaderNamespace* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader); - - private: - Result InitPublicNamespace(const char* library_path); - NativeLoaderNamespace* FindParentNamespaceByClassLoader(JNIEnv* env, jobject class_loader); - - bool initialized_; - NativeLoaderNamespace* app_main_namespace_; - std::list> namespaces_; -}; - -} // namespace android::nativeloader diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp deleted file mode 100644 index 6d3c057b9..000000000 --- a/libnativeloader/native_loader.cpp +++ /dev/null @@ -1,254 +0,0 @@ -/* - * 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. - */ - -#define LOG_TAG "nativeloader" - -#include "nativeloader/native_loader.h" - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifdef __ANDROID__ -#include -#include "library_namespaces.h" -#include "nativeloader/dlext_namespaces.h" -#endif - -namespace android { - -namespace { -#if defined(__ANDROID__) -using android::nativeloader::LibraryNamespaces; - -constexpr const char* kApexPath = "/apex/"; - -std::mutex g_namespaces_mutex; -LibraryNamespaces* g_namespaces = new LibraryNamespaces; - -android_namespace_t* FindExportedNamespace(const char* caller_location) { - std::string location = caller_location; - // Lots of implicit assumptions here: we expect `caller_location` to be of the form: - // /apex/com.android...modulename/... - // - // And we extract from it 'modulename', which is the name of the linker namespace. - if (android::base::StartsWith(location, kApexPath)) { - size_t slash_index = location.find_first_of('/', strlen(kApexPath)); - LOG_ALWAYS_FATAL_IF((slash_index == std::string::npos), - "Error finding namespace of apex: no slash in path %s", caller_location); - size_t dot_index = location.find_last_of('.', slash_index); - LOG_ALWAYS_FATAL_IF((dot_index == std::string::npos), - "Error finding namespace of apex: no dot in apex name %s", caller_location); - std::string name = location.substr(dot_index + 1, slash_index - dot_index - 1); - android_namespace_t* boot_namespace = android_get_exported_namespace(name.c_str()); - LOG_ALWAYS_FATAL_IF((boot_namespace == nullptr), - "Error finding namespace of apex: no namespace called %s", name.c_str()); - return boot_namespace; - } - return nullptr; -} -#endif // #if defined(__ANDROID__) -} // namespace - -void InitializeNativeLoader() { -#if defined(__ANDROID__) - std::lock_guard guard(g_namespaces_mutex); - g_namespaces->Initialize(); -#endif -} - -void ResetNativeLoader() { -#if defined(__ANDROID__) - std::lock_guard guard(g_namespaces_mutex); - g_namespaces->Reset(); -#endif -} - -jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, - bool is_shared, jstring dex_path, jstring library_path, - jstring permitted_path) { -#if defined(__ANDROID__) - std::lock_guard guard(g_namespaces_mutex); - auto ns = g_namespaces->Create(env, target_sdk_version, class_loader, is_shared, dex_path, - library_path, permitted_path); - if (!ns) { - return env->NewStringUTF(ns.error().message().c_str()); - } -#else - UNUSED(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, permitted_path); -#endif - return nullptr; -} - -void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, - jobject class_loader, const char* caller_location, jstring library_path, - bool* needs_native_bridge, char** error_msg) { -#if defined(__ANDROID__) - UNUSED(target_sdk_version); - if (class_loader == nullptr) { - *needs_native_bridge = false; - if (caller_location != nullptr) { - android_namespace_t* boot_namespace = FindExportedNamespace(caller_location); - if (boot_namespace != nullptr) { - const android_dlextinfo dlextinfo = { - .flags = ANDROID_DLEXT_USE_NAMESPACE, - .library_namespace = boot_namespace, - }; - void* handle = android_dlopen_ext(path, RTLD_NOW, &dlextinfo); - if (handle == nullptr) { - *error_msg = strdup(dlerror()); - } - return handle; - } - } - void* handle = dlopen(path, RTLD_NOW); - if (handle == nullptr) { - *error_msg = strdup(dlerror()); - } - return handle; - } - - std::lock_guard guard(g_namespaces_mutex); - NativeLoaderNamespace* ns; - - if ((ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader)) == nullptr) { - // This is the case where the classloader was not created by ApplicationLoaders - // In this case we create an isolated not-shared namespace for it. - Result isolated_ns = - g_namespaces->Create(env, target_sdk_version, class_loader, false /* is_shared */, nullptr, - library_path, nullptr); - if (!isolated_ns) { - *error_msg = strdup(isolated_ns.error().message().c_str()); - return nullptr; - } else { - ns = *isolated_ns; - } - } - - return OpenNativeLibraryInNamespace(ns, path, needs_native_bridge, error_msg); -#else - UNUSED(env, target_sdk_version, class_loader, caller_location); - - // Do some best effort to emulate library-path support. It will not - // work for dependencies. - // - // Note: null has a special meaning and must be preserved. - std::string c_library_path; // Empty string by default. - if (library_path != nullptr && path != nullptr && path[0] != '/') { - ScopedUtfChars library_path_utf_chars(env, library_path); - c_library_path = library_path_utf_chars.c_str(); - } - - std::vector library_paths = base::Split(c_library_path, ":"); - - for (const std::string& lib_path : library_paths) { - *needs_native_bridge = false; - const char* path_arg; - std::string complete_path; - if (path == nullptr) { - // Preserve null. - path_arg = nullptr; - } else { - complete_path = lib_path; - if (!complete_path.empty()) { - complete_path.append("/"); - } - complete_path.append(path); - path_arg = complete_path.c_str(); - } - void* handle = dlopen(path_arg, RTLD_NOW); - if (handle != nullptr) { - return handle; - } - if (NativeBridgeIsSupported(path_arg)) { - *needs_native_bridge = true; - handle = NativeBridgeLoadLibrary(path_arg, RTLD_NOW); - if (handle != nullptr) { - return handle; - } - *error_msg = strdup(NativeBridgeGetError()); - } else { - *error_msg = strdup(dlerror()); - } - } - return nullptr; -#endif -} - -bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) { - bool success; - if (needs_native_bridge) { - success = (NativeBridgeUnloadLibrary(handle) == 0); - if (!success) { - *error_msg = strdup(NativeBridgeGetError()); - } - } else { - success = (dlclose(handle) == 0); - if (!success) { - *error_msg = strdup(dlerror()); - } - } - - return success; -} - -void NativeLoaderFreeErrorMessage(char* msg) { - // The error messages get allocated through strdup, so we must call free on them. - free(msg); -} - -#if defined(__ANDROID__) -void* OpenNativeLibraryInNamespace(NativeLoaderNamespace* ns, const char* path, - bool* needs_native_bridge, char** error_msg) { - auto handle = ns->Load(path); - if (!handle && error_msg != nullptr) { - *error_msg = strdup(handle.error().message().c_str()); - } - if (needs_native_bridge != nullptr) { - *needs_native_bridge = ns->IsBridged(); - } - return handle ? *handle : nullptr; -} - -// native_bridge_namespaces are not supported for callers of this function. -// This function will return nullptr in the case when application is running -// on native bridge. -android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { - std::lock_guard guard(g_namespaces_mutex); - NativeLoaderNamespace* ns = g_namespaces->FindNamespaceByClassLoader(env, class_loader); - if (ns != nullptr && !ns->IsBridged()) { - return ns->ToRawAndroidNamespace(); - } - return nullptr; -} - -NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { - std::lock_guard guard(g_namespaces_mutex); - return g_namespaces->FindNamespaceByClassLoader(env, class_loader); -} -#endif - -}; // namespace android diff --git a/libnativeloader/native_loader_lazy.cpp b/libnativeloader/native_loader_lazy.cpp deleted file mode 100644 index 2eb120379..000000000 --- a/libnativeloader/native_loader_lazy.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "nativeloader/native_loader.h" -#define LOG_TAG "nativeloader" - -#include -#include -#include - -#include - -namespace android { - -namespace { - -void* GetLibHandle() { - static void* handle = dlopen("libnativeloader.so", RTLD_NOW); - LOG_FATAL_IF(handle == nullptr, "Failed to load libnativeloader.so: %s", dlerror()); - return handle; -} - -template -FuncPtr GetFuncPtr(const char* function_name) { - auto f = reinterpret_cast(dlsym(GetLibHandle(), function_name)); - LOG_FATAL_IF(f == nullptr, "Failed to get address of %s: %s", function_name, dlerror()); - return f; -} - -#define GET_FUNC_PTR(name) GetFuncPtr(#name) - -} // namespace - -void InitializeNativeLoader() { - static auto f = GET_FUNC_PTR(InitializeNativeLoader); - return f(); -} - -jstring CreateClassLoaderNamespace(JNIEnv* env, int32_t target_sdk_version, jobject class_loader, - bool is_shared, jstring dex_path, jstring library_path, - jstring permitted_path) { - static auto f = GET_FUNC_PTR(CreateClassLoaderNamespace); - return f(env, target_sdk_version, class_loader, is_shared, dex_path, library_path, - permitted_path); -} - -void* OpenNativeLibrary(JNIEnv* env, int32_t target_sdk_version, const char* path, - jobject class_loader, const char* caller_location, jstring library_path, - bool* needs_native_bridge, char** error_msg) { - static auto f = GET_FUNC_PTR(OpenNativeLibrary); - return f(env, target_sdk_version, path, class_loader, caller_location, library_path, - needs_native_bridge, error_msg); -} - -bool CloseNativeLibrary(void* handle, const bool needs_native_bridge, char** error_msg) { - static auto f = GET_FUNC_PTR(CloseNativeLibrary); - return f(handle, needs_native_bridge, error_msg); -} - -void NativeLoaderFreeErrorMessage(char* msg) { - static auto f = GET_FUNC_PTR(NativeLoaderFreeErrorMessage); - return f(msg); -} - -struct android_namespace_t* FindNamespaceByClassLoader(JNIEnv* env, jobject class_loader) { - static auto f = GET_FUNC_PTR(FindNamespaceByClassLoader); - return f(env, class_loader); -} - -struct NativeLoaderNamespace* FindNativeLoaderNamespaceByClassLoader(JNIEnv* env, - jobject class_loader) { - static auto f = GET_FUNC_PTR(FindNativeLoaderNamespaceByClassLoader); - return f(env, class_loader); -} - -void* OpenNativeLibraryInNamespace(struct NativeLoaderNamespace* ns, const char* path, - bool* needs_native_bridge, char** error_msg) { - static auto f = GET_FUNC_PTR(OpenNativeLibraryInNamespace); - return f(ns, path, needs_native_bridge, error_msg); -} - -void ResetNativeLoader() { - static auto f = GET_FUNC_PTR(ResetNativeLoader); - return f(); -} - -#undef GET_FUNC_PTR - -} // namespace android diff --git a/libnativeloader/native_loader_namespace.cpp b/libnativeloader/native_loader_namespace.cpp deleted file mode 100644 index a81fddf0f..000000000 --- a/libnativeloader/native_loader_namespace.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "nativeloader" - -#include "native_loader_namespace.h" - -#include - -#include - -#include -#include -#include - -#include "nativeloader/dlext_namespaces.h" - -using android::base::Error; -using android::base::Errorf; - -namespace android { - -namespace { - -constexpr const char* kDefaultNamespaceName = "default"; -constexpr const char* kPlatformNamespaceName = "platform"; - -std::string GetLinkerError(bool is_bridged) { - const char* msg = is_bridged ? NativeBridgeGetError() : dlerror(); - if (msg == nullptr) { - return "no error"; - } - return std::string(msg); -} - -} // namespace - -Result NativeLoaderNamespace::GetExportedNamespace(const std::string& name, - bool is_bridged) { - if (!is_bridged) { - auto raw = android_get_exported_namespace(name.c_str()); - if (raw != nullptr) { - return NativeLoaderNamespace(name, raw); - } - } else { - auto raw = NativeBridgeGetExportedNamespace(name.c_str()); - if (raw != nullptr) { - return NativeLoaderNamespace(name, raw); - } - } - return Errorf("namespace {} does not exist or exported", name); -} - -// The platform namespace is called "default" for binaries in /system and -// "platform" for those in the Runtime APEX. Try "platform" first since -// "default" always exists. -Result NativeLoaderNamespace::GetPlatformNamespace(bool is_bridged) { - auto ns = GetExportedNamespace(kPlatformNamespaceName, is_bridged); - if (ns) return ns; - ns = GetExportedNamespace(kDefaultNamespaceName, is_bridged); - if (ns) return ns; - - // If nothing is found, return NativeLoaderNamespace constructed from nullptr. - // nullptr also means default namespace to the linker. - if (!is_bridged) { - return NativeLoaderNamespace(kDefaultNamespaceName, static_cast(nullptr)); - } else { - return NativeLoaderNamespace(kDefaultNamespaceName, - static_cast(nullptr)); - } -} - -Result NativeLoaderNamespace::Create( - const std::string& name, const std::string& search_paths, const std::string& permitted_paths, - const NativeLoaderNamespace* parent, bool is_shared, bool is_greylist_enabled, - bool also_used_as_anonymous) { - bool is_bridged = false; - if (parent != nullptr) { - is_bridged = parent->IsBridged(); - } else if (!search_paths.empty()) { - is_bridged = NativeBridgeIsPathSupported(search_paths.c_str()); - } - - // Fall back to the platform namespace if no parent is set. - auto platform_ns = GetPlatformNamespace(is_bridged); - if (!platform_ns) { - return platform_ns.error(); - } - const NativeLoaderNamespace& effective_parent = parent != nullptr ? *parent : *platform_ns; - - // All namespaces for apps are isolated - uint64_t type = ANDROID_NAMESPACE_TYPE_ISOLATED; - - // The namespace is also used as the anonymous namespace - // which is used when the linker fails to determine the caller address - if (also_used_as_anonymous) { - type |= ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS; - } - - // Bundled apps have access to all system libraries that are currently loaded - // in the default namespace - if (is_shared) { - type |= ANDROID_NAMESPACE_TYPE_SHARED; - } - if (is_greylist_enabled) { - type |= ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED; - } - - if (!is_bridged) { - android_namespace_t* raw = - android_create_namespace(name.c_str(), nullptr, search_paths.c_str(), type, - permitted_paths.c_str(), effective_parent.ToRawAndroidNamespace()); - if (raw != nullptr) { - return NativeLoaderNamespace(name, raw); - } - } else { - native_bridge_namespace_t* raw = NativeBridgeCreateNamespace( - name.c_str(), nullptr, search_paths.c_str(), type, permitted_paths.c_str(), - effective_parent.ToRawNativeBridgeNamespace()); - if (raw != nullptr) { - return NativeLoaderNamespace(name, raw); - } - } - return Errorf("failed to create {} namespace name:{}, search_paths:{}, permitted_paths:{}", - is_bridged ? "bridged" : "native", name, search_paths, permitted_paths); -} - -Result NativeLoaderNamespace::Link(const NativeLoaderNamespace& target, - const std::string& shared_libs) const { - LOG_ALWAYS_FATAL_IF(shared_libs.empty(), "empty share lib when linking %s to %s", - this->name().c_str(), target.name().c_str()); - if (!IsBridged()) { - if (android_link_namespaces(this->ToRawAndroidNamespace(), target.ToRawAndroidNamespace(), - shared_libs.c_str())) { - return {}; - } - } else { - if (NativeBridgeLinkNamespaces(this->ToRawNativeBridgeNamespace(), - target.ToRawNativeBridgeNamespace(), shared_libs.c_str())) { - return {}; - } - } - return Error() << GetLinkerError(IsBridged()); -} - -Result NativeLoaderNamespace::Load(const char* lib_name) const { - if (!IsBridged()) { - android_dlextinfo extinfo; - extinfo.flags = ANDROID_DLEXT_USE_NAMESPACE; - extinfo.library_namespace = this->ToRawAndroidNamespace(); - void* handle = android_dlopen_ext(lib_name, RTLD_NOW, &extinfo); - if (handle != nullptr) { - return handle; - } - } else { - void* handle = - NativeBridgeLoadLibraryExt(lib_name, RTLD_NOW, this->ToRawNativeBridgeNamespace()); - if (handle != nullptr) { - return handle; - } - } - return Error() << GetLinkerError(IsBridged()); -} - -} // namespace android diff --git a/libnativeloader/native_loader_namespace.h b/libnativeloader/native_loader_namespace.h deleted file mode 100644 index 7200ee796..000000000 --- a/libnativeloader/native_loader_namespace.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#if defined(__ANDROID__) - -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace android { - -using android::base::Result; - -// NativeLoaderNamespace abstracts a linker namespace for the native -// architecture (ex: arm on arm) or the translated architecture (ex: arm on -// x86). Instances of this class are managed by LibraryNamespaces object. -struct NativeLoaderNamespace { - public: - static Result Create(const std::string& name, - const std::string& search_paths, - const std::string& permitted_paths, - const NativeLoaderNamespace* parent, bool is_shared, - bool is_greylist_enabled, - bool also_used_as_anonymous); - - NativeLoaderNamespace(NativeLoaderNamespace&&) = default; - NativeLoaderNamespace(const NativeLoaderNamespace&) = default; - NativeLoaderNamespace& operator=(const NativeLoaderNamespace&) = default; - - android_namespace_t* ToRawAndroidNamespace() const { return std::get<0>(raw_); } - native_bridge_namespace_t* ToRawNativeBridgeNamespace() const { return std::get<1>(raw_); } - - std::string name() const { return name_; } - bool IsBridged() const { return raw_.index() == 1; } - - Result Link(const NativeLoaderNamespace& target, const std::string& shared_libs) const; - Result Load(const char* lib_name) const; - - static Result GetExportedNamespace(const std::string& name, - bool is_bridged); - static Result GetPlatformNamespace(bool is_bridged); - - private: - explicit NativeLoaderNamespace(const std::string& name, android_namespace_t* ns) - : name_(name), raw_(ns) {} - explicit NativeLoaderNamespace(const std::string& name, native_bridge_namespace_t* ns) - : name_(name), raw_(ns) {} - - std::string name_; - std::variant raw_; -}; - -} // namespace android -#endif // #if defined(__ANDROID__) diff --git a/libnativeloader/native_loader_test.cpp b/libnativeloader/native_loader_test.cpp deleted file mode 100644 index 8bd7386ee..000000000 --- a/libnativeloader/native_loader_test.cpp +++ /dev/null @@ -1,663 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include "native_loader_namespace.h" -#include "nativeloader/dlext_namespaces.h" -#include "nativeloader/native_loader.h" -#include "public_libraries.h" - -using namespace ::testing; -using namespace ::android::nativeloader::internal; - -namespace android { -namespace nativeloader { - -// gmock interface that represents interested platform APIs on libdl and libnativebridge -class Platform { - public: - virtual ~Platform() {} - - // libdl APIs - virtual void* dlopen(const char* filename, int flags) = 0; - virtual int dlclose(void* handle) = 0; - virtual char* dlerror(void) = 0; - - // These mock_* are the APIs semantically the same across libdl and libnativebridge. - // Instead of having two set of mock APIs for the two, define only one set with an additional - // argument 'bool bridged' to identify the context (i.e., called for libdl or libnativebridge). - typedef char* mock_namespace_handle; - virtual bool mock_init_anonymous_namespace(bool bridged, const char* sonames, - const char* search_paths) = 0; - virtual mock_namespace_handle mock_create_namespace( - bool bridged, const char* name, const char* ld_library_path, const char* default_library_path, - uint64_t type, const char* permitted_when_isolated_path, mock_namespace_handle parent) = 0; - virtual bool mock_link_namespaces(bool bridged, mock_namespace_handle from, - mock_namespace_handle to, const char* sonames) = 0; - virtual mock_namespace_handle mock_get_exported_namespace(bool bridged, const char* name) = 0; - virtual void* mock_dlopen_ext(bool bridged, const char* filename, int flags, - mock_namespace_handle ns) = 0; - - // libnativebridge APIs for which libdl has no corresponding APIs - virtual bool NativeBridgeInitialized() = 0; - virtual const char* NativeBridgeGetError() = 0; - virtual bool NativeBridgeIsPathSupported(const char*) = 0; - virtual bool NativeBridgeIsSupported(const char*) = 0; - - // To mock "ClassLoader Object.getParent()" - virtual const char* JniObject_getParent(const char*) = 0; -}; - -// The mock does not actually create a namespace object. But simply casts the pointer to the -// string for the namespace name as the handle to the namespace object. -#define TO_ANDROID_NAMESPACE(str) \ - reinterpret_cast(const_cast(str)) - -#define TO_BRIDGED_NAMESPACE(str) \ - reinterpret_cast(const_cast(str)) - -#define TO_MOCK_NAMESPACE(ns) reinterpret_cast(ns) - -// These represents built-in namespaces created by the linker according to ld.config.txt -static std::unordered_map namespaces = { - {"platform", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("platform"))}, - {"default", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("default"))}, - {"art", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("art"))}, - {"sphal", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("sphal"))}, - {"vndk", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("vndk"))}, - {"neuralnetworks", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("neuralnetworks"))}, -}; - -// The actual gmock object -class MockPlatform : public Platform { - public: - explicit MockPlatform(bool is_bridged) : is_bridged_(is_bridged) { - ON_CALL(*this, NativeBridgeIsSupported(_)).WillByDefault(Return(is_bridged_)); - ON_CALL(*this, NativeBridgeIsPathSupported(_)).WillByDefault(Return(is_bridged_)); - ON_CALL(*this, mock_get_exported_namespace(_, _)) - .WillByDefault(Invoke([](bool, const char* name) -> mock_namespace_handle { - if (namespaces.find(name) != namespaces.end()) { - return namespaces[name]; - } - return TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("(namespace not found")); - })); - } - - // Mocking libdl APIs - MOCK_METHOD2(dlopen, void*(const char*, int)); - MOCK_METHOD1(dlclose, int(void*)); - MOCK_METHOD0(dlerror, char*()); - - // Mocking the common APIs - MOCK_METHOD3(mock_init_anonymous_namespace, bool(bool, const char*, const char*)); - MOCK_METHOD7(mock_create_namespace, - mock_namespace_handle(bool, const char*, const char*, const char*, uint64_t, - const char*, mock_namespace_handle)); - MOCK_METHOD4(mock_link_namespaces, - bool(bool, mock_namespace_handle, mock_namespace_handle, const char*)); - MOCK_METHOD2(mock_get_exported_namespace, mock_namespace_handle(bool, const char*)); - MOCK_METHOD4(mock_dlopen_ext, void*(bool, const char*, int, mock_namespace_handle)); - - // Mocking libnativebridge APIs - MOCK_METHOD0(NativeBridgeInitialized, bool()); - MOCK_METHOD0(NativeBridgeGetError, const char*()); - MOCK_METHOD1(NativeBridgeIsPathSupported, bool(const char*)); - MOCK_METHOD1(NativeBridgeIsSupported, bool(const char*)); - - // Mocking "ClassLoader Object.getParent()" - MOCK_METHOD1(JniObject_getParent, const char*(const char*)); - - private: - bool is_bridged_; -}; - -static std::unique_ptr mock; - -// Provide C wrappers for the mock object. -extern "C" { -void* dlopen(const char* file, int flag) { - return mock->dlopen(file, flag); -} - -int dlclose(void* handle) { - return mock->dlclose(handle); -} - -char* dlerror(void) { - return mock->dlerror(); -} - -bool android_init_anonymous_namespace(const char* sonames, const char* search_path) { - return mock->mock_init_anonymous_namespace(false, sonames, search_path); -} - -struct android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path, - const char* default_library_path, - uint64_t type, - const char* permitted_when_isolated_path, - struct android_namespace_t* parent) { - return TO_ANDROID_NAMESPACE( - mock->mock_create_namespace(false, name, ld_library_path, default_library_path, type, - permitted_when_isolated_path, TO_MOCK_NAMESPACE(parent))); -} - -bool android_link_namespaces(struct android_namespace_t* from, struct android_namespace_t* to, - const char* sonames) { - return mock->mock_link_namespaces(false, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames); -} - -struct android_namespace_t* android_get_exported_namespace(const char* name) { - return TO_ANDROID_NAMESPACE(mock->mock_get_exported_namespace(false, name)); -} - -void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* info) { - return mock->mock_dlopen_ext(false, filename, flags, TO_MOCK_NAMESPACE(info->library_namespace)); -} - -// libnativebridge APIs -bool NativeBridgeIsSupported(const char* libpath) { - return mock->NativeBridgeIsSupported(libpath); -} - -struct native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name) { - return TO_BRIDGED_NAMESPACE(mock->mock_get_exported_namespace(true, name)); -} - -struct native_bridge_namespace_t* NativeBridgeCreateNamespace( - const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type, - const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent) { - return TO_BRIDGED_NAMESPACE( - mock->mock_create_namespace(true, name, ld_library_path, default_library_path, type, - permitted_when_isolated_path, TO_MOCK_NAMESPACE(parent))); -} - -bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from, - struct native_bridge_namespace_t* to, const char* sonames) { - return mock->mock_link_namespaces(true, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames); -} - -void* NativeBridgeLoadLibraryExt(const char* libpath, int flag, - struct native_bridge_namespace_t* ns) { - return mock->mock_dlopen_ext(true, libpath, flag, TO_MOCK_NAMESPACE(ns)); -} - -bool NativeBridgeInitialized() { - return mock->NativeBridgeInitialized(); -} - -bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames, - const char* anon_ns_library_path) { - return mock->mock_init_anonymous_namespace(true, public_ns_sonames, anon_ns_library_path); -} - -const char* NativeBridgeGetError() { - return mock->NativeBridgeGetError(); -} - -bool NativeBridgeIsPathSupported(const char* path) { - return mock->NativeBridgeIsPathSupported(path); -} - -} // extern "C" - -// A very simple JNI mock. -// jstring is a pointer to utf8 char array. We don't need utf16 char here. -// jobject, jclass, and jmethodID are also a pointer to utf8 char array -// Only a few JNI methods that are actually used in libnativeloader are mocked. -JNINativeInterface* CreateJNINativeInterface() { - JNINativeInterface* inf = new JNINativeInterface(); - memset(inf, 0, sizeof(JNINativeInterface)); - - inf->GetStringUTFChars = [](JNIEnv*, jstring s, jboolean*) -> const char* { - return reinterpret_cast(s); - }; - - inf->ReleaseStringUTFChars = [](JNIEnv*, jstring, const char*) -> void { return; }; - - inf->NewStringUTF = [](JNIEnv*, const char* bytes) -> jstring { - return reinterpret_cast(const_cast(bytes)); - }; - - inf->FindClass = [](JNIEnv*, const char* name) -> jclass { - return reinterpret_cast(const_cast(name)); - }; - - inf->CallObjectMethodV = [](JNIEnv*, jobject obj, jmethodID mid, va_list) -> jobject { - if (strcmp("getParent", reinterpret_cast(mid)) == 0) { - // JniObject_getParent can be a valid jobject or nullptr if there is - // no parent classloader. - const char* ret = mock->JniObject_getParent(reinterpret_cast(obj)); - return reinterpret_cast(const_cast(ret)); - } - return nullptr; - }; - - inf->GetMethodID = [](JNIEnv*, jclass, const char* name, const char*) -> jmethodID { - return reinterpret_cast(const_cast(name)); - }; - - inf->NewWeakGlobalRef = [](JNIEnv*, jobject obj) -> jobject { return obj; }; - - inf->IsSameObject = [](JNIEnv*, jobject a, jobject b) -> jboolean { - return strcmp(reinterpret_cast(a), reinterpret_cast(b)) == 0; - }; - - return inf; -} - -static void* const any_nonnull = reinterpret_cast(0x12345678); - -// Custom matcher for comparing namespace handles -MATCHER_P(NsEq, other, "") { - *result_listener << "comparing " << reinterpret_cast(arg) << " and " << other; - return strcmp(reinterpret_cast(arg), reinterpret_cast(other)) == 0; -} - -///////////////////////////////////////////////////////////////// - -// Test fixture -class NativeLoaderTest : public ::testing::TestWithParam { - protected: - bool IsBridged() { return GetParam(); } - - void SetUp() override { - mock = std::make_unique>(IsBridged()); - - env = std::make_unique(); - env->functions = CreateJNINativeInterface(); - } - - void SetExpectations() { - std::vector default_public_libs = - android::base::Split(preloadable_public_libraries(), ":"); - for (auto l : default_public_libs) { - EXPECT_CALL(*mock, dlopen(StrEq(l.c_str()), RTLD_NOW | RTLD_NODELETE)) - .WillOnce(Return(any_nonnull)); - } - } - - void RunTest() { InitializeNativeLoader(); } - - void TearDown() override { - ResetNativeLoader(); - delete env->functions; - mock.reset(); - } - - std::unique_ptr env; -}; - -///////////////////////////////////////////////////////////////// - -TEST_P(NativeLoaderTest, InitializeLoadsDefaultPublicLibraries) { - SetExpectations(); - RunTest(); -} - -INSTANTIATE_TEST_SUITE_P(NativeLoaderTests, NativeLoaderTest, testing::Bool()); - -///////////////////////////////////////////////////////////////// - -class NativeLoaderTest_Create : public NativeLoaderTest { - protected: - // Test inputs (initialized to the default values). Overriding these - // must be done before calling SetExpectations() and RunTest(). - uint32_t target_sdk_version = 29; - std::string class_loader = "my_classloader"; - bool is_shared = false; - std::string dex_path = "/data/app/foo/classes.dex"; - std::string library_path = "/data/app/foo/lib/arm"; - std::string permitted_path = "/data/app/foo/lib"; - - // expected output (.. for the default test inputs) - std::string expected_namespace_name = "classloader-namespace"; - uint64_t expected_namespace_flags = - ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS; - std::string expected_library_path = library_path; - std::string expected_permitted_path = std::string("/data:/mnt/expand:") + permitted_path; - std::string expected_parent_namespace = "platform"; - bool expected_link_with_platform_ns = true; - bool expected_link_with_art_ns = true; - bool expected_link_with_sphal_ns = !vendor_public_libraries().empty(); - bool expected_link_with_vndk_ns = false; - bool expected_link_with_default_ns = false; - bool expected_link_with_neuralnetworks_ns = true; - std::string expected_shared_libs_to_platform_ns = default_public_libraries(); - std::string expected_shared_libs_to_art_ns = art_public_libraries(); - std::string expected_shared_libs_to_sphal_ns = vendor_public_libraries(); - std::string expected_shared_libs_to_vndk_ns = vndksp_libraries(); - std::string expected_shared_libs_to_default_ns = default_public_libraries(); - std::string expected_shared_libs_to_neuralnetworks_ns = neuralnetworks_public_libraries(); - - void SetExpectations() { - NativeLoaderTest::SetExpectations(); - - ON_CALL(*mock, JniObject_getParent(StrEq(class_loader))).WillByDefault(Return(nullptr)); - - EXPECT_CALL(*mock, NativeBridgeIsPathSupported(_)).Times(AnyNumber()); - EXPECT_CALL(*mock, NativeBridgeInitialized()).Times(AnyNumber()); - - EXPECT_CALL(*mock, mock_create_namespace( - Eq(IsBridged()), StrEq(expected_namespace_name), nullptr, - StrEq(expected_library_path), expected_namespace_flags, - StrEq(expected_permitted_path), NsEq(expected_parent_namespace.c_str()))) - .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(dex_path.c_str())))); - if (expected_link_with_platform_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("platform"), - StrEq(expected_shared_libs_to_platform_ns))) - .WillOnce(Return(true)); - } - if (expected_link_with_art_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("art"), - StrEq(expected_shared_libs_to_art_ns))) - .WillOnce(Return(true)); - } - if (expected_link_with_sphal_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("sphal"), - StrEq(expected_shared_libs_to_sphal_ns))) - .WillOnce(Return(true)); - } - if (expected_link_with_vndk_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("vndk"), - StrEq(expected_shared_libs_to_vndk_ns))) - .WillOnce(Return(true)); - } - if (expected_link_with_default_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("default"), - StrEq(expected_shared_libs_to_default_ns))) - .WillOnce(Return(true)); - } - if (expected_link_with_neuralnetworks_ns) { - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("neuralnetworks"), - StrEq(expected_shared_libs_to_neuralnetworks_ns))) - .WillOnce(Return(true)); - } - } - - void RunTest() { - NativeLoaderTest::RunTest(); - - jstring err = CreateClassLoaderNamespace( - env(), target_sdk_version, env()->NewStringUTF(class_loader.c_str()), is_shared, - env()->NewStringUTF(dex_path.c_str()), env()->NewStringUTF(library_path.c_str()), - env()->NewStringUTF(permitted_path.c_str())); - - // no error - EXPECT_EQ(err, nullptr); - - if (!IsBridged()) { - struct android_namespace_t* ns = - FindNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str())); - - // The created namespace is for this apk - EXPECT_EQ(dex_path.c_str(), reinterpret_cast(ns)); - } else { - struct NativeLoaderNamespace* ns = - FindNativeLoaderNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str())); - - // The created namespace is for the this apk - EXPECT_STREQ(dex_path.c_str(), - reinterpret_cast(ns->ToRawNativeBridgeNamespace())); - } - } - - JNIEnv* env() { return NativeLoaderTest::env.get(); } -}; - -TEST_P(NativeLoaderTest_Create, DownloadedApp) { - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, BundledSystemApp) { - dex_path = "/system/app/foo/foo.apk"; - is_shared = true; - - expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, BundledVendorApp) { - dex_path = "/vendor/app/foo/foo.apk"; - is_shared = true; - - expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, UnbundledVendorApp) { - dex_path = "/vendor/app/foo/foo.apk"; - is_shared = false; - - expected_namespace_name = "vendor-classloader-namespace"; - expected_library_path = expected_library_path + ":/vendor/lib"; - expected_permitted_path = expected_permitted_path + ":/vendor/lib"; - expected_shared_libs_to_platform_ns = - expected_shared_libs_to_platform_ns + ":" + llndk_libraries(); - expected_link_with_vndk_ns = true; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, BundledProductApp_pre30) { - dex_path = "/product/app/foo/foo.apk"; - is_shared = true; - - expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, BundledProductApp_post30) { - dex_path = "/product/app/foo/foo.apk"; - is_shared = true; - target_sdk_version = 30; - - expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, UnbundledProductApp_pre30) { - dex_path = "/product/app/foo/foo.apk"; - is_shared = false; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, UnbundledProductApp_post30) { - dex_path = "/product/app/foo/foo.apk"; - is_shared = false; - target_sdk_version = 30; - - expected_namespace_name = "vendor-classloader-namespace"; - expected_library_path = expected_library_path + ":/product/lib:/system/product/lib"; - expected_permitted_path = expected_permitted_path + ":/product/lib:/system/product/lib"; - expected_shared_libs_to_platform_ns = - expected_shared_libs_to_platform_ns + ":" + llndk_libraries(); - expected_link_with_vndk_ns = true; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, NamespaceForSharedLibIsNotUsedAsAnonymousNamespace) { - if (IsBridged()) { - // There is no shared lib in translated arch - // TODO(jiyong): revisit this - return; - } - // compared to apks, for java shared libs, library_path is empty; java shared - // libs don't have their own native libs. They use platform's. - library_path = ""; - expected_library_path = library_path; - // no ALSO_USED_AS_ANONYMOUS - expected_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED; - SetExpectations(); - RunTest(); -} - -TEST_P(NativeLoaderTest_Create, TwoApks) { - SetExpectations(); - const uint32_t second_app_target_sdk_version = 29; - const std::string second_app_class_loader = "second_app_classloader"; - const bool second_app_is_shared = false; - const std::string second_app_dex_path = "/data/app/bar/classes.dex"; - const std::string second_app_library_path = "/data/app/bar/lib/arm"; - const std::string second_app_permitted_path = "/data/app/bar/lib"; - const std::string expected_second_app_permitted_path = - std::string("/data:/mnt/expand:") + second_app_permitted_path; - const std::string expected_second_app_parent_namespace = "classloader-namespace"; - // no ALSO_USED_AS_ANONYMOUS - const uint64_t expected_second_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED; - - // The scenario is that second app is loaded by the first app. - // So the first app's classloader (`classloader`) is parent of the second - // app's classloader. - ON_CALL(*mock, JniObject_getParent(StrEq(second_app_class_loader))) - .WillByDefault(Return(class_loader.c_str())); - - // namespace for the second app is created. Its parent is set to the namespace - // of the first app. - EXPECT_CALL(*mock, mock_create_namespace( - Eq(IsBridged()), StrEq(expected_namespace_name), nullptr, - StrEq(second_app_library_path), expected_second_namespace_flags, - StrEq(expected_second_app_permitted_path), NsEq(dex_path.c_str()))) - .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(second_app_dex_path.c_str())))); - EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), NsEq(second_app_dex_path.c_str()), _, _)) - .WillRepeatedly(Return(true)); - - RunTest(); - jstring err = CreateClassLoaderNamespace( - env(), second_app_target_sdk_version, env()->NewStringUTF(second_app_class_loader.c_str()), - second_app_is_shared, env()->NewStringUTF(second_app_dex_path.c_str()), - env()->NewStringUTF(second_app_library_path.c_str()), - env()->NewStringUTF(second_app_permitted_path.c_str())); - - // success - EXPECT_EQ(err, nullptr); - - if (!IsBridged()) { - struct android_namespace_t* ns = - FindNamespaceByClassLoader(env(), env()->NewStringUTF(second_app_class_loader.c_str())); - - // The created namespace is for the second apk - EXPECT_EQ(second_app_dex_path.c_str(), reinterpret_cast(ns)); - } else { - struct NativeLoaderNamespace* ns = FindNativeLoaderNamespaceByClassLoader( - env(), env()->NewStringUTF(second_app_class_loader.c_str())); - - // The created namespace is for the second apk - EXPECT_STREQ(second_app_dex_path.c_str(), - reinterpret_cast(ns->ToRawNativeBridgeNamespace())); - } -} - -INSTANTIATE_TEST_SUITE_P(NativeLoaderTests_Create, NativeLoaderTest_Create, testing::Bool()); - -const std::function(const struct ConfigEntry&)> always_true = - [](const struct ConfigEntry&) -> Result { return true; }; - -TEST(NativeLoaderConfigParser, NamesAndComments) { - const char file_content[] = R"( -###### - -libA.so -#libB.so - - - libC.so -libD.so - #### libE.so -)"; - const std::vector expected_result = {"libA.so", "libC.so", "libD.so"}; - Result> result = ParseConfig(file_content, always_true); - ASSERT_TRUE(result) << result.error().message(); - ASSERT_EQ(expected_result, *result); -} - -TEST(NativeLoaderConfigParser, WithBitness) { - const char file_content[] = R"( -libA.so 32 -libB.so 64 -libC.so -)"; -#if defined(__LP64__) - const std::vector expected_result = {"libB.so", "libC.so"}; -#else - const std::vector expected_result = {"libA.so", "libC.so"}; -#endif - Result> result = ParseConfig(file_content, always_true); - ASSERT_TRUE(result) << result.error().message(); - ASSERT_EQ(expected_result, *result); -} - -TEST(NativeLoaderConfigParser, WithNoPreload) { - const char file_content[] = R"( -libA.so nopreload -libB.so nopreload -libC.so -)"; - - const std::vector expected_result = {"libC.so"}; - Result> result = - ParseConfig(file_content, - [](const struct ConfigEntry& entry) -> Result { return !entry.nopreload; }); - ASSERT_TRUE(result) << result.error().message(); - ASSERT_EQ(expected_result, *result); -} - -TEST(NativeLoaderConfigParser, WithNoPreloadAndBitness) { - const char file_content[] = R"( -libA.so nopreload 32 -libB.so 64 nopreload -libC.so 32 -libD.so 64 -libE.so nopreload -)"; - -#if defined(__LP64__) - const std::vector expected_result = {"libD.so"}; -#else - const std::vector expected_result = {"libC.so"}; -#endif - Result> result = - ParseConfig(file_content, - [](const struct ConfigEntry& entry) -> Result { return !entry.nopreload; }); - ASSERT_TRUE(result) << result.error().message(); - ASSERT_EQ(expected_result, *result); -} - -TEST(NativeLoaderConfigParser, RejectMalformed) { - ASSERT_FALSE(ParseConfig("libA.so 32 64", always_true)); - ASSERT_FALSE(ParseConfig("libA.so 32 32", always_true)); - ASSERT_FALSE(ParseConfig("libA.so 32 nopreload 64", always_true)); - ASSERT_FALSE(ParseConfig("32 libA.so nopreload", always_true)); - ASSERT_FALSE(ParseConfig("nopreload libA.so 32", always_true)); - ASSERT_FALSE(ParseConfig("libA.so nopreload # comment", always_true)); -} - -} // namespace nativeloader -} // namespace android diff --git a/libnativeloader/public_libraries.cpp b/libnativeloader/public_libraries.cpp deleted file mode 100644 index 11c30701d..000000000 --- a/libnativeloader/public_libraries.cpp +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "nativeloader" - -#include "public_libraries.h" - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "utils.h" - -namespace android::nativeloader { - -using namespace internal; -using namespace ::std::string_literals; -using android::base::ErrnoError; -using android::base::Errorf; -using android::base::Result; - -namespace { - -constexpr const char* kDefaultPublicLibrariesFile = "/etc/public.libraries.txt"; -constexpr const char* kExtendedPublicLibrariesFilePrefix = "public.libraries-"; -constexpr const char* kExtendedPublicLibrariesFileSuffix = ".txt"; -constexpr const char* kVendorPublicLibrariesFile = "/vendor/etc/public.libraries.txt"; -constexpr const char* kLlndkLibrariesFile = "/system/etc/llndk.libraries.txt"; -constexpr const char* kVndkLibrariesFile = "/system/etc/vndksp.libraries.txt"; - -const std::vector kArtApexPublicLibraries = { - "libicuuc.so", - "libicui18n.so", -}; - -constexpr const char* kArtApexLibPath = "/apex/com.android.art/" LIB; - -constexpr const char* kNeuralNetworksApexPublicLibrary = "libneuralnetworks.so"; - -// TODO(b/130388701): do we need this? -std::string root_dir() { - static const char* android_root_env = getenv("ANDROID_ROOT"); - return android_root_env != nullptr ? android_root_env : "/system"; -} - -bool debuggable() { - static bool debuggable = android::base::GetBoolProperty("ro.debuggable", false); - return debuggable; -} - -std::string vndk_version_str() { - static std::string version = android::base::GetProperty("ro.vndk.version", ""); - if (version != "" && version != "current") { - return "." + version; - } - return ""; -} - -// For debuggable platform builds use ANDROID_ADDITIONAL_PUBLIC_LIBRARIES environment -// variable to add libraries to the list. This is intended for platform tests only. -std::string additional_public_libraries() { - if (debuggable()) { - const char* val = getenv("ANDROID_ADDITIONAL_PUBLIC_LIBRARIES"); - return val ? val : ""; - } - return ""; -} - -void InsertVndkVersionStr(std::string* file_name) { - CHECK(file_name != nullptr); - size_t insert_pos = file_name->find_last_of("."); - if (insert_pos == std::string::npos) { - insert_pos = file_name->length(); - } - file_name->insert(insert_pos, vndk_version_str()); -} - -const std::function(const struct ConfigEntry&)> always_true = - [](const struct ConfigEntry&) -> Result { return true; }; - -Result> ReadConfig( - const std::string& configFile, - const std::function(const ConfigEntry& /* entry */)>& filter_fn) { - std::string file_content; - if (!base::ReadFileToString(configFile, &file_content)) { - return ErrnoError(); - } - Result> result = ParseConfig(file_content, filter_fn); - if (!result) { - return Errorf("Cannot parse {}: {}", configFile, result.error().message()); - } - return result; -} - -void ReadExtensionLibraries(const char* dirname, std::vector* sonames) { - std::unique_ptr dir(opendir(dirname), closedir); - if (dir != nullptr) { - // Failing to opening the dir is not an error, which can happen in - // webview_zygote. - while (struct dirent* ent = readdir(dir.get())) { - if (ent->d_type != DT_REG && ent->d_type != DT_LNK) { - continue; - } - const std::string filename(ent->d_name); - std::string_view fn = filename; - if (android::base::ConsumePrefix(&fn, kExtendedPublicLibrariesFilePrefix) && - android::base::ConsumeSuffix(&fn, kExtendedPublicLibrariesFileSuffix)) { - const std::string company_name(fn); - const std::string config_file_path = dirname + "/"s + filename; - LOG_ALWAYS_FATAL_IF( - company_name.empty(), - "Error extracting company name from public native library list file path \"%s\"", - config_file_path.c_str()); - - auto ret = ReadConfig( - config_file_path, [&company_name](const struct ConfigEntry& entry) -> Result { - if (android::base::StartsWith(entry.soname, "lib") && - android::base::EndsWith(entry.soname, "." + company_name + ".so")) { - return true; - } else { - return Errorf("Library name \"{}\" does not end with the company name {}.", - entry.soname, company_name); - } - }); - if (ret) { - sonames->insert(sonames->end(), ret->begin(), ret->end()); - } else { - LOG_ALWAYS_FATAL("Error reading public native library list from \"%s\": %s", - config_file_path.c_str(), ret.error().message().c_str()); - } - } - } - } -} - -static std::string InitDefaultPublicLibraries(bool for_preload) { - std::string config_file = root_dir() + kDefaultPublicLibrariesFile; - auto sonames = - ReadConfig(config_file, [&for_preload](const struct ConfigEntry& entry) -> Result { - if (for_preload) { - return !entry.nopreload; - } else { - return true; - } - }); - if (!sonames) { - LOG_ALWAYS_FATAL("Error reading public native library list from \"%s\": %s", - config_file.c_str(), sonames.error().message().c_str()); - return ""; - } - - std::string additional_libs = additional_public_libraries(); - if (!additional_libs.empty()) { - auto vec = base::Split(additional_libs, ":"); - std::copy(vec.begin(), vec.end(), std::back_inserter(*sonames)); - } - - // If this is for preloading libs, don't remove the libs from APEXes. - if (for_preload) { - return android::base::Join(*sonames, ':'); - } - - // Remove the public libs in the art namespace. - // These libs are listed in public.android.txt, but we don't want the rest of android - // in default namespace to dlopen the libs. - // For example, libicuuc.so is exposed to classloader namespace from art namespace. - // Unfortunately, it does not have stable C symbols, and default namespace should only use - // stable symbols in libandroidicu.so. http://b/120786417 - for (const std::string& lib_name : kArtApexPublicLibraries) { - std::string path(kArtApexLibPath); - path.append("/").append(lib_name); - - struct stat s; - // Do nothing if the path in /apex does not exist. - // Runtime APEX must be mounted since libnativeloader is in the same APEX - if (stat(path.c_str(), &s) != 0) { - continue; - } - - auto it = std::find(sonames->begin(), sonames->end(), lib_name); - if (it != sonames->end()) { - sonames->erase(it); - } - } - - // Remove the public libs in the nnapi namespace. - auto it = std::find(sonames->begin(), sonames->end(), kNeuralNetworksApexPublicLibrary); - if (it != sonames->end()) { - sonames->erase(it); - } - return android::base::Join(*sonames, ':'); -} - -static std::string InitArtPublicLibraries() { - CHECK(sizeof(kArtApexPublicLibraries) > 0); - std::string list = android::base::Join(kArtApexPublicLibraries, ":"); - - std::string additional_libs = additional_public_libraries(); - if (!additional_libs.empty()) { - list = list + ':' + additional_libs; - } - return list; -} - -static std::string InitVendorPublicLibraries() { - // This file is optional, quietly ignore if the file does not exist. - auto sonames = ReadConfig(kVendorPublicLibrariesFile, always_true); - if (!sonames) { - return ""; - } - return android::base::Join(*sonames, ':'); -} - -// read /system/etc/public.libraries-.txt and -// /product/etc/public.libraries-.txt which contain partner defined -// system libs that are exposed to apps. The libs in the txt files must be -// named as lib..so. -static std::string InitExtendedPublicLibraries() { - std::vector sonames; - ReadExtensionLibraries("/system/etc", &sonames); - ReadExtensionLibraries("/product/etc", &sonames); - return android::base::Join(sonames, ':'); -} - -static std::string InitLlndkLibraries() { - std::string config_file = kLlndkLibrariesFile; - InsertVndkVersionStr(&config_file); - auto sonames = ReadConfig(config_file, always_true); - if (!sonames) { - LOG_ALWAYS_FATAL("%s", sonames.error().message().c_str()); - return ""; - } - return android::base::Join(*sonames, ':'); -} - -static std::string InitVndkspLibraries() { - std::string config_file = kVndkLibrariesFile; - InsertVndkVersionStr(&config_file); - auto sonames = ReadConfig(config_file, always_true); - if (!sonames) { - LOG_ALWAYS_FATAL("%s", sonames.error().message().c_str()); - return ""; - } - return android::base::Join(*sonames, ':'); -} - -static std::string InitNeuralNetworksPublicLibraries() { - return kNeuralNetworksApexPublicLibrary; -} - -} // namespace - -const std::string& preloadable_public_libraries() { - static std::string list = InitDefaultPublicLibraries(/*for_preload*/ true); - return list; -} - -const std::string& default_public_libraries() { - static std::string list = InitDefaultPublicLibraries(/*for_preload*/ false); - return list; -} - -const std::string& art_public_libraries() { - static std::string list = InitArtPublicLibraries(); - return list; -} - -const std::string& vendor_public_libraries() { - static std::string list = InitVendorPublicLibraries(); - return list; -} - -const std::string& extended_public_libraries() { - static std::string list = InitExtendedPublicLibraries(); - return list; -} - -const std::string& neuralnetworks_public_libraries() { - static std::string list = InitNeuralNetworksPublicLibraries(); - return list; -} - -const std::string& llndk_libraries() { - static std::string list = InitLlndkLibraries(); - return list; -} - -const std::string& vndksp_libraries() { - static std::string list = InitVndkspLibraries(); - return list; -} - -namespace internal { -// Exported for testing -Result> ParseConfig( - const std::string& file_content, - const std::function(const ConfigEntry& /* entry */)>& filter_fn) { - std::vector lines = base::Split(file_content, "\n"); - - std::vector sonames; - for (auto& line : lines) { - auto trimmed_line = base::Trim(line); - if (trimmed_line[0] == '#' || trimmed_line.empty()) { - continue; - } - - std::vector tokens = android::base::Split(trimmed_line, " "); - if (tokens.size() < 1 || tokens.size() > 3) { - return Errorf("Malformed line \"{}\"", line); - } - struct ConfigEntry entry = {.soname = "", .nopreload = false, .bitness = ALL}; - size_t i = tokens.size(); - while (i-- > 0) { - if (tokens[i] == "nopreload") { - entry.nopreload = true; - } else if (tokens[i] == "32" || tokens[i] == "64") { - if (entry.bitness != ALL) { - return Errorf("Malformed line \"{}\": bitness can be specified only once", line); - } - entry.bitness = tokens[i] == "32" ? ONLY_32 : ONLY_64; - } else { - if (i != 0) { - return Errorf("Malformed line \"{}\"", line); - } - entry.soname = tokens[i]; - } - } - - // skip 32-bit lib on 64-bit process and vice versa -#if defined(__LP64__) - if (entry.bitness == ONLY_32) continue; -#else - if (entry.bitness == ONLY_64) continue; -#endif - - Result ret = filter_fn(entry); - if (!ret) { - return ret.error(); - } - if (*ret) { - // filter_fn has returned true. - sonames.push_back(entry.soname); - } - } - return sonames; -} - -} // namespace internal - -} // namespace android::nativeloader diff --git a/libnativeloader/public_libraries.h b/libnativeloader/public_libraries.h deleted file mode 100644 index b892e6f69..000000000 --- a/libnativeloader/public_libraries.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#include - -namespace android::nativeloader { - -using android::base::Result; - -// These provide the list of libraries that are available to the namespace for apps. -// Not all of the libraries are available to apps. Depending on the context, -// e.g., if it is a vendor app or not, different set of libraries are made available. -const std::string& preloadable_public_libraries(); -const std::string& default_public_libraries(); -const std::string& art_public_libraries(); -const std::string& vendor_public_libraries(); -const std::string& extended_public_libraries(); -const std::string& neuralnetworks_public_libraries(); -const std::string& llndk_libraries(); -const std::string& vndksp_libraries(); - -// These are exported for testing -namespace internal { - -enum Bitness { ALL = 0, ONLY_32, ONLY_64 }; - -struct ConfigEntry { - std::string soname; - bool nopreload; - Bitness bitness; -}; - -Result> ParseConfig( - const std::string& file_content, - const std::function(const ConfigEntry& /* entry */)>& filter_fn); - -} // namespace internal - -} // namespace android::nativeloader diff --git a/libnativeloader/test/Android.bp b/libnativeloader/test/Android.bp deleted file mode 100644 index 4d5c53dba..000000000 --- a/libnativeloader/test/Android.bp +++ /dev/null @@ -1,82 +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. -// - -cc_library { - name: "libfoo.oem1", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libfoo.oem1.so\""], - shared_libs: [ - "libbase", - ], -} - -cc_library { - name: "libbar.oem1", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libbar.oem1.so\""], - shared_libs: [ - "libbase", - ], -} - -cc_library { - name: "libfoo.oem2", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libfoo.oem2.so\""], - shared_libs: [ - "libbase", - ], -} - -cc_library { - name: "libbar.oem2", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libbar.oem2.so\""], - shared_libs: [ - "libbase", - ], -} - -cc_library { - name: "libfoo.product1", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libfoo.product1.so\""], - product_specific: true, - shared_libs: [ - "libbase", - ], -} - -cc_library { - name: "libbar.product1", - srcs: ["test.cpp"], - cflags: ["-DLIBNAME=\"libbar.product1.so\""], - product_specific: true, - shared_libs: [ - "libbase", - ], -} - -// Build the test for the C API. -cc_test { - name: "libnativeloader-api-tests", - host_supported: true, - test_per_src: true, - srcs: [ - "api_test.c", - ], - header_libs: ["libnativeloader-headers"], -} diff --git a/libnativeloader/test/Android.mk b/libnativeloader/test/Android.mk deleted file mode 100644 index 65e7b09bc..000000000 --- a/libnativeloader/test/Android.mk +++ /dev/null @@ -1,57 +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_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_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_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) -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) -include $(BUILD_PACKAGE) diff --git a/libnativeloader/test/api_test.c b/libnativeloader/test/api_test.c deleted file mode 100644 index e7025fd7a..000000000 --- a/libnativeloader/test/api_test.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* The main purpose of this test is to ensure this C header compiles in C, so - * that no C++ features inadvertently leak into the C ABI. */ -#include "nativeloader/native_loader.h" - -int main(int argc, char** argv) { - (void)argc; - (void)argv; - return 0; -} diff --git a/libnativeloader/test/public.libraries-oem1.txt b/libnativeloader/test/public.libraries-oem1.txt deleted file mode 100644 index f9433e2a0..000000000 --- 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 de6bdb08e..000000000 --- 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 358154c62..000000000 --- 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 40beb5b4d..000000000 --- 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/TestActivity.java b/libnativeloader/test/src/android/test/app/TestActivity.java deleted file mode 100644 index a7a455d33..000000000 --- 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/system/AndroidManifest.xml b/libnativeloader/test/system/AndroidManifest.xml deleted file mode 100644 index c3048891a..000000000 --- a/libnativeloader/test/system/AndroidManifest.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/libnativeloader/test/test.cpp b/libnativeloader/test/test.cpp deleted file mode 100644 index b166928f0..000000000 --- a/libnativeloader/test/test.cpp +++ /dev/null @@ -1,21 +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. - */ -#define LOG_TAG "oemlib" -#include - -static __attribute__((constructor)) void test_lib_init() { - LOG(DEBUG) << LIBNAME << " loaded"; -} diff --git a/libnativeloader/test/vendor/AndroidManifest.xml b/libnativeloader/test/vendor/AndroidManifest.xml deleted file mode 100644 index c4c1a9c21..000000000 --- a/libnativeloader/test/vendor/AndroidManifest.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/libnativeloader/utils.h b/libnativeloader/utils.h deleted file mode 100644 index a1c2be547..000000000 --- a/libnativeloader/utils.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2019 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -namespace android::nativeloader { - -#if defined(__LP64__) -#define LIB "lib64" -#else -#define LIB "lib" -#endif - -} // namespace android::nativeloader