upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
1
android/system/core/libnativebridge/.clang-format
Symbolic link
1
android/system/core/libnativebridge/.clang-format
Symbolic link
|
@ -0,0 +1 @@
|
|||
../.clang-format-2
|
35
android/system/core/libnativebridge/Android.bp
Normal file
35
android/system/core/libnativebridge/Android.bp
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
cc_library_headers {
|
||||
name: "libnativebridge-dummy-headers",
|
||||
|
||||
host_supported: true,
|
||||
export_include_dirs=["include"],
|
||||
}
|
||||
|
||||
cc_library {
|
||||
name: "libnativebridge",
|
||||
|
||||
host_supported: true,
|
||||
srcs: ["native_bridge.cc"],
|
||||
shared_libs: ["liblog"],
|
||||
clang: true,
|
||||
|
||||
export_include_dirs=["include"],
|
||||
|
||||
cflags: [
|
||||
"-Werror",
|
||||
"-Wall",
|
||||
],
|
||||
cppflags: [
|
||||
"-fvisibility=protected",
|
||||
],
|
||||
|
||||
host_ldlibs: ["-ldl"],
|
||||
target: {
|
||||
android: {
|
||||
shared_libs: ["libdl"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
subdirs = ["tests"]
|
3
android/system/core/libnativebridge/Android.mk
Normal file
3
android/system/core/libnativebridge/Android.mk
Normal file
|
@ -0,0 +1,3 @@
|
|||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(LOCAL_PATH)/tests/Android.mk
|
|
@ -0,0 +1,401 @@
|
|||
/*
|
||||
* 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 "jni.h"
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
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 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.
|
||||
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.
|
||||
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);
|
||||
|
||||
// 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(native_bridge_namespace_t* from, 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, native_bridge_namespace_t* ns);
|
||||
|
||||
// Returns vendor namespace if it is enabled for the device and null otherwise
|
||||
native_bridge_namespace_t* NativeBridgeGetVendorNamespace();
|
||||
|
||||
// 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 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.
|
||||
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,
|
||||
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)(native_bridge_namespace_t* from, 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, 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
|
||||
native_bridge_namespace_t* (*getVendorNamespace)();
|
||||
};
|
||||
|
||||
// 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);
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
||||
#endif // NATIVE_BRIDGE_H_
|
645
android/system/core/libnativebridge/native_bridge.cc
Normal file
645
android/system/core/libnativebridge/native_bridge.cc
Normal file
|
@ -0,0 +1,645 @@
|
|||
/*
|
||||
* 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 <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// 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,
|
||||
};
|
||||
|
||||
// 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<NativeBridgeCallbacks*>(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;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__arm__)
|
||||
static const char* kRuntimeISA = "arm";
|
||||
#elif defined(__aarch64__)
|
||||
static const char* kRuntimeISA = "arm64";
|
||||
#elif defined(__mips__) && !defined(__LP64__)
|
||||
static const char* kRuntimeISA = "mips";
|
||||
#elif defined(__mips__) && defined(__LP64__)
|
||||
static const char* kRuntimeISA = "mips64";
|
||||
#elif defined(__i386__)
|
||||
static const char* kRuntimeISA = "x86";
|
||||
#elif defined(__x86_64__)
|
||||
static const char* kRuntimeISA = "x86_64";
|
||||
#else
|
||||
static const char* kRuntimeISA = "unknown";
|
||||
#endif
|
||||
|
||||
|
||||
bool NeedsNativeBridge(const char* instruction_set) {
|
||||
if (instruction_set == nullptr) {
|
||||
ALOGE("Null instruction set in NeedsNativeBridge.");
|
||||
return false;
|
||||
}
|
||||
return strncmp(instruction_set, kRuntimeISA, strlen(kRuntimeISA) + 1) != 0;
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
template<typename T> void UNUSED(const T&) {}
|
||||
#endif
|
||||
|
||||
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}/<isa>/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* NativeBridgeGetVendorNamespace() {
|
||||
if (!NativeBridgeInitialized() || !isCompatibleWith(VENDOR_NAMESPACE_VERSION)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return callbacks->getVendorNamespace();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}; // namespace android
|
54
android/system/core/libnativebridge/tests/Android.bp
Normal file
54
android/system/core/libnativebridge/tests/Android.bp
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// 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-dummy-headers"],
|
||||
cppflags: ["-fvisibility=protected"],
|
||||
target: {
|
||||
android: {
|
||||
shared_libs: ["libdl"],
|
||||
},
|
||||
host: {
|
||||
host_ldlibs: ["-ldl"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
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"],
|
||||
}
|
51
android/system/core/libnativebridge/tests/Android.mk
Normal file
51
android/system/core/libnativebridge/tests/Android.mk
Normal file
|
@ -0,0 +1,51 @@
|
|||
# Build the unit tests.
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# Build the unit tests.
|
||||
test_src_files := \
|
||||
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_libraries := \
|
||||
liblog \
|
||||
libnativebridge \
|
||||
libnativebridge-dummy
|
||||
|
||||
$(foreach file,$(test_src_files), \
|
||||
$(eval include $(CLEAR_VARS)) \
|
||||
$(eval LOCAL_CLANG := true) \
|
||||
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
|
||||
$(eval LOCAL_SRC_FILES := $(file)) \
|
||||
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
|
||||
$(eval include $(BUILD_NATIVE_TEST)) \
|
||||
)
|
||||
|
||||
$(foreach file,$(test_src_files), \
|
||||
$(eval include $(CLEAR_VARS)) \
|
||||
$(eval LOCAL_CLANG := true) \
|
||||
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
|
||||
$(eval LOCAL_SRC_FILES := $(file)) \
|
||||
$(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
|
||||
$(eval include $(BUILD_HOST_NATIVE_TEST)) \
|
||||
)
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "NativeBridgeTest.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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 <signal.h>
|
||||
|
||||
// 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
|
||||
};
|
||||
|
124
android/system/core/libnativebridge/tests/DummyNativeBridge3.cpp
Normal file
124
android/system/core/libnativebridge/tests/DummyNativeBridge3.cpp
Normal file
|
@ -0,0 +1,124 @@
|
|||
/*
|
||||
* 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 <signal.h>
|
||||
|
||||
// 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};
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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 <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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
|
39
android/system/core/libnativebridge/tests/NativeBridgeTest.h
Normal file
39
android/system/core/libnativebridge/tests/NativeBridgeTest.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 <nativebridge/native_bridge.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
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_
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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 <unistd.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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* kISAs[] = { "arm", "arm64", "mips", "mips64", "x86", "x86_64", "random", "64arm",
|
||||
"64_x86", "64_x86_64", "", "reallylongstringabcd", nullptr };
|
||||
|
||||
#if defined(__arm__)
|
||||
static const char* kRuntimeISA = "arm";
|
||||
#elif defined(__aarch64__)
|
||||
static const char* kRuntimeISA = "arm64";
|
||||
#elif defined(__mips__) && !defined(__LP64__)
|
||||
static const char* kRuntimeISA = "mips";
|
||||
#elif defined(__mips__) && defined(__LP64__)
|
||||
static const char* kRuntimeISA = "mips64";
|
||||
#elif defined(__i386__)
|
||||
static const char* kRuntimeISA = "x86";
|
||||
#elif defined(__x86_64__)
|
||||
static const char* kRuntimeISA = "x86_64";
|
||||
#else
|
||||
static const char* kRuntimeISA = "unknown";
|
||||
#endif
|
||||
|
||||
TEST_F(NativeBridgeTest, NeedsNativeBridge) {
|
||||
EXPECT_EQ(false, NeedsNativeBridge(kRuntimeISA));
|
||||
|
||||
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], kRuntimeISA) != 0,
|
||||
NeedsNativeBridge(kISAs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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 <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "NativeBridgeTest.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
TEST_F(NativeBridgeTest, PreInitializeNativeBridgeFail2) {
|
||||
// Needs LoadNativeBridge() first
|
||||
ASSERT_FALSE(PreInitializeNativeBridge(nullptr, "isa"));
|
||||
ASSERT_TRUE(NativeBridgeError());
|
||||
}
|
||||
|
||||
} // namespace android
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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 <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "NativeBridgeTest.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
static constexpr const char* kTestData = "PreInitializeNativeBridge test.";
|
||||
|
||||
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.
|
||||
// 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
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#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
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
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
|
Loading…
Add table
Add a link
Reference in a new issue