0

This is the first patch to separate JNI registration with initialization, currently, we have JNI_OnLoad defined multiple places which has a lot of

duplicated code and JNI registration and initialization are mixed;

This patch
- Added JNIOnLoadDelegate class for each component  specific initialization.
- Added base::android::OnJNIOnLoad() to call a list of delegates
- Migrate testing, content_shell, chrome_shell.

BUG=447393
TBR=thakis

Review URL: https://codereview.chromium.org/864563002

Cr-Commit-Position: refs/heads/master@{#313592}
This commit is contained in:
michaelbai
2015-01-28 13:40:36 -08:00
committed by Commit bot
parent 005229b167
commit 842c972d50
29 changed files with 424 additions and 113 deletions

@ -23,6 +23,8 @@ component("base") {
"allocator/type_profiler_control.h",
"android/application_status_listener.cc",
"android/application_status_listener.h",
"android/base_jni_onload.cc",
"android/base_jni_onload.h",
"android/base_jni_registrar.cc",
"android/base_jni_registrar.h",
"android/build_info.cc",
@ -46,6 +48,7 @@ component("base") {
"android/jni_android.h",
"android/jni_array.cc",
"android/jni_array.h",
"android/jni_onload_delegate.h",
"android/jni_registrar.cc",
"android/jni_registrar.h",
"android/jni_string.cc",

@ -0,0 +1,64 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/base_jni_onload.h"
#include "base/android/jni_android.h"
#include "base/android/jni_onload_delegate.h"
#include "base/android/library_loader/library_loader_hooks.h"
namespace base {
namespace android {
namespace {
// The JNIOnLoadDelegate implementation in base.
class BaseJNIOnLoadDelegate : public JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
bool BaseJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
return RegisterLibraryLoaderEntryHook(env);
}
bool BaseJNIOnLoadDelegate::Init() {
return true;
}
} // namespace
bool OnJNIOnLoad(JavaVM* vm,
std::vector<JNIOnLoadDelegate*>* delegates) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
BaseJNIOnLoadDelegate delegate;
delegates->push_back(&delegate);
bool ret = true;
for (std::vector<JNIOnLoadDelegate*>::reverse_iterator i =
delegates->rbegin(); i != delegates->rend(); ++i) {
if (!(*i)->RegisterJNI(env)) {
ret = false;
break;
}
}
if (ret) {
for (std::vector<JNIOnLoadDelegate*>::reverse_iterator i =
delegates->rbegin(); i != delegates->rend(); ++i) {
if (!(*i)->Init()) {
ret = false;
break;
}
}
}
delegates->pop_back();
return ret;
}
} // namespace android
} // namespace base

@ -0,0 +1,27 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_ANDROID_BASE_JNI_ONLOAD_H_
#define BASE_ANDROID_BASE_JNI_ONLOAD_H_
#include <jni.h>
#include <vector>
#include "base/base_export.h"
namespace base {
namespace android {
class JNIOnLoadDelegate;
// Returns whether JNI registration and initialization succeeded. Caller shall
// put the JNIOnLoadDelegate into |delegates| in reverse order. Refer
// JNIOnLoadDelegate for more information.
BASE_EXPORT bool OnJNIOnLoad(JavaVM* vm,
std::vector<JNIOnLoadDelegate*>* delegates);
} // namespace android
} // namespace base
#endif // BASE_ANDROID_BASE_JNI_ONLOAD_H_

@ -0,0 +1,41 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_ANDROID_JNI_ONLOAD_DELEGATE_H_
#define BASE_ANDROID_JNI_ONLOAD_DELEGATE_H_
#include <jni.h>
#include "base/base_export.h"
namespace base {
namespace android {
// This delegate class is used to implement component specific JNI registration
// and initialization. All methods are called in JNI_OnLoad().
//
// Both RegisterJNI() and Init() methods are called if the shared library
// is loaded by crazy linker that can't find JNI methods without JNI
// registration, otherwise, only Init() is invoked where dynamic lookup is
// used to find the JNI methods.
//
// It is important to make sure the JNI registration code is only in
// RegisterJNI(), so it could be stripped out when JNI registration isn't
// needed.
class BASE_EXPORT JNIOnLoadDelegate {
public:
virtual ~JNIOnLoadDelegate() {}
// Returns whether the JNI registration succeeded.
virtual bool RegisterJNI(JNIEnv* env) = 0;
// Returns whether the initialization succeeded. This method is called after
// RegisterJNI(), all JNI methods shall ready to be used.
virtual bool Init() = 0;
};
} // namespace android
} // namespace base
#endif // BASE_ANDROID_JNI_ONLOAD_DELEGATE_H_

@ -28,6 +28,8 @@
'allocator/type_profiler_control.h',
'android/application_status_listener.cc',
'android/application_status_listener.h',
'android/base_jni_onload.cc',
'android/base_jni_onload.h',
'android/base_jni_registrar.cc',
'android/base_jni_registrar.h',
'android/build_info.cc',
@ -53,6 +55,7 @@
'android/jni_android.h',
'android/jni_array.cc',
'android/jni_array.h',
'android/jni_onload_delegate.h',
'android/jni_registrar.cc',
'android/jni_registrar.h',
'android/jni_string.cc',

@ -582,6 +582,7 @@ if (is_android) {
sources = [
"app/android/chrome_android_initializer.cc",
"app/android/chrome_android_initializer.h",
"app/android/chrome_jni_onload.cc",
"app/android/chrome_main_delegate_android.cc",
"app/android/chrome_main_delegate_android.h",
"app/chrome_main_delegate.cc",

@ -187,9 +187,6 @@ group("chrome_shell_base") {
shared_library("chrome_shell") {
testonly = true
sources = [
# This file must always be included in the shared_library step to ensure
# JNI_OnLoad is exported.
"//chrome/app/android/chrome_jni_onload.cc",
"shell/chrome_main_delegate_chrome_shell_android.cc",
"shell/chrome_main_delegate_chrome_shell_android.h",
]
@ -210,9 +207,6 @@ shared_library("chrome_shell") {
shared_library("chrome_sync_shell") {
testonly = true
sources = [
# This file must always be included in the shared_library step to ensure
# JNI_OnLoad is exported.
#"//chrome/app/android/chrome_jni_onload.cc",
#"sync_shell/chrome_main_delegate_chrome_sync_shell_android.cc",
#"sync_shell/chrome_main_delegate_chrome_sync_shell_android.h",
]

@ -4,28 +4,17 @@
#include "chrome/app/android/chrome_android_initializer.h"
#include "base/android/jni_android.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/logging.h"
#include "chrome/app/android/chrome_main_delegate_android.h"
#include "chrome/common/chrome_version_info.h"
#include "content/public/app/android_library_loader_hooks.h"
#include "content/public/app/content_main.h"
jint RunChrome(JavaVM* vm, ChromeMainDelegateAndroid* main_delegate) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
if (!base::android::RegisterLibraryLoaderEntryHook(env))
return -1;
bool RunChrome() {
// Pass the library version number to content so that we can check it from the
// Java side before continuing initialization
chrome::VersionInfo vi;
base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
base::android::SetVersionNumber(vi.Version().c_str());
content::SetContentMainDelegate(ChromeMainDelegateAndroid::Create());
DCHECK(main_delegate);
content::SetContentMainDelegate(main_delegate);
return JNI_VERSION_1_4;
return true;
}

@ -5,10 +5,6 @@
#ifndef CHROME_APP_ANDROID_CHROME_ANDROID_INITIALIZER_H_
#define CHROME_APP_ANDROID_CHROME_ANDROID_INITIALIZER_H_
#include <jni.h>
class ChromeMainDelegateAndroid;
jint RunChrome(JavaVM* vm, ChromeMainDelegateAndroid* main_delegate);
bool RunChrome();
#endif // CHROME_APP_ANDROID_CHROME_ANDROID_INITIALIZER_H_

@ -2,16 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/jni_android.h"
#include "base/android/jni_onload_delegate.h"
#include "chrome/app/android/chrome_android_initializer.h"
#include "chrome/app/android/chrome_main_delegate_android.h"
#include "content/public/app/content_jni_onload.h"
namespace {
class ChromeJNIOnLoadDelegate : public base::android::JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
bool ChromeJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
return true;
}
bool ChromeJNIOnLoadDelegate::Init() {
// TODO(michaelbai): Move the JNI registration from RunChrome() to
// RegisterJNI().
return RunChrome();
}
} // namespace
// This is called by the VM when the shared library is first loaded.
// Note that this file must be included in the final shared_library build step
// and not in a static library or the JNI_OnLoad symbol won't be included
// because the Android build is compiled with exclude-libs=ALL to reduce symbol
// size.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
return RunChrome(vm, ChromeMainDelegateAndroid::Create());
ChromeJNIOnLoadDelegate delegate;
if (!content::android::OnJNIOnLoad(vm, &delegate))
return -1;
return JNI_VERSION_1_4;
}

@ -40,6 +40,7 @@
'sources': [
'app/android/chrome_android_initializer.cc',
'app/android/chrome_android_initializer.h',
'app/android/chrome_jni_onload.cc',
'app/android/chrome_main_delegate_android.cc',
'app/android/chrome_main_delegate_android.h',
'app/chrome_main_delegate.cc',

@ -48,9 +48,6 @@
'target_name': 'libchromeshell',
'type': 'shared_library',
'sources': [
# This file must always be included in the shared_library step to ensure
# JNI_OnLoad is exported.
'app/android/chrome_jni_onload.cc',
'android/shell/chrome_main_delegate_chrome_shell_android.cc',
'android/shell/chrome_main_delegate_chrome_shell_android.h',
],
@ -68,9 +65,6 @@
'target_name': 'libchromesyncshell',
'type': 'shared_library',
'sources': [
# This file must always be included in the shared_library step to ensure
# JNI_OnLoad is exported.
'app/android/chrome_jni_onload.cc',
'android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.cc',
'android/sync_shell/chrome_main_delegate_chrome_sync_shell_android.h',
],

@ -10,6 +10,7 @@ content_app_sources = [
"android/app_jni_registrar.h",
"android/child_process_service.cc",
"android/child_process_service.h",
"android/content_jni_onload.cc",
"android/content_main.cc",
"android/content_main.h",
"android/library_loader_hooks.cc",

@ -0,0 +1,52 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/app/content_jni_onload.h"
#include <vector>
#include "base/android/base_jni_onload.h"
#include "base/android/jni_onload_delegate.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "content/public/app/android_library_loader_hooks.h"
#include "content/public/app/content_main.h"
namespace content {
namespace android {
namespace {
class ContentJNIOnLoadDelegate
: public base::android::JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
bool ContentJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
// TODO(michaelbai): Remove the EnsureJniRegistered from
// content::LibraryLoaded and move android_library_loader_hooks.h to
// content/app/android/.
return content::EnsureJniRegistered(env);
}
bool ContentJNIOnLoadDelegate::Init() {
base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
return true;
}
} // namespace
bool OnJNIOnLoad(JavaVM* vm,
base::android::JNIOnLoadDelegate* delegate) {
std::vector<base::android::JNIOnLoadDelegate*> delegates;
ContentJNIOnLoadDelegate content_delegate;
delegates.push_back(delegate);
delegates.push_back(&content_delegate);
return base::android::OnJNIOnLoad(vm, &delegates);
}
} // namespace android
} // namespace content

@ -22,6 +22,7 @@
'app/android/app_jni_registrar.h',
'app/android/child_process_service.cc',
'app/android/child_process_service.h',
'app/android/content_jni_onload.cc',
'app/android/content_main.cc',
'app/android/content_main.h',
'app/android/library_loader_hooks.cc',
@ -30,6 +31,7 @@
'app/mojo/mojo_init.cc',
'app/mojo/mojo_init.h',
'public/app/android_library_loader_hooks.h',
'public/app/content_jni_onload.h',
'public/app/content_main.h',
'public/app/content_main_delegate.cc',
'public/app/content_main_delegate.h',

@ -1016,7 +1016,6 @@
],
'sources': [
'shell/android/shell_library_loader.cc',
'shell/android/shell_library_loader.h',
],
'conditions': [
['android_webview_build==1', {

@ -264,6 +264,8 @@
'browser/accessibility/android_granularity_movement_browsertest.cc',
'browser/accessibility/android_hit_testing_browsertest.cc',
'shell/android/browsertests_apk/content_browser_tests_android.cc',
'shell/android/browsertests_apk/content_browser_tests_android.h',
'shell/android/browsertests_apk/content_browser_tests_jni_onload.cc',
],
'content_browsertests_webrtc_sources': [
'browser/media/webrtc_aecdump_browsertest.cc',

@ -22,6 +22,7 @@
public_app_shared_sources = [
"android_library_loader_hooks.h",
"content_jni_onload.h",
"content_main.h",
"content_main_delegate.cc",
"content_main_delegate.h",

@ -0,0 +1,32 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_
#define CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_
#include <jni.h>
#include "content/common/content_export.h"
namespace base {
namespace android {
class JNIOnLoadDelegate;
} // namespace android
} // namespace base
namespace content {
namespace android {
// Returns true if JNI registration and initialization succeeded. Refer to
// JNIOnLoadDelegate for more information.
CONTENT_EXPORT bool OnJNIOnLoad(
JavaVM* vm,
base::android::JNIOnLoadDelegate* delegate);
} // namespace android
} // namespace content
#endif // CONTENT_PUBLIC_APP_CONTENT_JNI_ONLOAD_H_

@ -30,7 +30,6 @@ shared_library("libcontent_shell_content_view") {
]
sources = [
"shell_library_loader.cc",
"shell_library_loader.h",
]
if (is_android_webview_build) {
ldflags = [ "-lgabi++" ]

@ -21,10 +21,7 @@
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "content/public/app/android_library_loader_hooks.h"
#include "content/public/app/content_main.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/nested_message_pump_android.h"
#include "content/public/test/test_launcher.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
@ -96,28 +93,9 @@ static void RunTests(JNIEnv* env,
ScopedMainEntryLogger scoped_main_entry_logger;
main(argc, &argv[0]);
}
} // namespace content
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
if (!base::android::RegisterLibraryLoaderEntryHook(env))
return -1;
if (!content::android::RegisterShellJni(env))
return -1;
if (!content::NestedMessagePumpAndroid::RegisterJni(env))
return -1;
if (!content::RegisterNativesImpl(env))
return -1;
content::SetContentMainDelegate(new content::ShellMainDelegate());
return JNI_VERSION_1_4;
bool RegisterContentBrowserTestsAndroid(JNIEnv* env) {
return RegisterNativesImpl(env);
}
} // namespace content

@ -0,0 +1,16 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_
#define CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_
#include <jni.h>
namespace content {
bool RegisterContentBrowserTestsAndroid(JNIEnv* env);
} // namespace content
#endif // CONTENT_SHELL_ANDROID_BROWSERTESTS_APK_CONTENT_BROWSER_TESTS_ANDROID_H_

@ -0,0 +1,44 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/jni_android.h"
#include "base/android/jni_onload_delegate.h"
#include "content/public/app/content_jni_onload.h"
#include "content/public/app/content_main.h"
#include "content/public/test/nested_message_pump_android.h"
#include "content/shell/android/browsertests_apk/content_browser_tests_android.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
namespace {
class ContentBrowserTestsJNIOnLoadDelegate :
public base::android::JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
bool ContentBrowserTestsJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
return content::android::RegisterShellJni(env) &&
content::NestedMessagePumpAndroid::RegisterJni(env) &&
content::RegisterContentBrowserTestsAndroid(env);
}
bool ContentBrowserTestsJNIOnLoadDelegate::Init() {
content::SetContentMainDelegate(new content::ShellMainDelegate());
return true;
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
ContentBrowserTestsJNIOnLoadDelegate delegate;
if (!content::android::OnJNIOnLoad(vm, &delegate))
return -1;
return JNI_VERSION_1_4;
}

@ -3,34 +3,39 @@
// found in the LICENSE file.
#include "base/android/jni_android.h"
#include "base/android/jni_registrar.h"
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/basictypes.h"
#include "base/debug/debugger.h"
#include "base/logging.h"
#include "content/public/app/android_library_loader_hooks.h"
#include "base/android/jni_onload_delegate.h"
#include "content/public/app/content_jni_onload.h"
#include "content/public/app/content_main.h"
#include "content/public/browser/android/compositor.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
namespace {
base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
class ShellJNIOnLoadDelegate : public base::android::JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
if (!base::android::RegisterLibraryLoaderEntryHook(env))
return -1;
// To be called only from the UI thread. If loading the library is done on
// a separate thread, this should be moved elsewhere.
if (!content::android::RegisterShellJni(env))
return -1;
bool ShellJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
return content::android::RegisterShellJni(env);
}
bool ShellJNIOnLoadDelegate::Init() {
content::Compositor::Initialize();
content::SetContentMainDelegate(new content::ShellMainDelegate());
return true;
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
ShellJNIOnLoadDelegate delegate;
if (!content::android::OnJNIOnLoad(vm, &delegate))
return -1;
return JNI_VERSION_1_4;
}

@ -8,7 +8,9 @@ import("//build/config/android/rules.gni")
source_set("native_test_native_code") {
testonly = true
sources = [
"native_test_jni_onload.cc",
"native_test_launcher.cc",
"native_test_launcher.h",
]
libs = [ "log" ]
deps = [

@ -12,7 +12,9 @@
'message': 'building native pieces of native test package',
'type': 'static_library',
'sources': [
'native_test_jni_onload.cc',
'native_test_launcher.cc',
'native_test_launcher.h',
],
'direct_dependent_settings': {
'ldflags!': [

@ -0,0 +1,40 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/android/base_jni_onload.h"
#include "base/android/jni_android.h"
#include "base/android/jni_onload_delegate.h"
#include "testing/android/native_test_launcher.h"
namespace {
class NativeTestJNIOnLoadDelegate : public base::android::JNIOnLoadDelegate {
public:
bool RegisterJNI(JNIEnv* env) override;
bool Init() override;
};
bool NativeTestJNIOnLoadDelegate::RegisterJNI(JNIEnv* env) {
return RegisterNativeTestJNI(env);
}
bool NativeTestJNIOnLoadDelegate::Init() {
InstallHandlers();
return true;
}
} // namespace
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
NativeTestJNIOnLoadDelegate delegate;
std::vector<base::android::JNIOnLoadDelegate*> delegates;
delegates.push_back(&delegate);
if (!base::android::OnJNIOnLoad(vm, &delegates))
return -1;
return JNI_VERSION_1_4;
}

@ -60,20 +60,6 @@ void SignalHandler(int sig, siginfo_t* info, void* reserved) {
g_old_sa[sig].sa_sigaction(sig, info, reserved);
}
// TODO(nileshagrawal): now that we're using FIFO, test scripts can detect EOF.
// Remove the signal handlers.
void InstallHandlers() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = SignalHandler;
sa.sa_flags = SA_SIGINFO;
for (unsigned int i = 0; kExceptionSignals[i] != -1; ++i) {
sigaction(kExceptionSignals[i], &sa, &g_old_sa[kExceptionSignals[i]]);
}
}
// Writes printf() style string to Android's logger where |priority| is one of
// the levels defined in <android/log.h>.
void AndroidLog(int priority, const char* format, ...) {
@ -92,8 +78,6 @@ static void RunTests(JNIEnv* env,
jstring jstdout_file_path,
jboolean jstdout_fifo,
jobject app_context) {
base::AtExitManager exit_manager;
// Command line initialized basically, will be fully initialized later.
static const char* const kInitialArgv[] = { "ChromeTestActivity" };
base::CommandLine::Init(arraysize(kInitialArgv), kInitialArgv);
@ -157,16 +141,21 @@ static void RunTests(JNIEnv* env,
main(argc, &argv[0]);
}
// This is called by the VM when the shared library is first loaded.
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// Install signal handlers to detect crashes.
InstallHandlers();
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
if (!RegisterNativesImpl(env)) {
return -1;
}
return JNI_VERSION_1_4;
bool RegisterNativeTestJNI(JNIEnv* env) {
return RegisterNativesImpl(env);
}
// TODO(nileshagrawal): now that we're using FIFO, test scripts can detect EOF.
// Remove the signal handlers.
void InstallHandlers() {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_sigaction = SignalHandler;
sa.sa_flags = SA_SIGINFO;
for (unsigned int i = 0; kExceptionSignals[i] != -1; ++i) {
sigaction(kExceptionSignals[i], &sa, &g_old_sa[kExceptionSignals[i]]);
}
}

@ -0,0 +1,13 @@
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef TESTING_ANDROID_NATIVE_TEST_LAUNCHER_H_
#define TESTING_ANDROID_NATIVE_TEST_LAUNCHER_H_
#include <jni.h>
void InstallHandlers();
bool RegisterNativeTestJNI(JNIEnv* env);
#endif // TESTING_ANDROID_NATIVE_TEST_LAUNCHER_H_