Reland: [Android JNI] Generate calls to RegisterNatives()

Reverted in: Ibbb98c136baaf016a9b26b3e614ca96e8a408c41

Reason for reland: Selective JNI registration is fixed by:
If97814bc5d79cfaa0211e46f785dbab329429d22

There is no change on this CL since reverted.

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
Cq-Include-Trybots: master.tryserver.chromium.android:android_cronet_tester
Change-Id: Ibdb983b4ba07cf7e2b23a4c1706213175acfa7bf
Reviewed-on: https://chromium-review.googlesource.com/553157
Reviewed-by: Andrew Grieve <agrieve@chromium.org>
Commit-Queue: Yipeng Wang <yipengw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#483150}

CrOS-Libchrome-Original-Commit: 5510546e55d45b802b20c9b67a7f2de010602e47
diff --git a/base/android/jni_generator/SampleForTests_jni.golden b/base/android/jni_generator/SampleForTests_jni.golden
index 7b38425..e50583a 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_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..53629a6 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..febb5b7
--- /dev/null
+++ b/base/android/jni_generator/jni_registration_generator.py
@@ -0,0 +1,179 @@
+#!/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..03aac48 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 3362c92..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 ef618da..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,