Reland #3: [Android JNI] Generate calls to RegisterNatives()
Reverted in: I31b4c809584f8dbb8e5626a28562d94a422611e7
Reason for reland: CL 556581 has fixed the bug.
TBR=sky@chromium.org,yfriedman@chromium.org,phajdan.jr@chromium.org,mef@chromium.org,torne@chromium.org,sergeyu@chromium.org,agrieve@chromium.org,halliwell@chromium.org,joedow@chromium.org,estevenson@chromium.org,jbudorick@chromium.org,yipengw@chromium.org
Bug: 683256, 738067
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester
Change-Id: Ie1afd9b6e606ebecfdf5ffbd0897fabbdfd3e157
Reviewed-on: https://chromium-review.googlesource.com/558004
Commit-Queue: Yipeng Wang <yipengw@chromium.org>
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Cr-Commit-Position: refs/heads/master@{#483760}
diff --git a/android_webview/test/embedded_test_server/BUILD.gn b/android_webview/test/embedded_test_server/BUILD.gn
index e9b2f3a..f9d6dbf9 100644
--- a/android_webview/test/embedded_test_server/BUILD.gn
+++ b/android_webview/test/embedded_test_server/BUILD.gn
@@ -57,6 +57,8 @@
":aw_java_test_native_support",
"//net:test_support",
]
+ configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+ configs += [ "//build/config/android:hide_all_but_jni" ]
}
android_apk("aw_net_test_support_apk") {
diff --git a/base/android/jni_generator/SampleForTests_jni.golden b/base/android/jni_generator/SampleForTests_jni.golden
index 7b384252..e50583ab 100644
--- a/base/android/jni_generator/SampleForTests_jni.golden
+++ b/base/android/jni_generator/SampleForTests_jni.golden
@@ -482,24 +482,35 @@
},
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsInnerClassSize = arraysize(kMethodsInnerClass);
+} // namespace android
+} // namespace base
+
+JNI_REGISTRATION_EXPORT bool
+ RegisterNative_org_chromium_example_jni_1generator_SampleForTests(JNIEnv*
+ env) {
+
+ const int kMethodsInnerClassSize =
+ arraysize(base::android::kMethodsInnerClass);
if (env->RegisterNatives(InnerClass_clazz(env),
- kMethodsInnerClass,
+ base::android::kMethodsInnerClass,
kMethodsInnerClassSize) < 0) {
jni_generator::HandleRegistrationError(
env, InnerClass_clazz(env), __FILE__);
return false;
}
- const int kMethodsSampleForTestsSize = arraysize(kMethodsSampleForTests);
+ const int kMethodsSampleForTestsSize =
+ arraysize(base::android::kMethodsSampleForTests);
if (env->RegisterNatives(SampleForTests_clazz(env),
- kMethodsSampleForTests,
+ base::android::kMethodsSampleForTests,
kMethodsSampleForTestsSize) < 0) {
jni_generator::HandleRegistrationError(
env, SampleForTests_clazz(env), __FILE__);
@@ -509,7 +520,4 @@
return true;
}
-} // namespace android
-} // namespace base
-
#endif // org_chromium_example_jni_generator_SampleForTests_JNI
diff --git a/base/android/jni_generator/jni_exception_list.gni b/base/android/jni_generator/jni_exception_list.gni
new file mode 100644
index 0000000..a990cc2
--- /dev/null
+++ b/base/android/jni_generator/jni_exception_list.gni
@@ -0,0 +1,16 @@
+# Copyright 2017 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.
+
+import("//device/vr/features/features.gni")
+
+jni_exception_files = [
+ "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+ "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+ "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+]
+
+# Exclude it from JNI registration if VR is not enabled.
+if (!enable_vr) {
+ jni_exception_files += [ "//chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java" ]
+}
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 3818009..8249fc9 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -401,7 +401,7 @@
def IsMainDexJavaClass(contents):
- """Returns "true" if the class is annotated with "@MainDex", "false" if not.
+ """Returns True if the class is annotated with "@MainDex", False if not.
JNI registration doesn't always need to be completed for non-browser processes
since most Java code is only used by the browser process. Classes that are
@@ -409,8 +409,17 @@
to force JNI registration.
"""
re_maindex = re.compile(r'@MainDex[\s\S]*class({|[\s\S]*{)')
- found = re.search(re_maindex, contents)
- return 'true' if found else 'false'
+ return bool(re.search(re_maindex, contents))
+
+
+def GetBinaryClassName(fully_qualified_class):
+ """Returns a string concatenating the Java package and class."""
+ return fully_qualified_class.replace('_', '_1').replace('/', '_')
+
+
+def GetRegistrationFunctionName(fully_qualified_class):
+ """Returns the register name with a given class."""
+ return 'RegisterNative_' + GetBinaryClassName(fully_qualified_class)
def GetStaticCastForReturnType(return_type):
@@ -620,7 +629,6 @@
is_constructor=True)]
self.called_by_natives = MangleCalledByNatives(self.jni_params,
self.called_by_natives)
-
self.constant_fields = []
re_constant_field = re.compile('.*?public static final int (?P<name>.*?);')
re_constant_field_value = re.compile(
@@ -673,13 +681,12 @@
jni_namespace = ExtractJNINamespace(contents) or options.namespace
natives = ExtractNatives(contents, options.ptr_type)
called_by_natives = ExtractCalledByNatives(self.jni_params, contents)
- maindex = IsMainDexJavaClass(contents)
if len(natives) == 0 and len(called_by_natives) == 0:
raise SyntaxError('Unable to find any JNI methods for %s.' %
fully_qualified_class)
inl_header_file_generator = InlHeaderFileGenerator(
jni_namespace, fully_qualified_class, natives, called_by_natives, [],
- self.jni_params, options, maindex)
+ self.jni_params, options)
self.content = inl_header_file_generator.GetContent()
@classmethod
@@ -715,8 +722,7 @@
"""Generates an inline header file for JNI integration."""
def __init__(self, namespace, fully_qualified_class, natives,
- called_by_natives, constant_fields, jni_params, options,
- maindex='false'):
+ called_by_natives, constant_fields, jni_params, options):
self.namespace = namespace
self.fully_qualified_class = fully_qualified_class
self.class_name = self.fully_qualified_class.split('/')[-1]
@@ -724,7 +730,6 @@
self.called_by_natives = called_by_natives
self.header_guard = fully_qualified_class.replace('/', '_') + '_JNI'
self.constant_fields = constant_fields
- self.maindex = maindex
self.jni_params = jni_params
self.options = options
@@ -766,8 +771,9 @@
// Step 3: RegisterNatives.
$JNI_NATIVE_METHODS
-$REGISTER_NATIVES
+$REGISTER_NATIVES_EMPTY
$CLOSE_NAMESPACE
+$REGISTER_NATIVES
#endif // ${HEADER_GUARD}
""")
@@ -779,8 +785,9 @@
'METHOD_STUBS': self.GetMethodStubsString(),
'OPEN_NAMESPACE': self.GetOpenNamespaceString(),
'JNI_NATIVE_METHODS': self.GetJNINativeMethodsString(),
- 'REGISTER_NATIVES': self.GetRegisterNativesString(),
+ 'REGISTER_NATIVES_EMPTY': self.GetOriginalRegisterNativesString(),
'CLOSE_NAMESPACE': self.GetCloseNamespaceString(),
+ 'REGISTER_NATIVES': self.GetRegisterNativesString(),
'HEADER_GUARD': self.header_guard,
'INCLUDES': self.GetIncludesString(),
}
@@ -829,14 +836,19 @@
return '\n'.join(ret)
def SubstituteNativeMethods(self, template):
- """Substitutes JAVA_CLASS and KMETHODS in the provided template."""
+ """Substitutes NAMESPACE, JAVA_CLASS and KMETHODS in the provided
+ template."""
ret = []
all_classes = self.GetUniqueClasses(self.natives)
all_classes[self.class_name] = self.fully_qualified_class
for clazz in all_classes:
kmethods = self.GetKMethodsString(clazz)
+ namespace_str = ''
+ if self.namespace:
+ namespace_str = self.namespace + '::'
if kmethods:
- values = {'JAVA_CLASS': clazz,
+ values = {'NAMESPACE': namespace_str,
+ 'JAVA_CLASS': clazz,
'KMETHODS': kmethods}
ret += [template.substitute(values)]
if not ret: return ''
@@ -853,32 +865,38 @@
""")
return self.SubstituteNativeMethods(template)
+ # TODO(agrieve): Remove this function when deleting original registers.
+ # https://crbug.com/683256.
+ def GetOriginalRegisterNativesString(self):
+ """Return the code for original RegisterNatives"""
+ natives = self.GetRegisterNativesImplString()
+ if not natives:
+ return ''
+
+ return """
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
+static bool RegisterNativesImpl(JNIEnv* env) {
+ return true;
+}
+"""
+
def GetRegisterNativesString(self):
"""Returns the code for RegisterNatives."""
natives = self.GetRegisterNativesImplString()
if not natives:
return ''
-
template = Template("""\
-${REGISTER_NATIVES_SIGNATURE} {
-${EARLY_EXIT}
+JNI_REGISTRATION_EXPORT bool ${REGISTER_NAME}(JNIEnv* env) {
${NATIVES}
return true;
}
""")
- signature = 'static bool RegisterNativesImpl(JNIEnv* env)'
- early_exit = ''
- if self.options.native_exports_optional:
- early_exit = """\
- if (jni_generator::ShouldSkipJniRegistration(%s))
- return true;
-""" % self.maindex
-
- values = {'REGISTER_NATIVES_SIGNATURE': signature,
- 'EARLY_EXIT': early_exit,
- 'NATIVES': natives,
- }
-
+ values = {
+ 'REGISTER_NAME':
+ GetRegistrationFunctionName(self.fully_qualified_class),
+ 'NATIVES': natives
+ }
return template.substitute(values)
def GetRegisterNativesImplString(self):
@@ -887,10 +905,11 @@
return ''
template = Template("""\
- const int kMethods${JAVA_CLASS}Size = arraysize(kMethods${JAVA_CLASS});
+ const int kMethods${JAVA_CLASS}Size =
+ arraysize(${NAMESPACE}kMethods${JAVA_CLASS});
if (env->RegisterNatives(${JAVA_CLASS}_clazz(env),
- kMethods${JAVA_CLASS},
+ ${NAMESPACE}kMethods${JAVA_CLASS},
kMethods${JAVA_CLASS}Size) < 0) {
jni_generator::HandleRegistrationError(
env, ${JAVA_CLASS}_clazz(env), __FILE__);
@@ -974,7 +993,7 @@
"""
template = Template("Java_${JAVA_NAME}_native${NAME}")
- java_name = self.fully_qualified_class.replace('_', '_1').replace('/', '_')
+ java_name = GetBinaryClassName(self.fully_qualified_class)
if native.java_class_name:
java_name += '_00024' + native.java_class_name
@@ -1314,19 +1333,21 @@
print e
sys.exit(1)
if output_file:
- if not os.path.exists(os.path.dirname(os.path.abspath(output_file))):
- os.makedirs(os.path.dirname(os.path.abspath(output_file)))
- if options.optimize_generation and os.path.exists(output_file):
- with file(output_file, 'r') as f:
- existing_content = f.read()
- if existing_content == content:
- return
- with file(output_file, 'w') as f:
- f.write(content)
+ WriteOutput(output_file, content)
else:
print content
+def WriteOutput(output_file, content):
+ if os.path.exists(output_file):
+ with open(output_file) as f:
+ existing_content = f.read()
+ if existing_content == content:
+ return
+ with open(output_file, 'w') as f:
+ f.write(content)
+
+
def GetScriptName():
script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
base_index = 0
@@ -1363,10 +1384,6 @@
option_parser.add_option('--output_dir',
help='The output directory. Must be used with '
'--input')
- option_parser.add_option('--optimize_generation', type="int",
- default=0, help='Whether we should optimize JNI '
- 'generation by not regenerating files if they have '
- 'not changed.')
option_parser.add_option('--script_name', default=GetScriptName(),
help='The name of this script in the generated '
'header.')
diff --git a/base/android/jni_generator/jni_generator_helper.h b/base/android/jni_generator/jni_generator_helper.h
index 3062806..53629a657 100644
--- a/base/android/jni_generator/jni_generator_helper.h
+++ b/base/android/jni_generator/jni_generator_helper.h
@@ -30,6 +30,13 @@
#define JNI_GENERATOR_EXPORT extern "C" __attribute__((visibility("default")))
#endif
+// Used to export JNI registration functions.
+#if defined(COMPONENT_BUILD)
+#define JNI_REGISTRATION_EXPORT __attribute__((visibility("default")))
+#else
+#define JNI_REGISTRATION_EXPORT
+#endif
+
namespace jni_generator {
inline void HandleRegistrationError(JNIEnv* env,
@@ -42,12 +49,14 @@
base::android::CheckException(env);
}
+// TODO(estevenson): Remove this function since all natives are registered
+// together. Currently gvr-android-sdk stil calls it.
+// https://crbug.com/664306.
inline bool ShouldSkipJniRegistration(bool is_maindex_class) {
switch (base::android::GetJniRegistrationType()) {
case base::android::ALL_JNI_REGISTRATION:
return false;
case base::android::NO_JNI_REGISTRATION:
- // TODO(estevenson): Change this to a DCHECK.
return true;
case base::android::SELECTIVE_JNI_REGISTRATION:
return !is_maindex_class;
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index d667a47..41e617f 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -967,33 +967,6 @@
test_options)
self.assertGoldenTextEquals(h.GetContent())
- def testMainDexFile(self):
- test_data = """
- package org.chromium.example.jni_generator;
-
- @MainDex
- class Test {
- private static native int nativeStaticMethod(long nativeTest, int arg1);
- }
- """
- options = TestOptions()
- jni_from_java = jni_generator.JNIFromJavaSource(
- test_data, 'org/chromium/foo/Bar', options)
- self.assertGoldenTextEquals(jni_from_java.GetContent())
-
- def testNonMainDexFile(self):
- test_data = """
- package org.chromium.example.jni_generator;
-
- class Test {
- private static native int nativeStaticMethod(long nativeTest, int arg1);
- }
- """
- options = TestOptions()
- jni_from_java = jni_generator.JNIFromJavaSource(
- test_data, 'org/chromium/foo/Bar', options)
- self.assertGoldenTextEquals(jni_from_java.GetContent())
-
def testMainDexAnnotation(self):
mainDexEntries = [
'@MainDex public class Test {',
@@ -1021,7 +994,7 @@
'@MainDex public class Test extends Testable<java.io.Serializable> {',
]
for entry in mainDexEntries:
- self.assertEquals("true", IsMainDexJavaClass(entry))
+ self.assertEquals(True, IsMainDexJavaClass(entry))
def testNoMainDexAnnotation(self):
noMainDexEntries = [
@@ -1031,7 +1004,7 @@
'public class Test extends BaseTest {'
]
for entry in noMainDexEntries:
- self.assertEquals("false", IsMainDexJavaClass(entry))
+ self.assertEquals(False, IsMainDexJavaClass(entry))
def testNativeExportsOnlyOption(self):
test_data = """
diff --git a/base/android/jni_generator/jni_registration_generator.py b/base/android/jni_generator/jni_registration_generator.py
new file mode 100755
index 0000000..a7ede2db
--- /dev/null
+++ b/base/android/jni_generator/jni_registration_generator.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python
+# Copyright 2017 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.
+
+"""Generate JNI registration entry points
+
+Creates a header file with two static functions: RegisterMainDexNatives() and
+RegisterNonMainDexNatives(). Together, these will use manual JNI registration
+to register all native methods that exist within an application."""
+
+import argparse
+import jni_generator
+import os
+import string
+import sys
+from util import build_utils
+
+
+def GenerateJNIHeader(java_file_paths, output_file, args):
+ """Generate a header file including two registration functions.
+
+ Forward declares all JNI registration functions created by jni_generator.py.
+ Calls the functions in RegisterMainDexNatives() if they are main dex. And
+ calls them in RegisterNonMainDexNatives() if they are non-main dex.
+
+ Args:
+ java_file_paths: A list of java file paths.
+ output_file: A relative path to output file.
+ args: All input arguments.
+ """
+ registration_dict = {
+ 'FORWARD_DECLARATIONS': '',
+ 'REGISTER_MAIN_DEX_NATIVES': '',
+ 'REGISTER_NON_MAIN_DEX_NATIVES': ''
+ }
+ # Sort the file list to make sure the order is deterministic.
+ java_file_paths.sort()
+ for path in java_file_paths:
+ if path in args.no_register_java:
+ continue
+ with open(path) as f:
+ contents = f.read()
+ natives = jni_generator.ExtractNatives(contents, 'long')
+ if len(natives) == 0:
+ continue
+ fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
+ path, contents)
+ main_dex = jni_generator.IsMainDexJavaClass(contents)
+ header_generator = HeaderGenerator(
+ fully_qualified_class, registration_dict, main_dex)
+ registration_dict = header_generator.GetContent()
+
+ header_content = CreateFromDict(registration_dict)
+ if output_file:
+ jni_generator.WriteOutput(output_file, header_content)
+ else:
+ print header_content
+
+
+def CreateFromDict(registration_dict):
+ """Returns the content of the header file."""
+
+ template = string.Template("""\
+// Copyright 2017 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.
+
+
+// This file is autogenerated by
+// base/android/jni_generator/jni_registration_generator.py
+// Please do not change its content.
+
+#ifndef HEADER_GUARD
+#define HEADER_GUARD
+
+#include <jni.h>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+// Step 1: Forward declaration.
+${FORWARD_DECLARATIONS}
+
+// Step 2: Main dex and non-main dex registration functions.
+
+bool RegisterMainDexNatives(JNIEnv* env) {
+${REGISTER_MAIN_DEX_NATIVES}
+
+ return true;
+}
+
+bool RegisterNonMainDexNatives(JNIEnv* env) {
+${REGISTER_NON_MAIN_DEX_NATIVES}
+
+ return true;
+}
+
+#endif // HEADER_GUARD
+""")
+ if len(registration_dict['FORWARD_DECLARATIONS']) == 0:
+ return ''
+ return jni_generator.WrapOutput(template.substitute(registration_dict))
+
+
+class HeaderGenerator(object):
+ """Generates an inline header file for JNI registration."""
+
+ def __init__(self, fully_qualified_class, registration_dict, main_dex):
+ self.fully_qualified_class = fully_qualified_class
+ self.class_name = self.fully_qualified_class.split('/')[-1]
+ self.registration_dict = registration_dict
+ self.main_dex = main_dex
+
+ def GetContent(self):
+ self._AddForwardDeclaration()
+ self._AddRegisterNatives()
+ return self.registration_dict
+
+ def _AddForwardDeclaration(self):
+ """Add the content of the forward declaration to the dictionary."""
+ template = string.Template('JNI_REGISTRATION_EXPORT bool ${METHOD_NAME}('
+ 'JNIEnv* env);\n')
+ value = {
+ 'METHOD_NAME':
+ jni_generator.GetRegistrationFunctionName(
+ self.fully_qualified_class)
+ }
+ self.registration_dict['FORWARD_DECLARATIONS'] += template.substitute(value)
+
+ def _AddRegisterNatives(self):
+ """Add the body of the RegisterNativesImpl method to the dictionary."""
+ template = string.Template("""
+if (!${REGISTER_NAME}(env))
+ return false;
+""")
+ value = {
+ 'REGISTER_NAME':
+ jni_generator.GetRegistrationFunctionName(
+ self.fully_qualified_class)
+ }
+ register_body = template.substitute(value)
+ if self.main_dex:
+ self.registration_dict['REGISTER_MAIN_DEX_NATIVES'] += register_body
+ else:
+ self.registration_dict['REGISTER_NON_MAIN_DEX_NATIVES'] += register_body
+
+
+def main(argv):
+ arg_parser = argparse.ArgumentParser()
+ build_utils.AddDepfileOption(arg_parser)
+
+ arg_parser.add_argument('--sources_files',
+ help='A list of .sources files which contain Java '
+ 'file paths. Must be used with --output.')
+ arg_parser.add_argument('--output',
+ help='The output file path.')
+ arg_parser.add_argument('--no_register_java',
+ help='A list of Java files which should be ignored '
+ 'by the parser.')
+ args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:]))
+ args.sources_files = build_utils.ParseGnList(args.sources_files)
+
+ if args.sources_files:
+ java_file_paths = []
+ for f in args.sources_files:
+ # java_file_paths stores each Java file path as a string.
+ java_file_paths += build_utils.ReadSourcesList(f)
+ else:
+ print '\nError: Must specify --sources_files.'
+ return 1
+ output_file = args.output
+ GenerateJNIHeader(java_file_paths, output_file, args)
+
+ if args.depfile:
+ build_utils.WriteDepfile(args.depfile, output_file)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/base/android/jni_generator/testInnerClassNatives.golden b/base/android/jni_generator/testInnerClassNatives.golden
index 20b8830..363f916 100644
--- a/base/android/jni_generator/testInnerClassNatives.golden
+++ b/base/android/jni_generator/testInnerClassNatives.golden
@@ -51,11 +51,16 @@
},
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+ const int kMethodsMyInnerClassSize =
+ arraysize(kMethodsMyInnerClass);
if (env->RegisterNatives(MyInnerClass_clazz(env),
kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
index 67352e7..6c07b58 100644
--- a/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
+++ b/base/android/jni_generator/testInnerClassNativesBothInnerAndOuter.golden
@@ -67,9 +67,13 @@
"I", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeInit) },
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
+
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
const int kMethodsMyOtherInnerClassSize =
arraysize(kMethodsMyOtherInnerClass);
@@ -82,7 +86,8 @@
return false;
}
- const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+ const int kMethodsTestJniSize =
+ arraysize(kMethodsTestJni);
if (env->RegisterNatives(TestJni_clazz(env),
kMethodsTestJni,
diff --git a/base/android/jni_generator/testInnerClassNativesMultiple.golden b/base/android/jni_generator/testInnerClassNativesMultiple.golden
index 7807efa..add5ac9 100644
--- a/base/android/jni_generator/testInnerClassNativesMultiple.golden
+++ b/base/android/jni_generator/testInnerClassNativesMultiple.golden
@@ -74,9 +74,13 @@
},
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
+
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
const int kMethodsMyOtherInnerClassSize =
arraysize(kMethodsMyOtherInnerClass);
@@ -89,7 +93,8 @@
return false;
}
- const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass);
+ const int kMethodsMyInnerClassSize =
+ arraysize(kMethodsMyInnerClass);
if (env->RegisterNatives(MyInnerClass_clazz(env),
kMethodsMyInnerClass,
diff --git a/base/android/jni_generator/testMainDexFile.golden b/base/android/jni_generator/testMainDexFile.golden
deleted file mode 100644
index cbb2a7d..0000000
--- a/base/android/jni_generator/testMainDexFile.golden
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 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.
-
-// This file is autogenerated by
-// base/android/jni_generator/jni_generator.py
-// For
-// org/chromium/foo/Bar
-
-#ifndef org_chromium_foo_Bar_JNI
-#define org_chromium_foo_Bar_JNI
-
-#include <jni.h>
-
-#include "base/android/jni_generator/jni_generator_helper.h"
-
-#include "base/android/jni_int_wrapper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kBarClassPath[] = "org/chromium/foo/Bar";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0;
-#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz)
-
-} // namespace
-
-// Step 2: method stubs.
-JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv*
- env, jobject jcaller,
- jlong nativeTest,
- jint arg1) {
- Test* native = reinterpret_cast<Test*>(nativeTest);
- CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0);
- return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env,
- jcaller), arg1);
-}
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsBar[] = {
- { "nativeStaticMethod",
-"("
-"J"
-"I"
-")"
-"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) },
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(true))
- return true;
-
- const int kMethodsBarSize = arraysize(kMethodsBar);
-
- if (env->RegisterNatives(Bar_clazz(env),
- kMethodsBar,
- kMethodsBarSize) < 0) {
- jni_generator::HandleRegistrationError(
- env, Bar_clazz(env), __FILE__);
- return false;
- }
-
- return true;
-}
-
-#endif // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
index 0eecb5a..03aac48e 100644
--- a/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testMultipleJNIAdditionalImport.golden
@@ -75,11 +75,16 @@
"V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) },
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsFooSize = arraysize(kMethodsFoo);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) {
+
+ const int kMethodsFooSize =
+ arraysize(kMethodsFoo);
if (env->RegisterNatives(Foo_clazz(env),
kMethodsFoo,
diff --git a/base/android/jni_generator/testNatives.golden b/base/android/jni_generator/testNatives.golden
index 3362c928..0bfbe04 100644
--- a/base/android/jni_generator/testNatives.golden
+++ b/base/android/jni_generator/testNatives.golden
@@ -320,11 +320,16 @@
},
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+ const int kMethodsTestJniSize =
+ arraysize(kMethodsTestJni);
if (env->RegisterNatives(TestJni_clazz(env),
kMethodsTestJni,
diff --git a/base/android/jni_generator/testNativesLong.golden b/base/android/jni_generator/testNativesLong.golden
index ec029ce..201a066 100644
--- a/base/android/jni_generator/testNativesLong.golden
+++ b/base/android/jni_generator/testNativesLong.golden
@@ -46,11 +46,16 @@
"V", reinterpret_cast<void*>(Java_org_chromium_TestJni_nativeDestroy) },
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsTestJniSize = arraysize(kMethodsTestJni);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_TestJni(JNIEnv* env) {
+
+ const int kMethodsTestJniSize =
+ arraysize(kMethodsTestJni);
if (env->RegisterNatives(TestJni_clazz(env),
kMethodsTestJni,
diff --git a/base/android/jni_generator/testNonMainDexFile.golden b/base/android/jni_generator/testNonMainDexFile.golden
deleted file mode 100644
index 533241e..0000000
--- a/base/android/jni_generator/testNonMainDexFile.golden
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 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.
-
-// This file is autogenerated by
-// base/android/jni_generator/jni_generator.py
-// For
-// org/chromium/foo/Bar
-
-#ifndef org_chromium_foo_Bar_JNI
-#define org_chromium_foo_Bar_JNI
-
-#include <jni.h>
-
-#include "base/android/jni_generator/jni_generator_helper.h"
-
-#include "base/android/jni_int_wrapper.h"
-
-// Step 1: forward declarations.
-namespace {
-const char kBarClassPath[] = "org/chromium/foo/Bar";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-base::subtle::AtomicWord g_Bar_clazz __attribute__((unused)) = 0;
-#define Bar_clazz(env) base::android::LazyGetClass(env, kBarClassPath, &g_Bar_clazz)
-
-} // namespace
-
-// Step 2: method stubs.
-JNI_GENERATOR_EXPORT jint Java_org_chromium_foo_Bar_nativeStaticMethod(JNIEnv*
- env, jobject jcaller,
- jlong nativeTest,
- jint arg1) {
- Test* native = reinterpret_cast<Test*>(nativeTest);
- CHECK_NATIVE_PTR(env, jcaller, native, "StaticMethod", 0);
- return native->StaticMethod(env, base::android::JavaParamRef<jobject>(env,
- jcaller), arg1);
-}
-
-// Step 3: RegisterNatives.
-
-static const JNINativeMethod kMethodsBar[] = {
- { "nativeStaticMethod",
-"("
-"J"
-"I"
-")"
-"I", reinterpret_cast<void*>(Java_org_chromium_foo_Bar_nativeStaticMethod) },
-};
-
-static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
-
- const int kMethodsBarSize = arraysize(kMethodsBar);
-
- if (env->RegisterNatives(Bar_clazz(env),
- kMethodsBar,
- kMethodsBarSize) < 0) {
- jni_generator::HandleRegistrationError(
- env, Bar_clazz(env), __FILE__);
- return false;
- }
-
- return true;
-}
-
-#endif // org_chromium_foo_Bar_JNI
diff --git a/base/android/jni_generator/testSingleJNIAdditionalImport.golden b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
index ef618da8..a367ae7 100644
--- a/base/android/jni_generator/testSingleJNIAdditionalImport.golden
+++ b/base/android/jni_generator/testSingleJNIAdditionalImport.golden
@@ -69,11 +69,16 @@
"V", reinterpret_cast<void*>(Java_org_chromium_foo_Foo_nativeDoSomething) },
};
+// TODO(agrieve): Remove these empty registration functions and functions
+// calling them. https://crbug.com/683256.
static bool RegisterNativesImpl(JNIEnv* env) {
- if (jni_generator::ShouldSkipJniRegistration(false))
- return true;
+ return true;
+}
- const int kMethodsFooSize = arraysize(kMethodsFoo);
+JNI_REGISTRATION_EXPORT bool RegisterNative_org_chromium_foo_Foo(JNIEnv* env) {
+
+ const int kMethodsFooSize =
+ arraysize(kMethodsFoo);
if (env->RegisterNatives(Foo_clazz(env),
kMethodsFoo,
diff --git a/build/android/gradle/generate_gradle.py b/build/android/gradle/generate_gradle.py
index e7bf827..ba2311a 100755
--- a/build/android/gradle/generate_gradle.py
+++ b/build/android/gradle/generate_gradle.py
@@ -211,7 +211,7 @@
def JavaFiles(self):
if self._java_files is None:
- java_sources_file = self.Gradle().get('java_sources_file')
+ java_sources_file = self.DepsInfo().get('java_sources_file')
java_files = []
if java_sources_file:
java_sources_file = _RebasePath(java_sources_file)
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index c085176..6eab4b2 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -413,7 +413,7 @@
gradle['android_manifest'] = options.android_manifest
if options.type in ('java_binary', 'java_library', 'android_apk'):
if options.java_sources_file:
- gradle['java_sources_file'] = options.java_sources_file
+ deps_info['java_sources_file'] = options.java_sources_file
if options.bundled_srcjars:
gradle['bundled_srcjars'] = (
build_utils.ParseGnList(options.bundled_srcjars))
@@ -436,6 +436,14 @@
gradle['dependent_java_projects'].append(c['path'])
+ if options.type == 'android_apk':
+ config['jni'] = {}
+ all_java_sources = [c['java_sources_file'] for c in all_library_deps
+ if 'java_sources_file' in c]
+ if options.java_sources_file:
+ all_java_sources.append(options.java_sources_file)
+ config['jni']['all_source'] = all_java_sources
+
if (options.type in ('java_binary', 'java_library')):
deps_info['requires_android'] = options.requires_android
deps_info['supports_android'] = options.supports_android
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 38032b768..ceffd06 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -192,7 +192,6 @@
"--depfile",
rebase_path(depfile, root_build_dir),
"--input_file={{source}}",
- "--optimize_generation=1",
"--ptr_type=long",
"--output_dir",
rebase_path(jni_output_dir, root_build_dir),
@@ -302,7 +301,6 @@
rebase_path(jar_file, root_build_dir),
"--input_file",
class,
- "--optimize_generation=1",
"--ptr_type=long",
"--output_dir",
rebase_path(jni_output_dir, root_build_dir),
@@ -334,6 +332,61 @@
}
}
+ # Declare a jni registration target.
+ #
+ # This target generates a header file calling JNI registration functions
+ # created by generate_jni and generate_jar_jni.
+ #
+ # See base/android/jni_generator/jni_registration_generator.py for more info
+ # about the format of the header file.
+ #
+ # Variables
+ # target: The Apk target to generate registrations for.
+ # output: Path to the generated .h file.
+ # exception_files: List of .java files that should be ignored when searching
+ # for native methods. (optional)
+ #
+ # Example
+ # generate_jni_registration("chrome_jni_registration") {
+ # target = ":chrome_public_apk"
+ # output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+ # exception_files = [
+ # "//base/android/java/src/org/chromium/base/library_loader/LegacyLinker.java",
+ # "//base/android/java/src/org/chromium/base/library_loader/Linker.java",
+ # "//base/android/java/src/org/chromium/base/library_loader/ModernLinker.java",
+ # ]
+ # }
+ template("generate_jni_registration") {
+ action(target_name) {
+ forward_variables_from(invoker, [ "testonly" ])
+ _build_config = get_label_info(invoker.target, "target_gen_dir") + "/" +
+ get_label_info(invoker.target, "name") + ".build_config"
+ _rebased_build_config = rebase_path(_build_config, root_build_dir)
+
+ _rebase_exception_java_files =
+ rebase_path(invoker.exception_files, root_build_dir)
+
+ script = "//base/android/jni_generator/jni_registration_generator.py"
+ deps = [
+ "${invoker.target}__build_config",
+ ]
+ inputs = [
+ _build_config,
+ ]
+ outputs = [
+ invoker.output,
+ ]
+
+ args = [
+ # This is a list of .sources files.
+ "--sources_files=@FileArg($_rebased_build_config:jni:all_source)",
+ "--output",
+ rebase_path(invoker.output, root_build_dir),
+ "--no_register_java=$_rebase_exception_java_files",
+ ]
+ }
+ }
+
# Declare a target for c-preprocessor-generated java files
#
# NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index d8fe989..1c3aa01 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1765,6 +1765,7 @@
# find the native side functions.
if (is_android && is_component_build) {
deps += [
+ "//device/gamepad",
"//device/generic_sensor",
"//device/sensors",
]
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index b80a1d6f..c59688c1 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//build/util/process_version.gni")
@@ -672,6 +673,7 @@
"../browser/android/chrome_entry_point.cc",
]
deps = [
+ ":chrome_jni_registration($default_toolchain)",
"//build/config:exe_and_shlib_deps",
"//chrome:chrome_android_core",
]
@@ -696,8 +698,22 @@
}
# Ensure that .pak files are built only once (build them in the default
-# toolchain).
+# toolchain). The central header file calling JNI registration functions
+# is generated from Java code so it just needs to be generated once.
if (current_toolchain == default_toolchain) {
+ generate_jni_registration("chrome_jni_registration") {
+ target = ":chrome_public_apk"
+ output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+ exception_files = jni_exception_files
+ }
+
+ generate_jni_registration("chrome_sync_shell_jni_registration") {
+ testonly = true
+ target = ":chrome_sync_shell_apk"
+ output = "$root_gen_dir/chrome/browser/android/${target_name}.h"
+ exception_files = jni_exception_files
+ }
+
if (enable_resource_whitelist_generation) {
generate_resource_whitelist("monochrome_resource_whitelist") {
# Always use the 32-bit library's whitelist since the 64-bit one is
@@ -793,12 +809,13 @@
shared_library("chrome_sync_shell") {
testonly = true
sources = [
- "../browser/android/chrome_entry_point.cc",
+ "../browser/android/chrome_sync_shell_entry_point.cc",
"../browser/android/chrome_sync_shell_main_delegate.cc",
"../browser/android/chrome_sync_shell_main_delegate.h",
"../browser/android/chrome_sync_shell_main_delegate_initializer.cc",
]
deps = [
+ ":chrome_sync_shell_jni_registration($default_toolchain)",
"//build/config:exe_and_shlib_deps",
"//chrome:chrome_android_core",
"//components/sync",
@@ -879,6 +896,9 @@
apk_name = "ChromeSyncShell"
shared_libraries = [ ":chrome_sync_shell" ]
+ # This exists here rather than in chrome_sync_shell_test_apk for JNI
+ # registration to be able to find the native side functions.
+ java_files = [ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java" ]
deps = [
":chrome_sync_shell_apk_template_resources",
@@ -886,6 +906,7 @@
# but that code is stripped out via proguard. Adding this deps adds
# usages and prevents removal of the proto code.
"//components/sync:test_support_proto_java",
+ "//third_party/android_protobuf:protobuf_nano_javalib",
]
}
@@ -979,11 +1000,23 @@
}
}
-android_library("chrome_sync_shell_test_apk_java") {
- testonly = true
-
- # From java_sources.jni.
- java_files = sync_shell_test_java_sources
+instrumentation_test_apk("chrome_sync_shell_test_apk") {
+ apk_name = "ChromeSyncShellTest"
+ apk_under_test = ":chrome_sync_shell_apk"
+ android_manifest = chrome_sync_shell_test_apk_manifest
+ android_manifest_dep = ":chrome_sync_shell_test_apk_manifest"
+ java_files = [
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
+ "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java",
+ ]
deps = [
"//base:base_java",
@@ -999,21 +1032,9 @@
"//components/sync/android:sync_java",
"//content/public/android:content_java",
"//content/public/test/android:content_java_test_support",
- "//third_party/android_protobuf:protobuf_nano_javalib",
"//third_party/android_support_test_runner:runner_java",
"//third_party/android_tools:android_support_v7_appcompat_java",
"//ui/android:ui_java",
]
-}
-
-instrumentation_test_apk("chrome_sync_shell_test_apk") {
- apk_name = "ChromeSyncShellTest"
- apk_under_test = ":chrome_sync_shell_apk"
- android_manifest = chrome_sync_shell_test_apk_manifest
- android_manifest_dep = ":chrome_sync_shell_test_apk_manifest"
- deps = [
- ":chrome_sync_shell_test_apk_java",
- "//third_party/android_support_test_runner:runner_java",
- ]
proguard_enabled = !is_java_debug
}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index fe6f03b..c76bfb3a 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1819,20 +1819,6 @@
"junit/src/org/chromium/chrome/browser/widget/selection/SelectionDelegateTest.java",
]
-sync_shell_test_java_sources = [
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/AutofillTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/BookmarksTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FakeServerHelper.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/FirstRunTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/GmsCoreSyncListenerTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/OpenTabsTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncCustomizationFragmentTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/SyncTestBase.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/TypedUrlsTest.java",
- "sync_shell/javatests/src/org/chromium/chrome/browser/sync/ui/PassphraseTypeDialogFragmentTest.java",
-]
-
# Only used for testing, should not be shipped to end users.
if (enable_offline_pages_harness) {
chrome_java_sources += [ "java/src/org/chromium/chrome/browser/offlinepages/evaluation/OfflinePageEvaluationBridge.java" ]
diff --git a/chrome/browser/android/DEPS b/chrome/browser/android/DEPS
index bb55a8c..8f032b7 100644
--- a/chrome/browser/android/DEPS
+++ b/chrome/browser/android/DEPS
@@ -2,6 +2,7 @@
"-components/devtools_bridge",
"+cc/layers/layer.h",
"+cc/output/context_provider.h",
+ "+chrome_jni_registration/chrome_jni_registration.h",
"+components/doodle",
"+components/ntp_snippets",
"+components/spellcheck/browser",
diff --git a/chrome/browser/android/chrome_entry_point.cc b/chrome/browser/android/chrome_entry_point.cc
index ee46cd6c..079358b 100644
--- a/chrome/browser/android/chrome_entry_point.cc
+++ b/chrome/browser/android/chrome_entry_point.cc
@@ -7,6 +7,7 @@
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "chrome/app/android/chrome_jni_onload.h"
+#include "chrome/browser/android/chrome_jni_registration.h"
namespace {
@@ -23,6 +24,19 @@
// Java side and only register a subset of JNI methods.
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+
+ if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+ if (!RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+ }
+
+ if (!RegisterMainDexNatives(env)) {
+ return -1;
+ }
+
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (base::android::IsSelectiveJniRegistrationEnabled(env)) {
base::android::SetJniRegistrationType(
base::android::SELECTIVE_JNI_REGISTRATION);
diff --git a/chrome/browser/android/chrome_sync_shell_entry_point.cc b/chrome/browser/android/chrome_sync_shell_entry_point.cc
new file mode 100644
index 0000000..e14ea511
--- /dev/null
+++ b/chrome/browser/android/chrome_sync_shell_entry_point.cc
@@ -0,0 +1,49 @@
+// Copyright 2017 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_utils.h"
+#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/bind.h"
+#include "chrome/app/android/chrome_jni_onload.h"
+#include "chrome/browser/android/chrome_sync_shell_jni_registration.h"
+
+namespace {
+
+bool NativeInit() {
+ return android::OnJNIOnLoadInit();
+}
+
+} // namespace
+
+// This is called by the VM when the shared library is first loaded.
+JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
+ // By default, all JNI methods are registered. However, since render processes
+ // don't need very much Java code, we enable selective JNI registration on the
+ // Java side and only register a subset of JNI methods.
+ base::android::InitVM(vm);
+ JNIEnv* env = base::android::AttachCurrentThread();
+
+ if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+ if (!RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+ }
+
+ if (!RegisterMainDexNatives(env)) {
+ return -1;
+ }
+
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
+ if (base::android::IsSelectiveJniRegistrationEnabled(env)) {
+ base::android::SetJniRegistrationType(
+ base::android::SELECTIVE_JNI_REGISTRATION);
+ }
+ if (!android::OnJNIOnLoadRegisterJNI(env)) {
+ return -1;
+ }
+ base::android::SetNativeInitializationHook(NativeInit);
+ return JNI_VERSION_1_4;
+}
diff --git a/chrome/browser/media/android/remote/remote_media_player_bridge.cc b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
index 531e3f4..6c3e609 100644
--- a/chrome/browser/media/android/remote/remote_media_player_bridge.cc
+++ b/chrome/browser/media/android/remote/remote_media_player_bridge.cc
@@ -262,7 +262,6 @@
// static
bool RemoteMediaPlayerBridge::RegisterRemoteMediaPlayerBridge(JNIEnv* env) {
bool ret = RegisterNativesImpl(env);
- DCHECK(g_RemoteMediaPlayerBridge_clazz);
return ret;
}
diff --git a/chrome/browser/media/android/router/media_router_android_bridge.cc b/chrome/browser/media/android/router/media_router_android_bridge.cc
index e56bbb5..4c57cde 100644
--- a/chrome/browser/media/android/router/media_router_android_bridge.cc
+++ b/chrome/browser/media/android/router/media_router_android_bridge.cc
@@ -29,7 +29,6 @@
// static
bool MediaRouterAndroidBridge::Register(JNIEnv* env) {
bool ret = RegisterNativesImpl(env);
- DCHECK(g_ChromeMediaRouter_clazz);
return ret;
}
diff --git a/chromecast/BUILD.gn b/chromecast/BUILD.gn
index 08cbad2..3d10c9cd 100644
--- a/chromecast/BUILD.gn
+++ b/chromecast/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/buildflag_header.gni")
import("//build/config/features.gni")
import("//build/config/sanitizers/sanitizers.gni")
@@ -481,6 +482,11 @@
}
if (is_android) {
+ generate_jni_registration("cast_shell_jni_registration") {
+ target = ":cast_shell_apk"
+ output = "$root_gen_dir/chromecast/android/${target_name}.h"
+ exception_files = jni_exception_files
+ }
android_assets("cast_shell_apk_assets") {
assert(v8_use_external_startup_data)
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn
index 1d29974..321a3d2 100644
--- a/chromecast/android/BUILD.gn
+++ b/chromecast/android/BUILD.gn
@@ -27,6 +27,7 @@
deps = [
":platform_jni_loader",
"//base",
+ "//chromecast:cast_shell_jni_registration",
"//chromecast:cast_shell_lib",
"//chromecast:chromecast_features",
"//chromecast/app",
diff --git a/chromecast/app/android/cast_jni_loader.cc b/chromecast/app/android/cast_jni_loader.cc
index 79a32fe..73b829bb 100644
--- a/chromecast/app/android/cast_jni_loader.cc
+++ b/chromecast/app/android/cast_jni_loader.cc
@@ -6,6 +6,7 @@
#include "base/android/library_loader/library_loader_hooks.h"
#include "base/bind.h"
#include "chromecast/android/cast_jni_registrar.h"
+#include "chromecast/android/cast_shell_jni_registration.h"
#include "chromecast/android/platform_jni_loader.h"
#include "chromecast/app/cast_main_delegate.h"
#include "chromecast/browser/android/jni_registrar.h"
@@ -42,6 +43,12 @@
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
!NativeInit()) {
return -1;
diff --git a/components/cronet/android/BUILD.gn b/components/cronet/android/BUILD.gn
index b5f646d..230ecf0 100644
--- a/components/cronet/android/BUILD.gn
+++ b/components/cronet/android/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/buildflag_header.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
@@ -25,6 +26,12 @@
jni_package = "cronet"
}
+generate_jni_registration("cronet_jni_registration") {
+ target = ":cronet_sample_apk"
+ output = "$root_gen_dir/components/cronet/android/${target_name}.h"
+ exception_files = jni_exception_files
+}
+
java_cpp_enum("effective_connection_type_java") {
sources = [
"//net/nqe/effective_connection_type.h",
@@ -165,6 +172,7 @@
deps = [
":cronet_android_cert_proto",
":cronet_jni_headers",
+ ":cronet_jni_registration",
":cronet_version_header",
"//base",
"//base/third_party/dynamic_annotations",
@@ -532,6 +540,9 @@
]
include_dirs = [ _cronet_version_header_include_dir ]
+
+ configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+ configs += [ "//build/config/android:hide_all_but_jni" ]
}
android_resources("cronet_test_apk_resources") {
diff --git a/components/cronet/android/cronet_library_loader.cc b/components/cronet/android/cronet_library_loader.cc
index 72c416e..b7aa07a 100644
--- a/components/cronet/android/cronet_library_loader.cc
+++ b/components/cronet/android/cronet_library_loader.cc
@@ -19,6 +19,7 @@
#include "base/message_loop/message_loop.h"
#include "base/metrics/statistics_recorder.h"
#include "components/cronet/android/cronet_bidirectional_stream_adapter.h"
+#include "components/cronet/android/cronet_jni_registration.h"
#include "components/cronet/android/cronet_upload_data_stream_adapter.h"
#include "components/cronet/android/cronet_url_request_adapter.h"
#include "components/cronet/android/cronet_url_request_context_adapter.h"
@@ -84,6 +85,11 @@
jint CronetOnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (!RegisterJNI(env) || !NativeInit()) {
return -1;
}
diff --git a/content/shell/android/BUILD.gn b/content/shell/android/BUILD.gn
index 2a0443ee..2c140859 100644
--- a/content/shell/android/BUILD.gn
+++ b/content/shell/android/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//third_party/icu/config.gni")
@@ -15,10 +16,18 @@
]
}
+generate_jni_registration("content_shell_jni_registration") {
+ testonly = true
+ target = ":content_shell_apk"
+ output = "$root_gen_dir/content/shell/android/${target_name}.h"
+ exception_files = jni_exception_files
+}
+
shared_library("libcontent_shell_content_view") {
testonly = true
deps = [
":content_shell_jni_headers",
+ ":content_shell_jni_registration",
"//build/config:exe_and_shlib_deps",
"//components/crash/content/browser",
"//content/shell:content_shell_lib",
@@ -26,6 +35,17 @@
"//media",
"//skia",
]
+
+ # Explicit dependency required for JNI registration to be able to
+ # find the native side functions.
+ if (is_component_build) {
+ deps += [
+ "//device/gamepad",
+ "//device/generic_sensor",
+ "//device/sensors",
+ "//media/midi",
+ ]
+ }
sources = [
"shell_library_loader.cc",
]
@@ -242,6 +262,7 @@
deps = [
":linker_test_jni_headers",
+ ":linker_test_jni_registration",
"//build/config:exe_and_shlib_deps",
"//content/shell:content_shell_lib",
@@ -250,6 +271,17 @@
"//skia",
"//third_party/re2",
]
+
+ # Explicit dependency required for JNI registration to be able to
+ # find the native side functions.
+ if (is_component_build) {
+ deps += [
+ "//device/gamepad",
+ "//device/generic_sensor",
+ "//device/sensors",
+ "//media/midi",
+ ]
+ }
}
generate_jni("linker_test_jni_headers") {
@@ -259,6 +291,14 @@
"linker_test_apk/src/org/chromium/chromium_linker_test_apk/LinkerTests.java",
]
}
+
+ generate_jni_registration("linker_test_jni_registration") {
+ testonly = true
+ target = ":chromium_linker_test_apk__apk"
+ output =
+ "$root_gen_dir/content/shell/android/linker_test_apk/${target_name}.h"
+ exception_files = jni_exception_files
+ }
}
android_library("content_shell_browsertests_java") {
diff --git a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
index 19f9c47..310bb2a 100644
--- a/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
+++ b/content/shell/android/linker_test_apk/chromium_linker_test_android.cc
@@ -9,6 +9,7 @@
#include "content/public/app/content_main.h"
#include "content/public/browser/android/compositor.h"
#include "content/shell/android/linker_test_apk/chromium_linker_test_linker_tests.h"
+#include "content/shell/android/linker_test_apk/linker_test_jni_registration.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
@@ -40,6 +41,11 @@
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
!NativeInit()) {
return -1;
diff --git a/content/shell/android/shell_library_loader.cc b/content/shell/android/shell_library_loader.cc
index dc88bd67..aaf1b55a 100644
--- a/content/shell/android/shell_library_loader.cc
+++ b/content/shell/android/shell_library_loader.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright 2012 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.
@@ -8,6 +8,7 @@
#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/content_shell_jni_registration.h"
#include "content/shell/android/shell_jni_registrar.h"
#include "content/shell/app/shell_main_delegate.h"
@@ -33,6 +34,12 @@
JNI_EXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (!content::android::OnJNIOnLoadRegisterJNI(env) || !RegisterJNI(env) ||
!NativeInit()) {
return -1;
diff --git a/mojo/android/BUILD.gn b/mojo/android/BUILD.gn
index 525e7fc..179eb6f 100644
--- a/mojo/android/BUILD.gn
+++ b/mojo/android/BUILD.gn
@@ -140,6 +140,8 @@
"//mojo/public/cpp/test_support:test_utils",
]
defines = [ "UNIT_TEST" ]
+ configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+ configs += [ "//build/config/android:hide_all_but_jni" ]
}
instrumentation_test_apk("mojo_test_apk") {
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn
index f855f47..8ef6f7c 100644
--- a/net/android/BUILD.gn
+++ b/net/android/BUILD.gn
@@ -109,6 +109,9 @@
":java_test_native_support",
"//net:test_support",
]
+
+ configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+ configs += [ "//build/config/android:hide_all_but_jni" ]
}
android_apk("net_test_support_apk") {
diff --git a/remoting/android/BUILD.gn b/remoting/android/BUILD.gn
index 248c1ea0..46798cb 100644
--- a/remoting/android/BUILD.gn
+++ b/remoting/android/BUILD.gn
@@ -2,6 +2,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import("//base/android/jni_generator/jni_exception_list.gni")
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
import("//remoting/android/client_java_tmpl.gni")
@@ -20,6 +21,12 @@
jni_package = "remoting"
}
+generate_jni_registration("remoting_jni_registration") {
+ target = ":remoting_apk"
+ output = "$root_gen_dir/remoting/client/${target_name}.h"
+ exception_files = jni_exception_files
+}
+
_raw_resources_base_dir = "$target_gen_dir/credits_resources_raw/res"
# The target is named this way, instead of "..._raw_resources", specifically
diff --git a/remoting/client/jni/BUILD.gn b/remoting/client/jni/BUILD.gn
index f0f8082..6f10926 100644
--- a/remoting/client/jni/BUILD.gn
+++ b/remoting/client/jni/BUILD.gn
@@ -19,6 +19,7 @@
shared_library("remoting_client_jni") {
deps = [
"//remoting/android:jni_headers",
+ "//remoting/android:remoting_jni_registration",
"//remoting/base",
"//remoting/client",
"//remoting/client/display",
diff --git a/remoting/client/jni/remoting_jni_onload.cc b/remoting/client/jni/remoting_jni_onload.cc
index 9db79a8..dd1a283d 100644
--- a/remoting/client/jni/remoting_jni_onload.cc
+++ b/remoting/client/jni/remoting_jni_onload.cc
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "net/android/net_jni_registrar.h"
#include "remoting/client/jni/remoting_jni_registrar.h"
+#include "remoting/client/remoting_jni_registration.h"
#include "ui/gfx/android/gfx_jni_registrar.h"
namespace {
@@ -32,6 +33,12 @@
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved) {
base::android::InitVM(vm);
JNIEnv* env = base::android::AttachCurrentThread();
+ if (!RegisterMainDexNatives(env) || !RegisterNonMainDexNatives(env)) {
+ return -1;
+ }
+
+ // TODO(agrieve): Delete this block, this is a no-op now.
+ // https://crbug.com/683256.
if (!RegisterJNI(env) || !base::android::OnJNIOnLoadInit()) {
return -1;
}
diff --git a/testing/test.gni b/testing/test.gni
index 36e0d91..64619b3 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -63,7 +63,7 @@
# the default shared_library configs rather than executable configs.
configs -= [
"//build/config:shared_library_config",
- "//build/config/android:hide_all_but_jni_onload",
+ "//build/config/android:hide_all_but_jni",
]
configs += [ "//build/config:executable_config" ]
@@ -321,6 +321,8 @@
set_defaults("test") {
if (is_android) {
configs = default_shared_library_configs
+ configs -= [ "//build/config/android:hide_all_but_jni_onload" ]
+ configs += [ "//build/config/android:hide_all_but_jni" ]
} else {
configs = default_executable_configs
}