[go: nahoru, domu]

jni_generator: Allow stub GEN_JNI generation from .py instead of annotation processor

And convert //base to use it instead of the annotation processor

Also reworks naming of test goldens and makes REBASELINE=1
delete obsolete ones.

Bug: 1410871
Change-Id: Ibebefff2d0f4e892c5ca4b65a195f3f1ef3e9f43
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4544941
Commit-Queue: Andrew Grieve <agrieve@chromium.org>
Auto-Submit: Andrew Grieve <agrieve@chromium.org>
Owners-Override: Andrew Grieve <agrieve@chromium.org>
Reviewed-by: Sam Maier <smaier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1149739}
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 44c4e04..0f331df5 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -1385,7 +1385,10 @@
       "android/trace_event_binding.cc",
       "android/trace_event_binding.h",
     ]
-    deps += [ ":base_jni_headers" ]
+    deps += [
+      ":base_jni",
+      ":process_launcher_jni",
+    ]
   }  # is_android || is_robolectric
 
   # Chromeos.
@@ -2916,7 +2919,7 @@
       "profiler/stack_sampling_profiler_java_test_util.h",
     ]
     deps += [
-      ":base_profiler_test_support_jni_headers",
+      ":base_profiler_test_support_jni",
       ":native_unwinder_android",
     ]
   }
@@ -3633,7 +3636,7 @@
       deps += [
         ":base_profiler_reparsing_test_support_library",
         ":base_profiler_test_support_java",
-        ":base_profiler_test_support_jni_headers",
+        ":base_profiler_test_support_jni",
         ":base_profiler_test_support_library",
         ":native_unwinder_android",
       ]
@@ -4091,7 +4094,7 @@
 }
 
 if (is_android || is_robolectric) {
-  generate_jni("base_jni_headers") {
+  generate_jni("base_jni") {
     sources = [
       "android/java/src/org/chromium/base/ApkAssets.java",
       "android/java/src/org/chromium/base/ApplicationStatus.java",
@@ -4132,7 +4135,6 @@
       "android/java/src/org/chromium/base/memory/MemoryInfoBridge.java",
       "android/java/src/org/chromium/base/metrics/NativeUmaRecorder.java",
       "android/java/src/org/chromium/base/metrics/StatisticsRecorderAndroid.java",
-      "android/java/src/org/chromium/base/process_launcher/ChildProcessService.java",
       "android/java/src/org/chromium/base/task/PostTask.java",
       "android/java/src/org/chromium/base/task/TaskRunnerImpl.java",
     ]
@@ -4151,6 +4153,10 @@
     classes = [ "java/lang/Runnable.class" ]
     unchecked_exceptions = true
   }
+
+  generate_jni("process_launcher_jni") {
+    sources = [ "android/java/src/org/chromium/base/process_launcher/ChildProcessService.java" ]
+  }
 }  # is_android || is_robolectric
 
 if (is_android) {
@@ -4193,7 +4199,10 @@
   }
 
   android_library("process_launcher_java") {
-    srcjar_deps = [ ":process_launcher_aidl" ]
+    srcjar_deps = [
+      ":process_launcher_aidl",
+      ":process_launcher_jni",
+    ]
     deps = [
       ":base_java",
       ":jni_java",
@@ -4218,13 +4227,12 @@
       "android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java",
       "android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java",
     ]
-
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   }
 
   android_library("base_java") {
     srcjar_deps = [
       ":base_android_java_enums_srcjar",
+      ":base_jni",
       ":java_features_srcjar",
       ":java_switches_srcjar",
     ]
@@ -4364,8 +4372,6 @@
       sources += [ "android/java/src/org/chromium/base/IntentUtils.java" ]
     }
 
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
-
     resources_package = "org.chromium.base"
 
     proguard_configs = [
@@ -4429,20 +4435,19 @@
       "android/javatests/src/org/chromium/base/test/metrics/HistogramWatcherWithoutNativeTest.java",
       "android/javatests/src/org/chromium/base/util/GarbageCollectionTestUtilsTest.java",
     ]
-
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+    srcjar_deps = [ ":base_javatests_jni" ]
   }
 
   source_set("base_javatests_lib") {
     testonly = true
     deps = [
       ":base",
-      ":base_javatests_jni_headers",
+      ":base_javatests_jni",
     ]
     sources = [ "test/library_loader/early_native_test_helper.cc" ]
   }
 
-  generate_jni("base_javatests_jni_headers") {
+  generate_jni("base_javatests_jni") {
     testonly = true
     sources = [ "android/javatests/src/org/chromium/base/library_loader/EarlyNativeTest.java" ]
   }
@@ -4460,7 +4465,6 @@
       "//third_party/androidx:androidx_annotation_annotation_java",
       "//third_party/junit:junit",
     ]
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   }
 
   android_library("base_java_test_support") {
@@ -4562,7 +4566,14 @@
       "test/android/javatests/src/org/chromium/base/test/util/TimeoutTimer.java",
       "test/android/javatests/src/org/chromium/base/test/util/UserActionTester.java",
     ]
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+  }
+
+  generate_jni("base_java_test_support_uncommon_jni") {
+    testonly = true
+    sources = [
+      "test/android/javatests/src/org/chromium/base/test/ReachedCodeProfiler.java",
+      "test/android/javatests/src/org/chromium/base/test/task/ThreadPoolTestHelpers.java",
+    ]
   }
 
   android_library("base_java_test_support_uncommon") {
@@ -4577,6 +4588,7 @@
       "//third_party/junit:junit",
     ]
 
+    srcjar_deps = [ ":base_java_test_support_uncommon_jni" ]
     sources = [
       "test/android/javatests/src/org/chromium/base/FakeTimeTestRule.java",
       "test/android/javatests/src/org/chromium/base/test/BundleTestRule.java",
@@ -4589,8 +4601,6 @@
       "test/android/javatests/src/org/chromium/base/test/util/InstrumentationUtils.java",
       "test/android/javatests/src/org/chromium/base/test/util/Matchers.java",
     ]
-
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
   }
 
   android_library("base_java_process_launcher_test_support") {
@@ -4710,7 +4720,7 @@
     }
   }
 
-  generate_jni("base_profiler_test_support_jni_headers") {
+  generate_jni("base_profiler_test_support_jni") {
     testonly = true
     sources =
         [ "android/javatests/src/org/chromium/base/profiler/TestSupport.java" ]
@@ -4720,8 +4730,7 @@
     testonly = true
     sources =
         [ "android/javatests/src/org/chromium/base/profiler/TestSupport.java" ]
-
-    annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+    srcjar_deps = [ ":base_profiler_test_support_jni" ]
 
     deps = [
       "//base:jni_java",
diff --git a/base/android/apk_assets.cc b/base/android/apk_assets.cc
index 7a1b1d18..3953b68c 100644
--- a/base/android/apk_assets.cc
+++ b/base/android/apk_assets.cc
@@ -9,7 +9,7 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/base_jni_headers/ApkAssets_jni.h"
+#include "base/base_jni/ApkAssets_jni.h"
 #include "base/file_descriptor_store.h"
 
 namespace base {
diff --git a/base/android/application_status_listener.cc b/base/android/application_status_listener.cc
index 464343f..2228c47 100644
--- a/base/android/application_status_listener.cc
+++ b/base/android/application_status_listener.cc
@@ -6,7 +6,7 @@
 
 #include <jni.h>
 
-#include "base/base_jni_headers/ApplicationStatus_jni.h"
+#include "base/base_jni/ApplicationStatus_jni.h"
 #include "base/functional/callback.h"
 #include "base/lazy_instance.h"
 #include "base/metrics/user_metrics.h"
diff --git a/base/android/base_feature_list.cc b/base/android/base_feature_list.cc
index 349c543..9d1b6bdc 100644
--- a/base/android/base_feature_list.cc
+++ b/base/android/base_feature_list.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/base_features.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/BaseFeatureList_jni.h"
+#include "base/base_jni/BaseFeatureList_jni.h"
 #include "base/feature_list.h"
 #include "base/notreached.h"
 
diff --git a/base/android/build_info.cc b/base/android/build_info.cc
index ff52fda..d6c295d 100644
--- a/base/android/build_info.cc
+++ b/base/android/build_info.cc
@@ -9,7 +9,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/base_jni_headers/BuildInfo_jni.h"
+#include "base/base_jni/BuildInfo_jni.h"
 #include "base/check_op.h"
 #include "base/memory/singleton.h"
 #include "base/notreached.h"
diff --git a/base/android/bundle_utils.cc b/base/android/bundle_utils.cc
index 800e97bc..9a376a4 100644
--- a/base/android/bundle_utils.cc
+++ b/base/android/bundle_utils.cc
@@ -9,7 +9,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/BundleUtils_jni.h"
+#include "base/base_jni/BundleUtils_jni.h"
 #include "base/check.h"
 #include "base/files/file_path.h"
 #include "base/notreached.h"
diff --git a/base/android/callback_android.cc b/base/android/callback_android.cc
index d3f6da5..df609db 100644
--- a/base/android/callback_android.cc
+++ b/base/android/callback_android.cc
@@ -7,7 +7,7 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/base_jni_headers/Callback_jni.h"
+#include "base/base_jni/Callback_jni.h"
 #include "base/time/time.h"
 
 namespace base {
diff --git a/base/android/child_process_service.cc b/base/android/child_process_service.cc
index 5b853c8..e86e072 100644
--- a/base/android/child_process_service.cc
+++ b/base/android/child_process_service.cc
@@ -5,11 +5,11 @@
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/library_loader/library_loader_hooks.h"
-#include "base/base_jni_headers/ChildProcessService_jni.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/file_descriptor_store.h"
 #include "base/logging.h"
 #include "base/posix/global_descriptors.h"
+#include "base/process_launcher_jni/ChildProcessService_jni.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 using base::android::JavaIntArrayToIntVector;
diff --git a/base/android/command_line_android.cc b/base/android/command_line_android.cc
index 75783d3..dd61d6d 100644
--- a/base/android/command_line_android.cc
+++ b/base/android/command_line_android.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/CommandLine_jni.h"
+#include "base/base_jni/CommandLine_jni.h"
 #include "base/command_line.h"
 
 using base::android::ConvertUTF8ToJavaString;
diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc
index c3fb589e..2ab50fc 100644
--- a/base/android/content_uri_utils.cc
+++ b/base/android/content_uri_utils.cc
@@ -6,7 +6,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/ContentUriUtils_jni.h"
+#include "base/base_jni/ContentUriUtils_jni.h"
 
 using base::android::ConvertUTF8ToJavaString;
 using base::android::ScopedJavaLocalRef;
diff --git a/base/android/cpu_features.cc b/base/android/cpu_features.cc
index a29ed6e..31d74d0 100644
--- a/base/android/cpu_features.cc
+++ b/base/android/cpu_features.cc
@@ -5,7 +5,7 @@
 #include <cpu-features.h>
 
 #include "base/android/jni_android.h"
-#include "base/base_jni_headers/CpuFeatures_jni.h"
+#include "base/base_jni/CpuFeatures_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/early_trace_event_binding.cc b/base/android/early_trace_event_binding.cc
index c40508b0..34bab452 100644
--- a/base/android/early_trace_event_binding.cc
+++ b/base/android/early_trace_event_binding.cc
@@ -8,7 +8,7 @@
 
 #include "base/android/jni_string.h"
 #include "base/android/trace_event_binding.h"
-#include "base/base_jni_headers/EarlyTraceEvent_jni.h"
+#include "base/base_jni/EarlyTraceEvent_jni.h"
 #include "base/time/time.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/tracing_buildflags.h"
diff --git a/base/android/event_log.cc b/base/android/event_log.cc
index 7f99d66..66ef6ec1 100644
--- a/base/android/event_log.cc
+++ b/base/android/event_log.cc
@@ -3,7 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/android/event_log.h"
-#include "base/base_jni_headers/EventLog_jni.h"
+#include "base/base_jni/EventLog_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/feature_list_jni.cc b/base/android/feature_list_jni.cc
index bb10d3c..403cc926 100644
--- a/base/android/feature_list_jni.cc
+++ b/base/android/feature_list_jni.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/base_jni_headers/FeatureList_jni.h"
+#include "base/base_jni/FeatureList_jni.h"
 #include "base/feature_list.h"
 
 namespace base {
diff --git a/base/android/feature_map.cc b/base/android/feature_map.cc
index a4aa03f..5110ac2 100644
--- a/base/android/feature_map.cc
+++ b/base/android/feature_map.cc
@@ -12,7 +12,7 @@
 
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/FeatureMap_jni.h"
+#include "base/base_jni/FeatureMap_jni.h"
 #include "base/metrics/field_trial_params.h"
 #include "base/notreached.h"
 
diff --git a/base/android/features_jni.cc b/base/android/features_jni.cc
index 0128651..8e3e25a 100644
--- a/base/android/features_jni.cc
+++ b/base/android/features_jni.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/base_jni_headers/Features_jni.h"
+#include "base/base_jni/Features_jni.h"
 #include "base/android/jni_string.h"
 #include "base/feature_list.h"
 #include "base/metrics/field_trial_params.h"
diff --git a/base/android/field_trial_list.cc b/base/android/field_trial_list.cc
index d2b01fca..5f29475 100644
--- a/base/android/field_trial_list.cc
+++ b/base/android/field_trial_list.cc
@@ -8,7 +8,7 @@
 #include <string>
 
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/FieldTrialList_jni.h"
+#include "base/base_jni/FieldTrialList_jni.h"
 #include "base/lazy_instance.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_list_including_low_anonymity.h"
diff --git a/base/android/important_file_writer_android.cc b/base/android/important_file_writer_android.cc
index 4ccc088..00ef000 100644
--- a/base/android/important_file_writer_android.cc
+++ b/base/android/important_file_writer_android.cc
@@ -6,7 +6,7 @@
 
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/ImportantFileWriterAndroid_jni.h"
+#include "base/base_jni/ImportantFileWriterAndroid_jni.h"
 #include "base/files/important_file_writer.h"
 #include "base/threading/thread_restrictions.h"
 
diff --git a/base/android/int_string_callback.cc b/base/android/int_string_callback.cc
index 4ad27b64..06d3e32 100644
--- a/base/android/int_string_callback.cc
+++ b/base/android/int_string_callback.cc
@@ -11,7 +11,7 @@
 #include <jni.h>
 
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/IntStringCallback_jni.h"
+#include "base/base_jni/IntStringCallback_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/java_exception_reporter.cc b/base/android/java_exception_reporter.cc
index 395e976..8c078e4 100644
--- a/base/android/java_exception_reporter.cc
+++ b/base/android/java_exception_reporter.cc
@@ -7,7 +7,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/base_jni_headers/JavaExceptionReporter_jni.h"
+#include "base/base_jni/JavaExceptionReporter_jni.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
diff --git a/base/android/java_handler_thread.cc b/base/android/java_handler_thread.cc
index 74fb75b..4118a09 100644
--- a/base/android/java_handler_thread.cc
+++ b/base/android/java_handler_thread.cc
@@ -8,7 +8,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/JavaHandlerThread_jni.h"
+#include "base/base_jni/JavaHandlerThread_jni.h"
 #include "base/functional/bind.h"
 #include "base/message_loop/message_pump.h"
 #include "base/message_loop/message_pump_type.h"
diff --git a/base/android/java_heap_dump_generator.cc b/base/android/java_heap_dump_generator.cc
index f618895..51cb700 100644
--- a/base/android/java_heap_dump_generator.cc
+++ b/base/android/java_heap_dump_generator.cc
@@ -7,7 +7,7 @@
 #include <jni.h>
 
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/JavaHeapDumpGenerator_jni.h"
+#include "base/base_jni/JavaHeapDumpGenerator_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/jni_android.cc b/base/android/jni_android.cc
index 0ddd543..704c4ac 100644
--- a/base/android/jni_android.cc
+++ b/base/android/jni_android.cc
@@ -10,7 +10,7 @@
 #include "base/android/java_exception_reporter.h"
 #include "base/android/jni_string.h"
 #include "base/android/jni_utils.h"
-#include "base/base_jni_headers/PiiElider_jni.h"
+#include "base/base_jni/PiiElider_jni.h"
 #include "base/debug/debugging_buildflags.h"
 #include "base/logging.h"
 #include "build/build_config.h"
diff --git a/base/android/jni_generator/codegen/placeholder_gen_jni_java.py b/base/android/jni_generator/codegen/placeholder_gen_jni_java.py
new file mode 100644
index 0000000..3f5bf59
--- /dev/null
+++ b/base/android/jni_generator/codegen/placeholder_gen_jni_java.py
@@ -0,0 +1,29 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+def Generate(jni_objs, *, gen_jni_class, script_name):
+  sb = []
+  sb.append(f"""\
+//
+// This file is a placeholder. It was generated by {script_name}
+//
+
+package {gen_jni_class.package_with_dots};
+
+public class {gen_jni_class.name} {{
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+""")
+
+  for jni_obj in jni_objs:
+    for native in jni_obj.proxy_natives:
+      sig_params = ', '.join(f'{p.datatype} {p.name}'
+                             for p in native.proxy_params)
+      sb.append(f"""
+  public static native {native.proxy_return_type} {native.proxy_name}\
+({sig_params});""")
+
+  sb.append('\n}\n')
+  return ''.join(sb)
diff --git a/base/android/jni_generator/codegen/proxy_impl_java.py b/base/android/jni_generator/codegen/proxy_impl_java.py
new file mode 100644
index 0000000..3edaa539
--- /dev/null
+++ b/base/android/jni_generator/codegen/proxy_impl_java.py
@@ -0,0 +1,77 @@
+# Copyright 2023 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+
+def Generate(jni_obj, *, gen_jni_class, script_name):
+  visibility = 'public ' if jni_obj.proxy_interface.is_public else ''
+  interface_name = jni_obj.proxy_interface.name_with_dots
+  impl_name = f'{jni_obj.java_class.name}Jni'
+
+  sb = []
+  sb.append(f"""\
+//
+// This file was generated by {script_name}
+//
+package {jni_obj.java_class.package_with_dots};
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import {gen_jni_class.full_name_with_dots};
+""")
+
+  # Copy over all imports (some will be unused, but oh well).
+  for java_class in jni_obj.type_resolver.imports:
+    sb.append(f'import {java_class.full_name_with_dots};\n')
+
+  sb.append(f"""
+@CheckDiscard("crbug.com/993421")
+{visibility}class {impl_name} implements {interface_name} {{
+  private static {interface_name} testInstance;
+
+  public static final JniStaticTestMocker<{interface_name}> TEST_HOOKS =
+      new JniStaticTestMocker<{interface_name}>() {{
+    @Override
+    public void setInstanceForTesting({interface_name} instance) {{
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {{
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }}
+      testInstance = instance;
+    }}
+  }};
+""")
+
+  for native in jni_obj.proxy_natives:
+    call_params = ', '.join(p.name for p in native.params)
+    sig_params = ', '.join(f'{p.datatype} {p.name}' for p in native.params)
+    return_prefix = ''
+    if native.return_type != 'void':
+      return_prefix = f'return ({native.return_type}) '
+
+    sb.append(f"""
+  @Override
+  public {native.return_type} {native.name}({sig_params}) {{
+    {return_prefix}GEN_JNI.{native.proxy_name}({call_params});
+  }}
+""")
+
+  sb.append(f"""
+  public static {interface_name} get() {{
+    if (GEN_JNI.TESTING_ENABLED) {{
+      if (testInstance != null) {{
+        return testInstance;
+      }}
+      if (GEN_JNI.REQUIRE_MOCK) {{
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of {interface_name}. "
+            + "The current configuration requires implementations be mocked.");
+      }}
+    }}
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new {impl_name}();
+  }}
+}}
+""")
+  return ''.join(sb)
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_GenJni.java.golden b/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_GenJni.java.golden
deleted file mode 100644
index 5ed4615..0000000
--- a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_GenJni.java.golden
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package this.is.a.package.prefix.org.chromium.base.natives;
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_registration_generator.py
-// Please do not change its content.
-
-public class GEN_JNI {
-    public static final boolean TESTING_ENABLED = false;
-    public static final boolean REQUIRE_MOCK = false;
-
-
-    public static void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_foo() {
-        this.is.a.package.prefix.J.N.MGfHLNVl();
-    }
-
-    public static Object this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_bar(Object sample) {
-        return this.is.a.package.prefix.J.N.M5EfCheU(sample);
-    }
-
-    public static String this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_revString(String stringToReverse) {
-        return this.is.a.package.prefix.J.N.MXQefv1w(stringToReverse);
-    }
-
-    public static String[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_sendToNative(String[] strs) {
-        return this.is.a.package.prefix.J.N.MSYtnUBS(strs);
-    }
-
-    public static Object[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_sendSamplesToNative(Object[] strs) {
-        return this.is.a.package.prefix.J.N.MaV5G8K8(strs);
-    }
-
-    public static boolean this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_hasPhalange() {
-        return this.is.a.package.prefix.J.N.MM2Yz6XD();
-    }
-
-    public static int[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_testAllPrimitives(int zint, int[] ints, long zlong, long[] longs, short zshort, short[] shorts, char zchar, char[] chars, byte zbyte, byte[] bytes, double zdouble, double[] doubles, float zfloat, float[] floats, boolean zbool, boolean[] bools) {
-        return this.is.a.package.prefix.J.N.MMy4dcxH(zint, ints, zlong, longs, zshort, shorts, zchar, chars, zbyte, bytes, zdouble, doubles, zfloat, floats, zbool, bools);
-    }
-
-    public static void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_testSpecialTypes(Class clazz, Class[] classes, Throwable throwable, Throwable[] throwables, String string, String[] strings, Object tStruct, Object[] structs, Object obj, Object[] objects) {
-        this.is.a.package.prefix.J.N.MSslZIsy(clazz, classes, throwable, throwables, string, strings, tStruct, structs, obj, objects);
-    }
-
-    public static Throwable this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnThrowable() {
-        return this.is.a.package.prefix.J.N.Mehs9t7u();
-    }
-
-    public static Throwable[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnThrowables() {
-        return this.is.a.package.prefix.J.N.MQH82FhP();
-    }
-
-    public static Class this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnClass() {
-        return this.is.a.package.prefix.J.N.MyxAHj2Y();
-    }
-
-    public static Class[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnClasses() {
-        return this.is.a.package.prefix.J.N.MNGv55Cm();
-    }
-
-    public static String this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnString() {
-        return this.is.a.package.prefix.J.N.Mysjo$pl();
-    }
-
-    public static String[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStrings() {
-        return this.is.a.package.prefix.J.N.M3B287zk();
-    }
-
-    public static Object this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStruct() {
-        return this.is.a.package.prefix.J.N.M8UGsyhL();
-    }
-
-    public static Object[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStructs() {
-        return this.is.a.package.prefix.J.N.MtYMX5wX();
-    }
-
-    public static Object this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnObject() {
-        return this.is.a.package.prefix.J.N.MIs8T9aQ();
-    }
-
-    public static Object[] this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnObjects() {
-        return this.is.a.package.prefix.J.N.MtkQGyRy();
-    }
-}
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_JN.java.golden b/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_JN.java.golden
deleted file mode 100644
index d30733e..0000000
--- a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual_JN.java.golden
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package this.is.a.package.prefix.J;
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_registration_generator.py
-// Please do not change its content.
-
-public class N {
-
-
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_foo
-      public static native void MGfHLNVl();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_bar
-      public static native Object M5EfCheU(Object sample);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_revString
-      public static native String MXQefv1w(String stringToReverse);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_sendToNative
-      public static native String[] MSYtnUBS(String[] strs);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_sendSamplesToNative
-      public static native Object[] MaV5G8K8(Object[] strs);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_hasPhalange
-      public static native boolean MM2Yz6XD();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_testAllPrimitives
-      public static native int[] MMy4dcxH(int zint, int[] ints, long zlong, long[] longs, short zshort, short[] shorts, char zchar, char[] chars, byte zbyte, byte[] bytes, double zdouble, double[] doubles, float zfloat, float[] floats, boolean zbool, boolean[] bools);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_testSpecialTypes
-      public static native void MSslZIsy(Class clazz, Class[] classes, Throwable throwable, Throwable[] throwables, String string, String[] strings, Object tStruct, Object[] structs, Object obj, Object[] objects);
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnThrowable
-      public static native Throwable Mehs9t7u();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnThrowables
-      public static native Throwable[] MQH82FhP();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnClass
-      public static native Class MyxAHj2Y();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnClasses
-      public static native Class[] MNGv55Cm();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnString
-      public static native String Mysjo$pl();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStrings
-      public static native String[] M3B287zk();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStruct
-      public static native Object M8UGsyhL();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnStructs
-      public static native Object[] MtYMX5wX();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnObject
-      public static native Object MIs8T9aQ();
-      // Original name: this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForAnnotationProcessor_returnObjects
-      public static native Object[] MtkQGyRy();
-}
diff --git a/base/android/jni_generator/golden/SampleForTestsWithSplit_jni.h.golden b/base/android/jni_generator/golden/SampleForTestsWithSplit_jni.h.golden
deleted file mode 100644
index 65d821a..0000000
--- a/base/android/jni_generator/golden/SampleForTestsWithSplit_jni.h.golden
+++ /dev/null
@@ -1,527 +0,0 @@
-// Copyright 2014 The Chromium Authors
-// 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/example/jni_generator/SampleForTests
-
-#ifndef org_chromium_example_jni_generator_SampleForTests_JNI
-#define org_chromium_example_jni_generator_SampleForTests_JNI
-
-#include <jni.h>
-
-#include "base/android/jni_generator/jni_generator_helper.h"
-
-
-// Step 1: Forward declarations.
-
-JNI_REGISTRATION_EXPORT extern const char
-    kClassPath_org_chromium_example_jni_1generator_SampleForTests[];
-const char kClassPath_org_chromium_example_jni_1generator_SampleForTests[] =
-    "org/chromium/example/jni_generator/SampleForTests";
-
-JNI_REGISTRATION_EXPORT extern const char
-    kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA[];
-const char kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA[] =
-    "org/chromium/example/jni_generator/SampleForTests$InnerStructA";
-
-JNI_REGISTRATION_EXPORT extern const char
-    kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB[];
-const char kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB[] =
-    "org/chromium/example/jni_generator/SampleForTests$InnerStructB";
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-JNI_REGISTRATION_EXPORT std::atomic<jclass>
-    g_org_chromium_example_jni_1generator_SampleForTests_clazz(nullptr);
-#ifndef org_chromium_example_jni_1generator_SampleForTests_clazz_defined
-#define org_chromium_example_jni_1generator_SampleForTests_clazz_defined
-inline jclass org_chromium_example_jni_1generator_SampleForTests_clazz(JNIEnv* env) {
-  return base::android::LazyGetClass(env,
-      kClassPath_org_chromium_example_jni_1generator_SampleForTests,
-      &g_org_chromium_example_jni_1generator_SampleForTests_clazz);
-}
-#endif
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-JNI_REGISTRATION_EXPORT std::atomic<jclass>
-    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(nullptr);
-#ifndef org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz_defined
-#define org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz_defined
-inline jclass org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(JNIEnv*
-    env) {
-  return base::android::LazyGetClass(env,
-      kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA,
-      &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz);
-}
-#endif
-// Leaking this jclass as we cannot use LazyInstance from some threads.
-JNI_REGISTRATION_EXPORT std::atomic<jclass>
-    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(nullptr);
-#ifndef org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz_defined
-#define org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz_defined
-inline jclass org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(JNIEnv*
-    env) {
-  return base::android::LazyGetClass(env,
-      kClassPath_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB,
-      &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz);
-}
-#endif
-
-
-// Step 2: Constants (optional).
-
-
-// Step 3: Method stubs.
-namespace base {
-namespace android {
-
-static jlong JNI_SampleForTests_Init(JNIEnv* env, const base::android::JavaParamRef<jobject>&
-    caller,
-    const base::android::JavaParamRef<jstring>& param);
-
-JNI_GENERATOR_EXPORT jlong
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1init(
-    JNIEnv* env,
-    jclass jcaller,
-    jobject caller,
-    jstring param) {
-  return JNI_SampleForTests_Init(env, base::android::JavaParamRef<jobject>(env, caller),
-      base::android::JavaParamRef<jstring>(env, param));
-}
-
-JNI_GENERATOR_EXPORT void
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1destroy(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeCPPClass,
-    jobject caller) {
-  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
-  CHECK_NATIVE_PTR(env, jcaller, native, "Destroy");
-  return native->Destroy(env, base::android::JavaParamRef<jobject>(env, caller));
-}
-
-static jdouble JNI_SampleForTests_GetDoubleFunction(JNIEnv* env, const
-    base::android::JavaParamRef<jobject>& caller);
-
-JNI_GENERATOR_EXPORT jdouble
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1getDoubleFunction(
-    JNIEnv* env,
-    jclass jcaller,
-    jobject caller) {
-  return JNI_SampleForTests_GetDoubleFunction(env, base::android::JavaParamRef<jobject>(env,
-      caller));
-}
-
-static jfloat JNI_SampleForTests_GetFloatFunction(JNIEnv* env);
-
-JNI_GENERATOR_EXPORT jfloat
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1getFloatFunction(
-    JNIEnv* env,
-    jclass jcaller) {
-  return JNI_SampleForTests_GetFloatFunction(env);
-}
-
-static void JNI_SampleForTests_SetNonPODDatatype(JNIEnv* env, const
-    base::android::JavaParamRef<jobject>& caller,
-    const base::android::JavaParamRef<jobject>& rect);
-
-JNI_GENERATOR_EXPORT void
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1setNonPODDatatype(
-    JNIEnv* env,
-    jclass jcaller,
-    jobject caller,
-    jobject rect) {
-  return JNI_SampleForTests_SetNonPODDatatype(env, base::android::JavaParamRef<jobject>(env,
-      caller), base::android::JavaParamRef<jobject>(env, rect));
-}
-
-static base::android::ScopedJavaLocalRef<jobject> JNI_SampleForTests_GetNonPODDatatype(JNIEnv* env,
-    const base::android::JavaParamRef<jobject>& caller);
-
-JNI_GENERATOR_EXPORT jobject
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1getNonPODDatatype(
-    JNIEnv* env,
-    jclass jcaller,
-    jobject caller) {
-  return JNI_SampleForTests_GetNonPODDatatype(env, base::android::JavaParamRef<jobject>(env,
-      caller)).Release();
-}
-
-JNI_GENERATOR_EXPORT jint
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1method(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeCPPClass,
-    jobject caller) {
-  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
-  CHECK_NATIVE_PTR(env, jcaller, native, "Method", 0);
-  return native->Method(env, base::android::JavaParamRef<jobject>(env, caller));
-}
-
-JNI_GENERATOR_EXPORT jdouble
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1methodOtherP0(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativePtr,
-    jobject caller) {
-  CPPClass::InnerClass* native = reinterpret_cast<CPPClass::InnerClass*>(nativePtr);
-  CHECK_NATIVE_PTR(env, jcaller, native, "MethodOtherP0", 0);
-  return native->MethodOtherP0(env, base::android::JavaParamRef<jobject>(env, caller));
-}
-
-JNI_GENERATOR_EXPORT void
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1addStructB(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeCPPClass,
-    jobject caller,
-    jobject b) {
-  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
-  CHECK_NATIVE_PTR(env, jcaller, native, "AddStructB");
-  return native->AddStructB(env, base::android::JavaParamRef<jobject>(env, caller),
-      base::android::JavaParamRef<jobject>(env, b));
-}
-
-JNI_GENERATOR_EXPORT void
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1iterateAndDoSomethingWithStructB(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeCPPClass,
-    jobject caller) {
-  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
-  CHECK_NATIVE_PTR(env, jcaller, native, "IterateAndDoSomethingWithStructB");
-  return native->IterateAndDoSomethingWithStructB(env, base::android::JavaParamRef<jobject>(env,
-      caller));
-}
-
-JNI_GENERATOR_EXPORT jstring
-    Java_org_chromium_base_natives_GEN_1JNI_org_1chromium_1example_1jni_11generator_1SampleForTests_1returnAString(
-    JNIEnv* env,
-    jclass jcaller,
-    jlong nativeCPPClass,
-    jobject caller) {
-  CPPClass* native = reinterpret_cast<CPPClass*>(nativeCPPClass);
-  CHECK_NATIVE_PTR(env, jcaller, native, "ReturnAString", NULL);
-  return native->ReturnAString(env, base::android::JavaParamRef<jobject>(env, caller)).Release();
-}
-
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_javaMethod(nullptr);
-static jint Java_SampleForTests_javaMethod(JNIEnv* env, const base::android::JavaRef<jobject>& obj,
-    JniIntWrapper foo,
-    JniIntWrapper bar) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env), 0);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "javaMethod",
-          "(II)I",
-          &g_org_chromium_example_jni_1generator_SampleForTests_javaMethod);
-
-  jint ret =
-      env->CallIntMethod(obj.obj(),
-          call_context.base.method_id, as_jint(foo), as_jint(bar));
-  return ret;
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_staticJavaMethod(nullptr);
-static jboolean Java_SampleForTests_staticJavaMethod(JNIEnv* env) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, clazz,
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env), false);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_STATIC>(
-          env,
-          clazz,
-          "staticJavaMethod",
-          "()Z",
-          &g_org_chromium_example_jni_1generator_SampleForTests_staticJavaMethod);
-
-  jboolean ret =
-      env->CallStaticBooleanMethod(clazz,
-          call_context.base.method_id);
-  return ret;
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_packagePrivateJavaMethod(nullptr);
-static void Java_SampleForTests_packagePrivateJavaMethod(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "packagePrivateJavaMethod",
-          "()V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_packagePrivateJavaMethod);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.base.method_id);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_methodWithGenericParams(nullptr);
-static void Java_SampleForTests_methodWithGenericParams(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj, const base::android::JavaRef<jobject>& foo,
-    const base::android::JavaRef<jobject>& bar) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "methodWithGenericParams",
-          "(Ljava/util/Map;Ljava/util/LinkedList;)V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_methodWithGenericParams);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.base.method_id, foo.obj(), bar.obj());
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_Constructor(nullptr);
-static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_Constructor(JNIEnv* env,
-    JniIntWrapper foo,
-    JniIntWrapper bar) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, clazz,
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "<init>",
-          "(II)V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_Constructor);
-
-  jobject ret =
-      env->NewObject(clazz,
-          call_context.base.method_id, as_jint(foo), as_jint(bar));
-  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_methodThatThrowsException(nullptr);
-static void Java_SampleForTests_methodThatThrowsException(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextUnchecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "methodThatThrowsException",
-          "()V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_methodThatThrowsException);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.method_id);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_javaMethodWithAnnotatedParam(nullptr);
-static void Java_SampleForTests_javaMethodWithAnnotatedParam(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj, JniIntWrapper foo,
-    JniIntWrapper bar,
-    JniIntWrapper baz,
-    JniIntWrapper bat) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "javaMethodWithAnnotatedParam",
-          "(IIII)V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_javaMethodWithAnnotatedParam);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.base.method_id, as_jint(foo), as_jint(bar), as_jint(baz), as_jint(bat));
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_create(nullptr);
-static base::android::ScopedJavaLocalRef<jobject> Java_InnerStructA_create(JNIEnv* env, jlong l,
-    JniIntWrapper i,
-    const base::android::JavaRef<jstring>& s) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env);
-  CHECK_CLAZZ(env, clazz,
-      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_STATIC>(
-          env,
-          clazz,
-          "create",
-          "(JILjava/lang/String;)Lorg/chromium/example/jni_generator/SampleForTests$InnerStructA;",
-          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructA_create);
-
-  jobject ret =
-      env->CallStaticObjectMethod(clazz,
-          call_context.base.method_id, l, as_jint(i), s.obj());
-  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_addStructA(nullptr);
-static void Java_SampleForTests_addStructA(JNIEnv* env, const base::android::JavaRef<jobject>& obj,
-    const base::android::JavaRef<jobject>& a) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "addStructA",
-          "(Lorg/chromium/example/jni_generator/SampleForTests$InnerStructA;)V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_addStructA);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.base.method_id, a.obj());
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomething(nullptr);
-static void Java_SampleForTests_iterateAndDoSomething(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env));
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "iterateAndDoSomething",
-          "()V",
-          &g_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomething);
-
-     env->CallVoidMethod(obj.obj(),
-          call_context.base.method_id);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getKey(nullptr);
-static jlong Java_InnerStructB_getKey(JNIEnv* env, const base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), 0);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "getKey",
-          "()J",
-          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getKey);
-
-  jlong ret =
-      env->CallLongMethod(obj.obj(),
-          call_context.base.method_id);
-  return ret;
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getValue(nullptr);
-static base::android::ScopedJavaLocalRef<jstring> Java_InnerStructB_getValue(JNIEnv* env, const
-    base::android::JavaRef<jobject>& obj) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env);
-  CHECK_CLAZZ(env, obj.obj(),
-      org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_INSTANCE>(
-          env,
-          clazz,
-          "getValue",
-          "()Ljava/lang/String;",
-          &g_org_chromium_example_jni_1generator_SampleForTests_00024InnerStructB_getValue);
-
-  jstring ret =
-      static_cast<jstring>(env->CallObjectMethod(obj.obj(),
-          call_context.base.method_id));
-  return base::android::ScopedJavaLocalRef<jstring>(env, ret);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_getInnerInterface(nullptr);
-static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_getInnerInterface(JNIEnv* env)
-    {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, clazz,
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_STATIC>(
-          env,
-          clazz,
-          "getInnerInterface",
-          "()Lorg/chromium/example/jni_generator/SampleForTests$InnerInterface;",
-          &g_org_chromium_example_jni_1generator_SampleForTests_getInnerInterface);
-
-  jobject ret =
-      env->CallStaticObjectMethod(clazz,
-          call_context.base.method_id);
-  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
-}
-
-static std::atomic<jmethodID>
-    g_org_chromium_example_jni_1generator_SampleForTests_getInnerEnum(nullptr);
-static base::android::ScopedJavaLocalRef<jobject> Java_SampleForTests_getInnerEnum(JNIEnv* env) {
-  jclass clazz = org_chromium_example_jni_1generator_SampleForTests_clazz(env);
-  CHECK_CLAZZ(env, clazz,
-      org_chromium_example_jni_1generator_SampleForTests_clazz(env), NULL);
-
-  jni_generator::JniJavaCallContextChecked call_context;
-  call_context.Init<
-      base::android::MethodID::TYPE_STATIC>(
-          env,
-          clazz,
-          "getInnerEnum",
-          "()Lorg/chromium/example/jni_generator/SampleForTests$InnerEnum;",
-          &g_org_chromium_example_jni_1generator_SampleForTests_getInnerEnum);
-
-  jobject ret =
-      env->CallStaticObjectMethod(clazz,
-          call_context.base.method_id);
-  return base::android::ScopedJavaLocalRef<jobject>(env, ret);
-}
-
-}  // namespace android
-}  // namespace base
-
-#endif  // org_chromium_example_jni_generator_SampleForTests_JNI
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_GenJni.java.golden b/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_GenJni.java.golden
deleted file mode 100644
index abec4bf..0000000
--- a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_GenJni.java.golden
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.base.natives;
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_registration_generator.py
-// Please do not change its content.
-
-public class GEN_JNI {
-    public static final boolean TESTING_ENABLED = false;
-    public static final boolean REQUIRE_MOCK = false;
-
-
-    public static void org_chromium_example_jni_1generator_SampleProxyEdgeCases_foo_1_1weirdly_1_1escaped_1name1() {
-        J.N.MV9YSTxh();
-    }
-
-    public static String[][] org_chromium_example_jni_1generator_SampleProxyEdgeCases_crazyTypes(int[] a, Object[][] b) {
-        return J.N.My6x4jXt(a, b);
-    }
-
-    public static void org_chromium_example_jni_1generator_SampleProxyEdgeCases_addStructB(Object caller, Object b) {
-        J.N.MyOkSBQ0(caller, b);
-    }
-
-    public static void org_chromium_example_jni_1generator_SampleProxyEdgeCases_setStringBuilder(Object sb) {
-        J.N.MD8PmkAP(sb);
-    }
-
-    public static void org_chromium_example_jni_1generator_SampleProxyEdgeCases_setBool(Object b, Object i) {
-        J.N.MPgXV$mN(b, i);
-    }
-}
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_JN.java.golden b/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_JN.java.golden
deleted file mode 100644
index db76314..0000000
--- a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_removed_JN.java.golden
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package J;
-
-// This file is autogenerated by
-//     base/android/jni_generator/jni_registration_generator.py
-// Please do not change its content.
-
-public class N {
-
-
-      // Original name: org_chromium_example_jni_1generator_SampleProxyEdgeCases_foo_1_1weirdly_1_1escaped_1name1
-      public static native void MV9YSTxh();
-      // Original name: org_chromium_example_jni_1generator_SampleProxyEdgeCases_crazyTypes
-      public static native String[][] My6x4jXt(int[] a, Object[][] b);
-      // Original name: org_chromium_example_jni_1generator_SampleProxyEdgeCases_addStructB
-      public static native void MyOkSBQ0(Object caller, Object b);
-      // Original name: org_chromium_example_jni_1generator_SampleProxyEdgeCases_setStringBuilder
-      public static native void MD8PmkAP(Object sb);
-      // Original name: org_chromium_example_jni_1generator_SampleProxyEdgeCases_setBool
-      public static native void MPgXV$mN(Object b, Object i);
-}
diff --git a/base/android/jni_generator/golden/SampleForTestsGenJni.java.golden b/base/android/jni_generator/golden/testBidirectionalClass-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForTestsGenJni.java.golden
rename to base/android/jni_generator/golden/testBidirectionalClass-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/testBidirectionalClass-Placeholder-GEN_JNI.java.golden b/base/android/jni_generator/golden/testBidirectionalClass-Placeholder-GEN_JNI.java.golden
new file mode 100644
index 0000000..9afc248
--- /dev/null
+++ b/base/android/jni_generator/golden/testBidirectionalClass-Placeholder-GEN_JNI.java.golden
@@ -0,0 +1,22 @@
+//
+// This file is a placeholder. It was generated by base/android/jni_generator/jni_generator.py
+//
+
+package org.chromium.base.natives;
+
+public class GEN_JNI {
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+
+  public static native long org_chromium_example_jni_1generator_SampleForTests_init(Object caller, String param);
+  public static native void org_chromium_example_jni_1generator_SampleForTests_destroy(long nativeCPPClass, Object caller);
+  public static native double org_chromium_example_jni_1generator_SampleForTests_getDoubleFunction(Object caller);
+  public static native float org_chromium_example_jni_1generator_SampleForTests_getFloatFunction();
+  public static native void org_chromium_example_jni_1generator_SampleForTests_setNonPODDatatype(Object caller, Object rect);
+  public static native Object org_chromium_example_jni_1generator_SampleForTests_getNonPODDatatype(Object caller);
+  public static native int org_chromium_example_jni_1generator_SampleForTests_method(long nativeCPPClass, Object caller);
+  public static native double org_chromium_example_jni_1generator_SampleForTests_methodOtherP0(long nativePtr, Object caller);
+  public static native void org_chromium_example_jni_1generator_SampleForTests_addStructB(long nativeCPPClass, Object caller, Object b);
+  public static native void org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomethingWithStructB(long nativeCPPClass, Object caller);
+  public static native String org_chromium_example_jni_1generator_SampleForTests_returnAString(long nativeCPPClass, Object caller);
+}
diff --git a/base/android/jni_generator/golden/testBidirectionalClass-SampleForTestsJni.java.golden b/base/android/jni_generator/golden/testBidirectionalClass-SampleForTestsJni.java.golden
new file mode 100644
index 0000000..05fcdc3
--- /dev/null
+++ b/base/android/jni_generator/golden/testBidirectionalClass-SampleForTestsJni.java.golden
@@ -0,0 +1,108 @@
+//
+// This file was generated by base/android/jni_generator/jni_generator.py
+//
+package org.chromium.example.jni_generator;
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import org.chromium.base.natives.GEN_JNI;
+import android.graphics.Rect;
+import org.chromium.base.annotations.AccessedByNative;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.CalledByNativeUnchecked;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeClassQualifiedName;
+import org.chromium.base.annotations.NativeMethods;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+@CheckDiscard("crbug.com/993421")
+public class SampleForTestsJni implements SampleForTests.Natives {
+  private static SampleForTests.Natives testInstance;
+
+  public static final JniStaticTestMocker<SampleForTests.Natives> TEST_HOOKS =
+      new JniStaticTestMocker<SampleForTests.Natives>() {
+    @Override
+    public void setInstanceForTesting(SampleForTests.Natives instance) {
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }
+      testInstance = instance;
+    }
+  };
+
+  @Override
+  public long init(SampleForTests caller, String param) {
+    return (long) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_init(caller, param);
+  }
+
+  @Override
+  public void destroy(long nativeCPPClass, SampleForTests caller) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_destroy(nativeCPPClass, caller);
+  }
+
+  @Override
+  public double getDoubleFunction(SampleForTests caller) {
+    return (double) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_getDoubleFunction(caller);
+  }
+
+  @Override
+  public float getFloatFunction() {
+    return (float) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_getFloatFunction();
+  }
+
+  @Override
+  public void setNonPODDatatype(SampleForTests caller, Rect rect) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_setNonPODDatatype(caller, rect);
+  }
+
+  @Override
+  public Object getNonPODDatatype(SampleForTests caller) {
+    return (Object) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_getNonPODDatatype(caller);
+  }
+
+  @Override
+  public int method(long nativeCPPClass, SampleForTests caller) {
+    return (int) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_method(nativeCPPClass, caller);
+  }
+
+  @Override
+  public double methodOtherP0(long nativePtr, SampleForTests caller) {
+    return (double) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_methodOtherP0(nativePtr, caller);
+  }
+
+  @Override
+  public void addStructB(long nativeCPPClass, SampleForTests caller, InnerStructB b) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_addStructB(nativeCPPClass, caller, b);
+  }
+
+  @Override
+  public void iterateAndDoSomethingWithStructB(long nativeCPPClass, SampleForTests caller) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomethingWithStructB(nativeCPPClass, caller);
+  }
+
+  @Override
+  public String returnAString(long nativeCPPClass, SampleForTests caller) {
+    return (String) GEN_JNI.org_chromium_example_jni_1generator_SampleForTests_returnAString(nativeCPPClass, caller);
+  }
+
+  public static SampleForTests.Natives get() {
+    if (GEN_JNI.TESTING_ENABLED) {
+      if (testInstance != null) {
+        return testInstance;
+      }
+      if (GEN_JNI.REQUIRE_MOCK) {
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of SampleForTests.Natives. "
+            + "The current configuration requires implementations be mocked.");
+      }
+    }
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new SampleForTestsJni();
+  }
+}
diff --git a/base/android/jni_generator/golden/SampleForTests_jni.h.golden b/base/android/jni_generator/golden/testBidirectionalClass-SampleForTests_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForTests_jni.h.golden
rename to base/android/jni_generator/golden/testBidirectionalClass-SampleForTests_jni.h.golden
diff --git a/base/android/jni_generator/golden/SampleBidirectionalNonProxy_jni.h.golden b/base/android/jni_generator/golden/testBirectionalNonProxy-SampleBidirectionalNonProxy_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleBidirectionalNonProxy_jni.h.golden
rename to base/android/jni_generator/golden/testBirectionalNonProxy-SampleBidirectionalNonProxy_jni.h.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessorGenJni.golden b/base/android/jni_generator/golden/testEndToEndManualRegistration-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessorGenJni.golden
rename to base/android/jni_generator/golden/testEndToEndManualRegistration-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_manual.h.golden b/base/android/jni_generator/golden/testEndToEndManualRegistration-Registration.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_manual.h.golden
rename to base/android/jni_generator/golden/testEndToEndManualRegistration-Registration.h.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_proxy_GenJni.java.golden b/base/android/jni_generator/golden/testEndToEndProxyHashed-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_proxy_GenJni.java.golden
rename to base/android/jni_generator/golden/testEndToEndProxyHashed-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_proxy_JN.java.golden b/base/android/jni_generator/golden/testEndToEndProxyHashed-Final-N.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_proxy_JN.java.golden
rename to base/android/jni_generator/golden/testEndToEndProxyHashed-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/testEndToEndProxyHashed-Registration.h.golden b/base/android/jni_generator/golden/testEndToEndProxyHashed-Registration.h.golden
new file mode 100644
index 0000000..e364132
--- /dev/null
+++ b/base/android/jni_generator/golden/testEndToEndProxyHashed-Registration.h.golden
@@ -0,0 +1,113 @@
+// Copyright 2017 The Chromium Authors
+// 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 TEMP_DIR_HEADER_
+#define TEMP_DIR_HEADER_
+
+#include <jni.h>
+
+#include <iterator>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+
+// Step 1: Forward declarations (classes).
+
+
+// Step 2: Forward declarations (methods).
+
+JNI_GENERATOR_EXPORT void Java_J_N_MygCV2jQ(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_J_N_MHuqnmXT(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject sample);
+JNI_GENERATOR_EXPORT jstring Java_J_N_MM5Xkwyy(
+    JNIEnv* env,
+    jclass jcaller,
+    jstring stringToReverse);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_MAC2QhR9(
+    JNIEnv* env,
+    jclass jcaller,
+    jobjectArray strs);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_MGhRh4Nd(
+    JNIEnv* env,
+    jclass jcaller,
+    jobjectArray strs);
+JNI_GENERATOR_EXPORT jboolean Java_J_N_MW0aEs4h(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jintArray Java_J_N_MlVFI4RX(
+    JNIEnv* env,
+    jclass jcaller,
+    jint zint,
+    jintArray ints,
+    jlong zlong,
+    jlongArray longs,
+    jshort zshort,
+    jshortArray shorts,
+    jchar zchar,
+    jcharArray chars,
+    jbyte zbyte,
+    jbyteArray bytes,
+    jdouble zdouble,
+    jdoubleArray doubles,
+    jfloat zfloat,
+    jfloatArray floats,
+    jboolean zbool,
+    jbooleanArray bools);
+JNI_GENERATOR_EXPORT void Java_J_N_MqOnlud7(
+    JNIEnv* env,
+    jclass jcaller,
+    jclass clazz,
+    jobjectArray classes,
+    jthrowable throwable,
+    jobjectArray throwables,
+    jstring string,
+    jobjectArray strings,
+    jobject tStruct,
+    jobjectArray structs,
+    jobject obj,
+    jobjectArray objects);
+JNI_GENERATOR_EXPORT jthrowable Java_J_N_MuZc76Vt(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_MAD53J7V(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jclass Java_J_N_M_00024ZgOi4g(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_M_00024hL1577(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jstring Java_J_N_M0k1OjBK(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_Mssfs54E(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_J_N_MSzcel_1H(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_MIBrQLK4(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_J_N_M_00024hPywjv(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_MPpCU1l5(
+    JNIEnv* env,
+    jclass jcaller);
+
+
+
+#endif  // TEMP_DIR_HEADER_
diff --git a/base/android/jni_generator/golden/SampleModuleGenJni.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleModuleGenJni.golden
rename to base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleModuleJN.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Final-N.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleModuleJN.golden
rename to base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Placeholder-GEN_JNI.java.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Placeholder-GEN_JNI.java.golden
new file mode 100644
index 0000000..907a5d1
--- /dev/null
+++ b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Placeholder-GEN_JNI.java.golden
@@ -0,0 +1,13 @@
+//
+// This file is a placeholder. It was generated by base/android/jni_generator/jni_generator.py
+//
+
+package org.chromium.base.natives;
+
+public class module_GEN_JNI {
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+
+  public static native void org_chromium_example_jni_1generator_SampleModule_foo();
+  public static native boolean org_chromium_example_jni_1generator_SampleModule_bar(int a);
+}
diff --git a/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Registration.h.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Registration.h.golden
new file mode 100644
index 0000000..737ee6f
--- /dev/null
+++ b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-Registration.h.golden
@@ -0,0 +1,36 @@
+// Copyright 2017 The Chromium Authors
+// 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 TEMP_DIR_HEADER_
+#define TEMP_DIR_HEADER_
+
+#include <jni.h>
+
+#include <iterator>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+
+// Step 1: Forward declarations (classes).
+
+
+// Step 2: Forward declarations (methods).
+
+JNI_GENERATOR_EXPORT void Java_J_module_1N_M_00024_00024EIl9t(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jboolean Java_J_module_1N_Mc2WZLnF(
+    JNIEnv* env,
+    jclass jcaller,
+    jint a);
+
+
+
+#endif  // TEMP_DIR_HEADER_
diff --git a/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModuleJni.java.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModuleJni.java.golden
new file mode 100644
index 0000000..69aaa31
--- /dev/null
+++ b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModuleJni.java.golden
@@ -0,0 +1,52 @@
+//
+// This file was generated by base/android/jni_generator/jni_generator.py
+//
+package org.chromium.example.jni_generator;
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import org.chromium.base.natives.module_GEN_JNI;
+import org.chromium.base.annotations.NativeMethods;
+
+@CheckDiscard("crbug.com/993421")
+class SampleModuleJni implements SampleModule.Natives {
+  private static SampleModule.Natives testInstance;
+
+  public static final JniStaticTestMocker<SampleModule.Natives> TEST_HOOKS =
+      new JniStaticTestMocker<SampleModule.Natives>() {
+    @Override
+    public void setInstanceForTesting(SampleModule.Natives instance) {
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }
+      testInstance = instance;
+    }
+  };
+
+  @Override
+  public void foo() {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleModule_foo();
+  }
+
+  @Override
+  public boolean bar(int a) {
+    return (boolean) GEN_JNI.org_chromium_example_jni_1generator_SampleModule_bar(a);
+  }
+
+  public static SampleModule.Natives get() {
+    if (GEN_JNI.TESTING_ENABLED) {
+      if (testInstance != null) {
+        return testInstance;
+      }
+      if (GEN_JNI.REQUIRE_MOCK) {
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of SampleModule.Natives. "
+            + "The current configuration requires implementations be mocked.");
+      }
+    }
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new SampleModuleJni();
+  }
+}
diff --git a/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModule_jni.h.golden b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModule_jni.h.golden
new file mode 100644
index 0000000..0729374
--- /dev/null
+++ b/base/android/jni_generator/golden/testEndToEndProxyJniWithModules-SampleModule_jni.h.golden
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors
+// 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/example/jni_generator/SampleModule
+
+#ifndef org_chromium_example_jni_generator_SampleModule_JNI
+#define org_chromium_example_jni_generator_SampleModule_JNI
+
+#include <jni.h>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+
+
+// Step 1: Forward declarations.
+
+
+// Step 2: Constants (optional).
+
+
+// Step 3: Method stubs.
+static void JNI_SampleModule_Foo(JNIEnv* env);
+
+JNI_GENERATOR_EXPORT void Java_J_module_1N_M_00024_00024EIl9t(
+    JNIEnv* env,
+    jclass jcaller) {
+  return JNI_SampleModule_Foo(env);
+}
+
+static jboolean JNI_SampleModule_Bar(JNIEnv* env, jint a);
+
+JNI_GENERATOR_EXPORT jboolean Java_J_module_1N_Mc2WZLnF(
+    JNIEnv* env,
+    jclass jcaller,
+    jint a) {
+  return JNI_SampleModule_Bar(env, a);
+}
+
+
+#endif  // org_chromium_example_jni_generator_SampleModule_JNI
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_GenJni.java.golden b/base/android/jni_generator/golden/testForTestingKept-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_GenJni.java.golden
rename to base/android/jni_generator/golden/testForTestingKept-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_JN.java.golden b/base/android/jni_generator/golden/testForTestingKept-Final-N.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_JN.java.golden
rename to base/android/jni_generator/golden/testForTestingKept-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/testForTestingKept-Placeholder-GEN_JNI.java.golden b/base/android/jni_generator/golden/testForTestingKept-Placeholder-GEN_JNI.java.golden
new file mode 100644
index 0000000..0aa20d9
--- /dev/null
+++ b/base/android/jni_generator/golden/testForTestingKept-Placeholder-GEN_JNI.java.golden
@@ -0,0 +1,18 @@
+//
+// This file is a placeholder. It was generated by base/android/jni_generator/jni_generator.py
+//
+
+package org.chromium.base.natives;
+
+public class GEN_JNI {
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_foo_1_1weirdly_1_1escaped_1name1();
+  public static native String[][] org_chromium_example_jni_1generator_SampleProxyEdgeCases_crazyTypes(int[] a, Object[][] b);
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_fooForTest();
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_fooForTesting();
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_addStructB(Object caller, Object b);
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_setStringBuilder(Object sb);
+  public static native void org_chromium_example_jni_1generator_SampleProxyEdgeCases_setBool(Object b, Object i);
+}
diff --git a/base/android/jni_generator/golden/testForTestingKept-Registration.h.golden b/base/android/jni_generator/golden/testForTestingKept-Registration.h.golden
new file mode 100644
index 0000000..4ed1cf5
--- /dev/null
+++ b/base/android/jni_generator/golden/testForTestingKept-Registration.h.golden
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors
+// 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 TEMP_DIR_HEADER_
+#define TEMP_DIR_HEADER_
+
+#include <jni.h>
+
+#include <iterator>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+
+// Step 1: Forward declarations (classes).
+
+extern const char kClassPath_org_chromium_example_jni_1generator_SampleProxyEdgeCases[];
+extern std::atomic<jclass> g_org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz;
+#ifndef org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz_defined
+#define org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz_defined
+inline jclass org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz(JNIEnv* env) {
+  return base::android::LazyGetClass(env,
+      kClassPath_org_chromium_example_jni_1generator_SampleProxyEdgeCases,
+      &g_org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz);
+}
+#endif
+
+
+// Step 2: Forward declarations (methods).
+
+JNI_GENERATOR_EXPORT void Java_J_N_MV9YSTxh(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_My6x4jXt(
+    JNIEnv* env,
+    jclass jcaller,
+    jintArray a,
+    jobjectArray b);
+JNI_GENERATOR_EXPORT void Java_J_N_M3dXOemX_1ForTesting(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT void Java_J_N_MCNruAwI_1ForTesting(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT void Java_J_N_MyOkSBQ0(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject caller,
+    jobject b);
+JNI_GENERATOR_EXPORT void Java_J_N_MD8PmkAP(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject sb);
+JNI_GENERATOR_EXPORT void Java_J_N_MPgXV_00024mN(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject b,
+    jobject i);
+JNI_GENERATOR_EXPORT void
+    Java_org_chromium_example_jni_1generator_SampleProxyEdgeCases_nativeInstanceMethod(
+    JNIEnv* env,
+    jobject jcaller,
+    jlong nativeInstance);
+JNI_GENERATOR_EXPORT void
+    Java_org_chromium_example_jni_1generator_SampleProxyEdgeCases_nativeStaticMethod(
+    JNIEnv* env,
+    jclass jcaller);
+
+
+
+#endif  // TEMP_DIR_HEADER_
diff --git a/base/android/jni_generator/golden/testForTestingKept-SampleProxyEdgeCasesJni.java.golden b/base/android/jni_generator/golden/testForTestingKept-SampleProxyEdgeCasesJni.java.golden
new file mode 100644
index 0000000..9580215
--- /dev/null
+++ b/base/android/jni_generator/golden/testForTestingKept-SampleProxyEdgeCasesJni.java.golden
@@ -0,0 +1,77 @@
+//
+// This file was generated by base/android/jni_generator/jni_generator.py
+//
+package org.chromium.example.jni_generator;
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import org.chromium.base.natives.GEN_JNI;
+import org.chromium.example.jni_generator.Boolean;
+
+@CheckDiscard("crbug.com/993421")
+class SampleProxyEdgeCasesJni implements SampleProxyEdgeCases.Natives {
+  private static SampleProxyEdgeCases.Natives testInstance;
+
+  public static final JniStaticTestMocker<SampleProxyEdgeCases.Natives> TEST_HOOKS =
+      new JniStaticTestMocker<SampleProxyEdgeCases.Natives>() {
+    @Override
+    public void setInstanceForTesting(SampleProxyEdgeCases.Natives instance) {
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }
+      testInstance = instance;
+    }
+  };
+
+  @Override
+  public void foo__weirdly__escaped_name1() {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_foo_1_1weirdly_1_1escaped_1name1();
+  }
+
+  @Override
+  public String[][] crazyTypes(int[] a, Object[][] b) {
+    return (String[][]) GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_crazyTypes(a, b);
+  }
+
+  @Override
+  public void fooForTest() {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_fooForTest();
+  }
+
+  @Override
+  public void fooForTesting() {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_fooForTesting();
+  }
+
+  @Override
+  public void addStructB(SampleForTests caller, SampleForTests.InnerStructB b) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_addStructB(caller, b);
+  }
+
+  @Override
+  public void setStringBuilder(StringBuilder sb) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_setStringBuilder(sb);
+  }
+
+  @Override
+  public void setBool(Boolean b, Integer i) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleProxyEdgeCases_setBool(b, i);
+  }
+
+  public static SampleProxyEdgeCases.Natives get() {
+    if (GEN_JNI.TESTING_ENABLED) {
+      if (testInstance != null) {
+        return testInstance;
+      }
+      if (GEN_JNI.REQUIRE_MOCK) {
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of SampleProxyEdgeCases.Natives. "
+            + "The current configuration requires implementations be mocked.");
+      }
+    }
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new SampleProxyEdgeCasesJni();
+  }
+}
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_jni.h.golden b/base/android/jni_generator/golden/testForTestingKept-SampleProxyEdgeCases_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_jni.h.golden
rename to base/android/jni_generator/golden/testForTestingKept-SampleProxyEdgeCases_jni.h.golden
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_GenJni.java.golden b/base/android/jni_generator/golden/testForTestingRemoved-Final-GEN_JNI.java.golden
similarity index 100%
copy from base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_GenJni.java.golden
copy to base/android/jni_generator/golden/testForTestingRemoved-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_JN.java.golden b/base/android/jni_generator/golden/testForTestingRemoved-Final-N.java.golden
similarity index 100%
copy from base/android/jni_generator/golden/SampleProxyEdgeCases_test_kept_JN.java.golden
copy to base/android/jni_generator/golden/testForTestingRemoved-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/testForTestingRemoved-Registration.h.golden b/base/android/jni_generator/golden/testForTestingRemoved-Registration.h.golden
new file mode 100644
index 0000000..4ed1cf5
--- /dev/null
+++ b/base/android/jni_generator/golden/testForTestingRemoved-Registration.h.golden
@@ -0,0 +1,77 @@
+// Copyright 2017 The Chromium Authors
+// 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 TEMP_DIR_HEADER_
+#define TEMP_DIR_HEADER_
+
+#include <jni.h>
+
+#include <iterator>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+
+// Step 1: Forward declarations (classes).
+
+extern const char kClassPath_org_chromium_example_jni_1generator_SampleProxyEdgeCases[];
+extern std::atomic<jclass> g_org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz;
+#ifndef org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz_defined
+#define org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz_defined
+inline jclass org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz(JNIEnv* env) {
+  return base::android::LazyGetClass(env,
+      kClassPath_org_chromium_example_jni_1generator_SampleProxyEdgeCases,
+      &g_org_chromium_example_jni_1generator_SampleProxyEdgeCases_clazz);
+}
+#endif
+
+
+// Step 2: Forward declarations (methods).
+
+JNI_GENERATOR_EXPORT void Java_J_N_MV9YSTxh(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_J_N_My6x4jXt(
+    JNIEnv* env,
+    jclass jcaller,
+    jintArray a,
+    jobjectArray b);
+JNI_GENERATOR_EXPORT void Java_J_N_M3dXOemX_1ForTesting(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT void Java_J_N_MCNruAwI_1ForTesting(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT void Java_J_N_MyOkSBQ0(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject caller,
+    jobject b);
+JNI_GENERATOR_EXPORT void Java_J_N_MD8PmkAP(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject sb);
+JNI_GENERATOR_EXPORT void Java_J_N_MPgXV_00024mN(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject b,
+    jobject i);
+JNI_GENERATOR_EXPORT void
+    Java_org_chromium_example_jni_1generator_SampleProxyEdgeCases_nativeInstanceMethod(
+    JNIEnv* env,
+    jobject jcaller,
+    jlong nativeInstance);
+JNI_GENERATOR_EXPORT void
+    Java_org_chromium_example_jni_1generator_SampleProxyEdgeCases_nativeStaticMethod(
+    JNIEnv* env,
+    jclass jcaller);
+
+
+
+#endif  // TEMP_DIR_HEADER_
diff --git a/base/android/jni_generator/golden/SampleNonProxy_class_file_jni.h.golden b/base/android/jni_generator/golden/testFromClassFile-SampleNonProxy_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleNonProxy_class_file_jni.h.golden
rename to base/android/jni_generator/golden/testFromClassFile-SampleNonProxy_jni.h.golden
diff --git a/base/android/jni_generator/golden/TinySample_full_stubs_GenJni.java.golden b/base/android/jni_generator/golden/testFullStubs-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/TinySample_full_stubs_GenJni.java.golden
rename to base/android/jni_generator/golden/testFullStubs-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing_GenJni.java.golden b/base/android/jni_generator/golden/testMultiplexing-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing_GenJni.java.golden
rename to base/android/jni_generator/golden/testMultiplexing-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing_JN.java.golden b/base/android/jni_generator/golden/testMultiplexing-Final-N.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing_JN.java.golden
rename to base/android/jni_generator/golden/testMultiplexing-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing.h.golden b/base/android/jni_generator/golden/testMultiplexing-Registration.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_multiplexing.h.golden
rename to base/android/jni_generator/golden/testMultiplexing-Registration.h.golden
diff --git a/base/android/jni_generator/golden/SampleNonProxy_jni.h.golden b/base/android/jni_generator/golden/testNonProxy-SampleNonProxy_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleNonProxy_jni.h.golden
rename to base/android/jni_generator/golden/testNonProxy-SampleNonProxy_jni.h.golden
diff --git a/base/android/jni_generator/golden/testPackagePrefixGenerator-Placeholder-GEN_JNI.java.golden b/base/android/jni_generator/golden/testPackagePrefixGenerator-Placeholder-GEN_JNI.java.golden
new file mode 100644
index 0000000..105487a
--- /dev/null
+++ b/base/android/jni_generator/golden/testPackagePrefixGenerator-Placeholder-GEN_JNI.java.golden
@@ -0,0 +1,22 @@
+//
+// This file is a placeholder. It was generated by base/android/jni_generator/jni_generator.py
+//
+
+package this.is.a.package.prefix.org.chromium.base.natives;
+
+public class GEN_JNI {
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+
+  public static native long this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_init(Object caller, String param);
+  public static native void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_destroy(long nativeCPPClass, Object caller);
+  public static native double this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getDoubleFunction(Object caller);
+  public static native float this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getFloatFunction();
+  public static native void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_setNonPODDatatype(Object caller, Object rect);
+  public static native Object this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getNonPODDatatype(Object caller);
+  public static native int this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_method(long nativeCPPClass, Object caller);
+  public static native double this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_methodOtherP0(long nativePtr, Object caller);
+  public static native void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_addStructB(long nativeCPPClass, Object caller, Object b);
+  public static native void this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomethingWithStructB(long nativeCPPClass, Object caller);
+  public static native String this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_returnAString(long nativeCPPClass, Object caller);
+}
diff --git a/base/android/jni_generator/golden/testPackagePrefixGenerator-SampleForTestsJni.java.golden b/base/android/jni_generator/golden/testPackagePrefixGenerator-SampleForTestsJni.java.golden
new file mode 100644
index 0000000..79375a5
--- /dev/null
+++ b/base/android/jni_generator/golden/testPackagePrefixGenerator-SampleForTestsJni.java.golden
@@ -0,0 +1,108 @@
+//
+// This file was generated by base/android/jni_generator/jni_generator.py
+//
+package this.is.a.package.prefix.org.chromium.example.jni_generator;
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import this.is.a.package.prefix.org.chromium.base.natives.GEN_JNI;
+import android.graphics.Rect;
+import org.chromium.base.annotations.AccessedByNative;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.annotations.CalledByNativeUnchecked;
+import org.chromium.base.annotations.JNINamespace;
+import org.chromium.base.annotations.NativeClassQualifiedName;
+import org.chromium.base.annotations.NativeMethods;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+@CheckDiscard("crbug.com/993421")
+public class SampleForTestsJni implements SampleForTests.Natives {
+  private static SampleForTests.Natives testInstance;
+
+  public static final JniStaticTestMocker<SampleForTests.Natives> TEST_HOOKS =
+      new JniStaticTestMocker<SampleForTests.Natives>() {
+    @Override
+    public void setInstanceForTesting(SampleForTests.Natives instance) {
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }
+      testInstance = instance;
+    }
+  };
+
+  @Override
+  public long init(SampleForTests caller, String param) {
+    return (long) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_init(caller, param);
+  }
+
+  @Override
+  public void destroy(long nativeCPPClass, SampleForTests caller) {
+    GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_destroy(nativeCPPClass, caller);
+  }
+
+  @Override
+  public double getDoubleFunction(SampleForTests caller) {
+    return (double) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getDoubleFunction(caller);
+  }
+
+  @Override
+  public float getFloatFunction() {
+    return (float) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getFloatFunction();
+  }
+
+  @Override
+  public void setNonPODDatatype(SampleForTests caller, Rect rect) {
+    GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_setNonPODDatatype(caller, rect);
+  }
+
+  @Override
+  public Object getNonPODDatatype(SampleForTests caller) {
+    return (Object) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_getNonPODDatatype(caller);
+  }
+
+  @Override
+  public int method(long nativeCPPClass, SampleForTests caller) {
+    return (int) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_method(nativeCPPClass, caller);
+  }
+
+  @Override
+  public double methodOtherP0(long nativePtr, SampleForTests caller) {
+    return (double) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_methodOtherP0(nativePtr, caller);
+  }
+
+  @Override
+  public void addStructB(long nativeCPPClass, SampleForTests caller, InnerStructB b) {
+    GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_addStructB(nativeCPPClass, caller, b);
+  }
+
+  @Override
+  public void iterateAndDoSomethingWithStructB(long nativeCPPClass, SampleForTests caller) {
+    GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_iterateAndDoSomethingWithStructB(nativeCPPClass, caller);
+  }
+
+  @Override
+  public String returnAString(long nativeCPPClass, SampleForTests caller) {
+    return (String) GEN_JNI.this_is_a_package_prefix_org_chromium_example_jni_1generator_SampleForTests_returnAString(nativeCPPClass, caller);
+  }
+
+  public static SampleForTests.Natives get() {
+    if (GEN_JNI.TESTING_ENABLED) {
+      if (testInstance != null) {
+        return testInstance;
+      }
+      if (GEN_JNI.REQUIRE_MOCK) {
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of SampleForTests.Natives. "
+            + "The current configuration requires implementations be mocked.");
+      }
+    }
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new SampleForTestsJni();
+  }
+}
diff --git a/base/android/jni_generator/golden/SampleForTests_package_prefix_jni.h.golden b/base/android/jni_generator/golden/testPackagePrefixGenerator-SampleForTests_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForTests_package_prefix_jni.h.golden
rename to base/android/jni_generator/golden/testPackagePrefixGenerator-SampleForTests_jni.h.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_manual_GenJni.java.golden b/base/android/jni_generator/golden/testPackagePrefixWithManualRegistration-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_manual_GenJni.java.golden
rename to base/android/jni_generator/golden/testPackagePrefixWithManualRegistration-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_manual.h.golden b/base/android/jni_generator/golden/testPackagePrefixWithManualRegistration-Registration.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_manual.h.golden
rename to base/android/jni_generator/golden/testPackagePrefixWithManualRegistration-Registration.h.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_GenJni.java.golden b/base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Final-GEN_JNI.java.golden
similarity index 100%
copy from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_GenJni.java.golden
copy to base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_JN.java.golden b/base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Final-N.java.golden
similarity index 100%
copy from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_JN.java.golden
copy to base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual.h.golden b/base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Registration.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_manual.h.golden
rename to base/android/jni_generator/golden/testPackagePrefixWithManualRegistrationWithProxyHash-Registration.h.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_GenJni.java.golden b/base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_GenJni.java.golden
rename to base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_JN.java.golden b/base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Final-N.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleForAnnotationProcessor_package_prefix_proxy_JN.java.golden
rename to base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Final-N.java.golden
diff --git a/base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Registration.h.golden b/base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Registration.h.golden
new file mode 100644
index 0000000..c92b36ef
--- /dev/null
+++ b/base/android/jni_generator/golden/testPackagePrefixWithProxyHash-Registration.h.golden
@@ -0,0 +1,113 @@
+// Copyright 2017 The Chromium Authors
+// 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 TEMP_DIR_HEADER_
+#define TEMP_DIR_HEADER_
+
+#include <jni.h>
+
+#include <iterator>
+
+#include "base/android/jni_generator/jni_generator_helper.h"
+#include "base/android/jni_int_wrapper.h"
+
+
+// Step 1: Forward declarations (classes).
+
+
+// Step 2: Forward declarations (methods).
+
+JNI_GENERATOR_EXPORT void Java_this_is_a_package_prefix_J_N_MGfHLNVl(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_this_is_a_package_prefix_J_N_M5EfCheU(
+    JNIEnv* env,
+    jclass jcaller,
+    jobject sample);
+JNI_GENERATOR_EXPORT jstring Java_this_is_a_package_prefix_J_N_MXQefv1w(
+    JNIEnv* env,
+    jclass jcaller,
+    jstring stringToReverse);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MSYtnUBS(
+    JNIEnv* env,
+    jclass jcaller,
+    jobjectArray strs);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MaV5G8K8(
+    JNIEnv* env,
+    jclass jcaller,
+    jobjectArray strs);
+JNI_GENERATOR_EXPORT jboolean Java_this_is_a_package_prefix_J_N_MM2Yz6XD(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jintArray Java_this_is_a_package_prefix_J_N_MMy4dcxH(
+    JNIEnv* env,
+    jclass jcaller,
+    jint zint,
+    jintArray ints,
+    jlong zlong,
+    jlongArray longs,
+    jshort zshort,
+    jshortArray shorts,
+    jchar zchar,
+    jcharArray chars,
+    jbyte zbyte,
+    jbyteArray bytes,
+    jdouble zdouble,
+    jdoubleArray doubles,
+    jfloat zfloat,
+    jfloatArray floats,
+    jboolean zbool,
+    jbooleanArray bools);
+JNI_GENERATOR_EXPORT void Java_this_is_a_package_prefix_J_N_MSslZIsy(
+    JNIEnv* env,
+    jclass jcaller,
+    jclass clazz,
+    jobjectArray classes,
+    jthrowable throwable,
+    jobjectArray throwables,
+    jstring string,
+    jobjectArray strings,
+    jobject tStruct,
+    jobjectArray structs,
+    jobject obj,
+    jobjectArray objects);
+JNI_GENERATOR_EXPORT jthrowable Java_this_is_a_package_prefix_J_N_Mehs9t7u(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MQH82FhP(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jclass Java_this_is_a_package_prefix_J_N_MyxAHj2Y(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MNGv55Cm(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jstring Java_this_is_a_package_prefix_J_N_Mysjo_00024pl(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_M3B287zk(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_this_is_a_package_prefix_J_N_M8UGsyhL(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MtYMX5wX(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobject Java_this_is_a_package_prefix_J_N_MIs8T9aQ(
+    JNIEnv* env,
+    jclass jcaller);
+JNI_GENERATOR_EXPORT jobjectArray Java_this_is_a_package_prefix_J_N_MtkQGyRy(
+    JNIEnv* env,
+    jclass jcaller);
+
+
+
+#endif  // TEMP_DIR_HEADER_
diff --git a/base/android/jni_generator/golden/TinySample_enable_mocks_GenJni.java.golden b/base/android/jni_generator/golden/testProxyMocks-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/TinySample_enable_mocks_GenJni.java.golden
rename to base/android/jni_generator/golden/testProxyMocks-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/TinySample_require_mocks_GenJni.java.golden b/base/android/jni_generator/golden/testRequireProxyMocks-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/TinySample_require_mocks_GenJni.java.golden
rename to base/android/jni_generator/golden/testRequireProxyMocks-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/StubGenJni.golden b/base/android/jni_generator/golden/testStubRegistration-Final-GEN_JNI.java.golden
similarity index 100%
rename from base/android/jni_generator/golden/StubGenJni.golden
rename to base/android/jni_generator/golden/testStubRegistration-Final-GEN_JNI.java.golden
diff --git a/base/android/jni_generator/golden/testUniqueAnnotations-Placeholder-GEN_JNI.java.golden b/base/android/jni_generator/golden/testUniqueAnnotations-Placeholder-GEN_JNI.java.golden
new file mode 100644
index 0000000..e18e85af
--- /dev/null
+++ b/base/android/jni_generator/golden/testUniqueAnnotations-Placeholder-GEN_JNI.java.golden
@@ -0,0 +1,13 @@
+//
+// This file is a placeholder. It was generated by base/android/jni_generator/jni_generator.py
+//
+
+package org.chromium.base.natives;
+
+public class GEN_JNI {
+  public static boolean TESTING_ENABLED;
+  public static boolean REQUIRE_MOCK;
+
+  public static native void org_chromium_example_jni_1generator_SampleUniqueAnnotations_foo(long nativePtr);
+  public static native int org_chromium_example_jni_1generator_SampleUniqueAnnotations_bar(int x, int y);
+}
diff --git a/base/android/jni_generator/golden/testUniqueAnnotations-SampleUniqueAnnotationsJni.java.golden b/base/android/jni_generator/golden/testUniqueAnnotations-SampleUniqueAnnotationsJni.java.golden
new file mode 100644
index 0000000..c230c19
--- /dev/null
+++ b/base/android/jni_generator/golden/testUniqueAnnotations-SampleUniqueAnnotationsJni.java.golden
@@ -0,0 +1,51 @@
+//
+// This file was generated by base/android/jni_generator/jni_generator.py
+//
+package org.chromium.example.jni_generator;
+
+import org.chromium.build.annotations.CheckDiscard;
+import org.chromium.base.JniStaticTestMocker;
+import org.chromium.base.NativeLibraryLoadedStatus;
+import org.chromium.base.natives.GEN_JNI;
+
+@CheckDiscard("crbug.com/993421")
+class SampleUniqueAnnotationsJni implements SampleUniqueAnnotations.Natives {
+  private static SampleUniqueAnnotations.Natives testInstance;
+
+  public static final JniStaticTestMocker<SampleUniqueAnnotations.Natives> TEST_HOOKS =
+      new JniStaticTestMocker<SampleUniqueAnnotations.Natives>() {
+    @Override
+    public void setInstanceForTesting(SampleUniqueAnnotations.Natives instance) {
+      if (!org.chromium.base.natives.GEN_JNI.TESTING_ENABLED) {
+        throw new RuntimeException(
+            "Tried to set a JNI mock when mocks aren't enabled!");
+      }
+      testInstance = instance;
+    }
+  };
+
+  @Override
+  public void foo(long nativePtr) {
+    GEN_JNI.org_chromium_example_jni_1generator_SampleUniqueAnnotations_foo(nativePtr);
+  }
+
+  @Override
+  public int bar(int x, int y) {
+    return (int) GEN_JNI.org_chromium_example_jni_1generator_SampleUniqueAnnotations_bar(x, y);
+  }
+
+  public static SampleUniqueAnnotations.Natives get() {
+    if (GEN_JNI.TESTING_ENABLED) {
+      if (testInstance != null) {
+        return testInstance;
+      }
+      if (GEN_JNI.REQUIRE_MOCK) {
+        throw new UnsupportedOperationException(
+            "No mock found for the native implementation of SampleUniqueAnnotations.Natives. "
+            + "The current configuration requires implementations be mocked.");
+      }
+    }
+    NativeLibraryLoadedStatus.checkLoaded();
+    return new SampleUniqueAnnotationsJni();
+  }
+}
diff --git a/base/android/jni_generator/golden/SampleUniqueAnnotations_jni.h.golden b/base/android/jni_generator/golden/testUniqueAnnotations-SampleUniqueAnnotations_jni.h.golden
similarity index 100%
rename from base/android/jni_generator/golden/SampleUniqueAnnotations_jni.h.golden
rename to base/android/jni_generator/golden/testUniqueAnnotations-SampleUniqueAnnotations_jni.h.golden
diff --git a/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java b/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
index c41c05ab..dc1f271 100644
--- a/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
+++ b/base/android/jni_generator/java/src/org/chromium/example/jni_generator/SampleForTests.java
@@ -226,7 +226,7 @@
     // The following methods demonstrate declaring methods to call into C++ from Java.
     // The generator detects the type and name of the first parameter.
     @NativeMethods
-    interface Natives {
+    public interface Natives {
         // This declares a C++ function which the application code must implement:
         // static jint Init(JNIEnv* env, jobject caller);
         // The jobject parameter refers back to this java side object instance.
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 1cb0b13..3e0adb8 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -37,7 +37,10 @@
 
 from util import build_utils
 import action_helpers  # build_utils adds //build to sys.path.
+import zip_helpers  # build_utils adds //build to sys.path.
 
+from codegen import placeholder_gen_jni_java
+from codegen import proxy_impl_java
 import common
 import models
 import parse
@@ -576,6 +579,7 @@
     self.type_resolver = parsed_file.type_resolver
     self.jni_namespace = parsed_file.jni_namespace or options.namespace
     self.module_name = parsed_file.module_name
+    self.proxy_interface = parsed_file.proxy_interface
 
     proxy_natives = []
     for parsed_method in parsed_file.proxy_methods:
@@ -1190,6 +1194,25 @@
   return ret
 
 
+def _CreateSrcJar(srcjar_path, gen_jni_class, jni_objs, *, script_name):
+  with action_helpers.atomic_output(srcjar_path) as f:
+    with zipfile.ZipFile(f, 'w') as srcjar:
+      for jni_obj in jni_objs:
+        if not jni_obj.proxy_natives:
+          continue
+        content = proxy_impl_java.Generate(jni_obj,
+                                           gen_jni_class=gen_jni_class,
+                                           script_name=script_name)
+        zip_path = f'{jni_obj.java_class.full_name_with_slashes}Jni.java'
+        zip_helpers.add_to_zip_hermetic(srcjar, zip_path, data=content)
+
+      content = placeholder_gen_jni_java.Generate(jni_objs,
+                                                  gen_jni_class=gen_jni_class,
+                                                  script_name=script_name)
+      zip_path = f'{gen_jni_class.full_name_with_slashes}.java'
+      zip_helpers.add_to_zip_hermetic(srcjar, zip_path, data=content)
+
+
 def DoGeneration(options):
   try:
     if options.jar_file:
@@ -1213,6 +1236,23 @@
     with action_helpers.atomic_output(output_file, 'w') as f:
       f.write(content)
 
+  # Write .srcjar
+  if options.srcjar_path:
+    # module_name is set only for proxy_natives.
+    jni_objs = [x for x in jni_objs if x.proxy_natives]
+    if jni_objs:
+      gen_jni_class = proxy.get_gen_jni_class(
+          short=False,
+          name_prefix=jni_objs[0].module_name,
+          package_prefix=options.package_prefix)
+      _CreateSrcJar(options.srcjar_path,
+                    gen_jni_class,
+                    jni_objs,
+                    script_name=GetScriptName())
+    else:
+      # Only @CalledByNatives.
+      zipfile.ZipFile(options.srcjar_path, 'w').close()
+
 
 def main():
   description = """
@@ -1252,6 +1292,8 @@
                       action='append',
                       dest='output_names',
                       help='Output filenames within output directory.')
+  parser.add_argument('--srcjar-path',
+                      help='Path to output srcjar for generated .java files.')
   parser.add_argument(
       '--includes',
       help='The comma-separated list of header files to '
diff --git a/base/android/jni_generator/jni_generator.pydeps b/base/android/jni_generator/jni_generator.pydeps
index 377f664..05a8200 100644
--- a/base/android/jni_generator/jni_generator.pydeps
+++ b/base/android/jni_generator/jni_generator.pydeps
@@ -4,6 +4,9 @@
 ../../../build/android/gyp/util/__init__.py
 ../../../build/android/gyp/util/build_utils.py
 ../../../build/gn_helpers.py
+../../../build/zip_helpers.py
+codegen/placeholder_gen_jni_java.py
+codegen/proxy_impl_java.py
 common.py
 java_lang_classes.py
 jni_generator.py
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index 2fd5b30..eca48a1 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -14,7 +14,7 @@
 import collections
 import copy
 import difflib
-import inspect
+import glob
 import logging
 import os
 import pathlib
@@ -26,13 +26,16 @@
 import zipfile
 
 _SCRIPT_DIR = os.path.normpath(os.path.dirname(__file__))
+_GOLDENS_DIR = os.path.join(_SCRIPT_DIR, 'golden')
 _INCLUDES = ('base/android/jni_generator/jni_generator_helper.h')
-_JAVA_SRC_DIR = os.path.join('java', 'src', 'org', 'chromium', 'example',
-                             'jni_generator')
+_JAVA_SRC_DIR = os.path.join(_SCRIPT_DIR, 'java', 'src', 'org', 'chromium',
+                             'example', 'jni_generator')
 
 # Set this environment variable in order to regenerate the golden text
 # files.
-_REBASELINE_ENV = 'REBASELINE'
+_REBASELINE = os.environ.get('REBASELINE', '0') != '0'
+
+_accessed_goldens = set()
 
 
 class CommonOptions:
@@ -49,13 +52,15 @@
 
 
 class JniGeneratorOptions(CommonOptions):
-  def __init__(self):
+  def __init__(self, **kwargs):
     super().__init__()
     self.includes = _INCLUDES
     self.input_file = None
     self.jar_file = None
+    self.module_name = ''
     self.output_dir = None
     self.output_name = 'output.h'
+    self.__dict__.update(kwargs)
 
   def to_args(self):
     ret = super().to_args()
@@ -76,7 +81,7 @@
 class JniRegistrationGeneratorOptions(CommonOptions):
   """The mock options object which is passed to the jni_generator.py script."""
 
-  def __init__(self):
+  def __init__(self, **kwargs):
     super().__init__()
     self.add_stubs_for_missing_native = False
     self.enable_proxy_mocks = False
@@ -86,6 +91,7 @@
     self.module_name = ''
     self.remove_uncalled_methods = False
     self.require_mocks = False
+    self.__dict__.update(kwargs)
 
   def to_args(self):
     ret = super().to_args()
@@ -114,12 +120,44 @@
     return ret
 
 
+def _MakePrefixes(options):
+  package_prefix = ''
+  if options.package_prefix:
+    package_prefix = options.package_prefix.replace('.', '/') + '/'
+  module_prefix = ''
+  if options.module_name:
+    module_prefix = f'{options.module_name}_'
+  return package_prefix, module_prefix
+
+
 class BaseTest(unittest.TestCase):
 
-  def _TestEndToEndGeneration(self, input_file, options, golden):
+  def _CheckSrcjarGoldens(self, srcjar_path, name_to_goldens):
+    with zipfile.ZipFile(srcjar_path, 'r') as srcjar:
+      self.assertEqual(set(srcjar.namelist()), set(name_to_goldens))
+      for name in srcjar.namelist():
+        self.assertTrue(
+            name in name_to_goldens,
+            f'Found {name} output, but not present in name_to_goldens map.')
+        contents = srcjar.read(name).decode('utf-8')
+        self.AssertGoldenTextEquals(contents, name_to_goldens[name])
+
+  def _TestEndToEndGeneration(self, input_file, *, srcjar=False, **kwargs):
+    golden_name = self._testMethodName
+    options = JniGeneratorOptions(**kwargs)
+    basename = os.path.splitext(input_file)[0]
+    header_golden = f'{golden_name}-{basename}_jni.h.golden'
+    if srcjar:
+      dir_prefix, file_prefix = _MakePrefixes(options)
+      name_to_goldens = {
+          f'{dir_prefix}org/chromium/base/natives/{file_prefix}GEN_JNI.java':
+          f'{golden_name}-Placeholder-GEN_JNI.java.golden',
+          f'{dir_prefix}org/chromium/example/jni_generator/{basename}Jni.java':
+          f'{golden_name}-{basename}Jni.java.golden',
+      }
+
     with tempfile.TemporaryDirectory() as tdir:
-      relative_input_file = self._JoinScriptDir(
-          os.path.join(_JAVA_SRC_DIR, input_file))
+      relative_input_file = os.path.join(_JAVA_SRC_DIR, input_file)
       if input_file.endswith('.class'):
         jar_path = os.path.join(tdir, 'input.jar')
         with zipfile.ZipFile(jar_path, 'w') as z:
@@ -130,35 +168,53 @@
         options.input_file = relative_input_file
 
       options.output_dir = tdir
-      cmd = [self._JoinScriptDir('jni_generator.py')] + options.to_args()
+      cmd = [os.path.join(_SCRIPT_DIR, 'jni_generator.py')]
+      if srcjar:
+        srcjar_path = os.path.join(tdir, 'srcjar.jar')
+        cmd += ['--srcjar-path', srcjar_path]
+      cmd += options.to_args()
+
       logging.info('Running: %s', shlex.join(cmd))
       subprocess.check_call(cmd)
+
       output_path = os.path.join(tdir, options.output_name)
       with open(output_path, 'r') as f:
         contents = f.read()
-      self.AssertGoldenTextEquals(contents, golden)
+      self.AssertGoldenTextEquals(contents, header_golden)
+
+      if srcjar:
+        self._CheckSrcjarGoldens(srcjar_path, name_to_goldens)
 
   def _TestEndToEndRegistration(self,
-                                input_src_files,
-                                options,
-                                name_to_goldens,
+                                input_files,
                                 src_files_for_asserts_and_stubs=None,
-                                header_golden=None):
+                                **kwargs):
+    golden_name = self._testMethodName
+    options = JniRegistrationGeneratorOptions(**kwargs)
+    dir_prefix, file_prefix = _MakePrefixes(options)
+    name_to_goldens = {
+        f'{dir_prefix}org/chromium/base/natives/{file_prefix}GEN_JNI.java':
+        f'{golden_name}-Final-GEN_JNI.java.golden',
+    }
+    if options.use_proxy_hash:
+      name_to_goldens[f'{dir_prefix}J/{file_prefix}N.java'] = (
+          f'{golden_name}-Final-N.java.golden')
+    header_golden = None
+    if options.use_proxy_hash or options.manual_jni_registration:
+      header_golden = f'{golden_name}-Registration.h.golden'
+
     with tempfile.TemporaryDirectory() as tdir:
-      native_sources = [
-          self._JoinScriptDir(os.path.join(_JAVA_SRC_DIR, f))
-          for f in input_src_files
-      ]
+      native_sources = [os.path.join(_JAVA_SRC_DIR, f) for f in input_files]
 
       if src_files_for_asserts_and_stubs:
         java_sources = [
-            self._JoinScriptDir(os.path.join(_JAVA_SRC_DIR, f))
+            os.path.join(_JAVA_SRC_DIR, f)
             for f in src_files_for_asserts_and_stubs
         ]
       else:
         java_sources = native_sources
 
-      cmd = [self._JoinScriptDir('jni_registration_generator.py')]
+      cmd = [os.path.join(_SCRIPT_DIR, 'jni_registration_generator.py')]
 
       java_sources_file = pathlib.Path(tdir) / 'java_sources.txt'
       java_sources_file.write_text('\n'.join(java_sources))
@@ -178,13 +234,8 @@
       logging.info('Running: %s', shlex.join(cmd))
       subprocess.check_call(cmd)
 
-      with zipfile.ZipFile(srcjar_path, 'r') as srcjar:
-        for name in srcjar.namelist():
-          self.assertTrue(
-              name in name_to_goldens,
-              f'Found {name} output, but not present in name_to_goldens map.')
-          contents = srcjar.read(name).decode('utf-8')
-          self.AssertGoldenTextEquals(contents, name_to_goldens[name])
+      self._CheckSrcjarGoldens(srcjar_path, name_to_goldens)
+
       if header_golden:
         with open(header_path, 'r') as f:
           # Temp directory will cause some diffs each time we run if we don't
@@ -193,17 +244,11 @@
               tdir.replace('/', '_').upper(), 'TEMP_DIR')
           self.AssertGoldenTextEquals(contents, header_golden)
 
-  def _JoinScriptDir(self, path):
-    return os.path.join(_SCRIPT_DIR, path)
-
-  def _JoinGoldenPath(self, golden_file_name):
-    return self._JoinScriptDir(os.path.join('golden', golden_file_name))
-
-  def _ReadGoldenFile(self, golden_file_name):
-    golden_file_name = self._JoinGoldenPath(golden_file_name)
-    if not os.path.exists(golden_file_name):
+  def _ReadGoldenFile(self, path):
+    _accessed_goldens.add(path)
+    if not os.path.exists(path):
       return None
-    with open(golden_file_name, 'r') as f:
+    with open(path, 'r') as f:
       return f.read()
 
   def AssertTextEquals(self, golden_text, generated_text):
@@ -238,94 +283,56 @@
 
     It will instead compare the generated text with
     script_dir/golden/golden_file."""
-    # This is the caller test method.
-    caller = inspect.stack()[1][3]
-
-    golden_text = self._ReadGoldenFile(golden_file)
-    if os.environ.get(_REBASELINE_ENV):
+    golden_path = os.path.join(_GOLDENS_DIR, golden_file)
+    golden_text = self._ReadGoldenFile(golden_path)
+    if _REBASELINE:
       if golden_text != generated_text:
-        with open(self._JoinGoldenPath(golden_file), 'w') as f:
+        print('Updated', golden_path)
+        with open(golden_path, 'w') as f:
           f.write(generated_text)
       return
     # golden_text is None if no file is found. Better to fail than in
     # AssertTextEquals so we can give a clearer message.
     if golden_text is None:
-      self.fail(
-          'Golden file %s does not exist.' % self._JoinGoldenPath(golden_file))
+      self.fail('Golden file does not exist: ' + golden_path)
     self.AssertTextEquals(golden_text, generated_text)
 
 
 @unittest.skipIf(os.name == 'nt', 'Not intended to work on Windows')
 class Tests(BaseTest):
   def testNonProxy(self):
-    self._TestEndToEndGeneration('SampleNonProxy.java', JniGeneratorOptions(),
-                                 'SampleNonProxy_jni.h.golden')
+    self._TestEndToEndGeneration('SampleNonProxy.java')
 
   def testBirectionalNonProxy(self):
-    self._TestEndToEndGeneration('SampleBidirectionalNonProxy.java',
-                                 JniGeneratorOptions(),
-                                 'SampleBidirectionalNonProxy_jni.h.golden')
+    self._TestEndToEndGeneration('SampleBidirectionalNonProxy.java')
 
   def testBidirectionalClass(self):
-    self._TestEndToEndGeneration('SampleForTests.java', JniGeneratorOptions(),
-                                 'SampleForTests_jni.h.golden')
-    self._TestEndToEndRegistration(
-        ['SampleForTests.java'], JniRegistrationGeneratorOptions(), {
-            'org/chromium/base/natives/GEN_JNI.java':
-            'SampleForTestsGenJni.java.golden'
-        })
+    self._TestEndToEndGeneration('SampleForTests.java', srcjar=True)
+    self._TestEndToEndRegistration(['SampleForTests.java'])
 
   def testFromClassFile(self):
-    self._TestEndToEndGeneration('SampleNonProxy.class', JniGeneratorOptions(),
-                                 'SampleNonProxy_class_file_jni.h.golden')
+    self._TestEndToEndGeneration('SampleNonProxy.class')
 
   def testUniqueAnnotations(self):
-    self._TestEndToEndGeneration('SampleUniqueAnnotations.java',
-                                 JniGeneratorOptions(),
-                                 'SampleUniqueAnnotations_jni.h.golden')
-
-  def testSplitNameExample(self):
-    self._TestEndToEndGeneration('SampleForTests.java', JniGeneratorOptions(),
-                                 'SampleForTestsWithSplit_jni.h.golden')
+    self._TestEndToEndGeneration('SampleUniqueAnnotations.java', srcjar=True)
 
   def testEndToEndProxyHashed(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.use_proxy_hash = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessor_proxy_GenJni.java.golden',
-        'J/N.java': 'SampleForAnnotationProcessor_proxy_JN.java.golden'
-    }
-    self._TestEndToEndRegistration(input_java_files, options, name_to_goldens)
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   use_proxy_hash=True)
 
   def testEndToEndManualRegistration(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.manual_jni_registration = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessorGenJni.golden'
-    }
-    self._TestEndToEndRegistration(
-        input_java_files,
-        options,
-        name_to_goldens,
-        header_golden='SampleForAnnotationProcessor_manual.h.golden')
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   manual_jni_registration=True)
 
   def testEndToEndProxyJniWithModules(self):
-    input_java_files = [
-        'SampleForAnnotationProcessor.java', 'SampleModule.java'
-    ]
-    options = JniRegistrationGeneratorOptions()
-    options.use_proxy_hash = True
-    options.module_name = 'module'
-    name_to_goldens = {
-        'org/chromium/base/natives/module_GEN_JNI.java':
-        'SampleModuleGenJni.golden',
-        'J/module_N.java': 'SampleModuleJN.golden'
-    }
-    self._TestEndToEndRegistration(input_java_files, options, name_to_goldens)
+    self._TestEndToEndGeneration('SampleModule.java',
+                                 srcjar=True,
+                                 use_proxy_hash=True,
+                                 module_name='module')
+    self._TestEndToEndRegistration(
+        ['SampleForAnnotationProcessor.java', 'SampleModule.java'],
+        use_proxy_hash=True,
+        module_name='module')
 
   def testStubRegistration(self):
     input_java_files = ['SampleForAnnotationProcessor.java']
@@ -333,151 +340,75 @@
         'TinySample.java', 'SampleProxyEdgeCases.java'
     ]
     extra_input_java_files = ['TinySample2.java']
-    options = JniRegistrationGeneratorOptions()
-    options.add_stubs_for_missing_native = True
-    options.remove_uncalled_methods = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java': 'StubGenJni.golden',
-        'J/N.java': 'HashedSampleForAnnotationProcessorGenJni.golden'
-    }
     self._TestEndToEndRegistration(
         input_java_files + extra_input_java_files,
-        options,
-        name_to_goldens,
-        src_files_for_asserts_and_stubs=stubs_java_files)
+        src_files_for_asserts_and_stubs=stubs_java_files,
+        add_stubs_for_missing_native=True,
+        remove_uncalled_methods=True)
 
   def testFullStubs(self):
-    stubs_java_files = ['TinySample.java']
-    options = JniRegistrationGeneratorOptions()
-    options.add_stubs_for_missing_native = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'TinySample_full_stubs_GenJni.java.golden'
-    }
     self._TestEndToEndRegistration(
         [],
-        options,
-        name_to_goldens,
-        src_files_for_asserts_and_stubs=stubs_java_files)
+        src_files_for_asserts_and_stubs=['TinySample.java'],
+        add_stubs_for_missing_native=True)
 
   def testForTestingKept(self):
     input_java_file = 'SampleProxyEdgeCases.java'
-    gen_options = JniGeneratorOptions()
-    self._TestEndToEndGeneration(input_java_file, gen_options,
-                                 'SampleProxyEdgeCases_test_kept_jni.h.golden')
-    options = JniRegistrationGeneratorOptions()
-    options.use_proxy_hash = True
-    options.include_test_only = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'SampleProxyEdgeCases_test_kept_GenJni.java.golden',
-        'J/N.java': 'SampleProxyEdgeCases_test_kept_JN.java.golden'
-    }
-    self._TestEndToEndRegistration([input_java_file], options, name_to_goldens)
+    self._TestEndToEndGeneration(input_java_file, srcjar=True)
+    self._TestEndToEndRegistration([input_java_file],
+                                   use_proxy_hash=True,
+                                   include_test_only=True)
 
   def testForTestingRemoved(self):
-    input_java_file = 'SampleProxyEdgeCases.java'
-    options = JniRegistrationGeneratorOptions()
-    options.use_proxy_hash = True
-    options.include_test_only = False
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'SampleProxyEdgeCases_test_removed_GenJni.java.golden',
-        'J/N.java': 'SampleProxyEdgeCases_test_removed_JN.java.golden'
-    }
-    self._TestEndToEndRegistration([input_java_file], options, name_to_goldens)
+    self._TestEndToEndRegistration(['SampleProxyEdgeCases.java'],
+                                   use_proxy_hash=True,
+                                   include_test_only=True)
 
   def testProxyMocks(self):
-    input_java_files = ['TinySample.java']
-    options = JniRegistrationGeneratorOptions()
-    options.enable_proxy_mocks = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'TinySample_enable_mocks_GenJni.java.golden',
-    }
-    self._TestEndToEndRegistration(input_java_files, options, name_to_goldens)
+    self._TestEndToEndRegistration(['TinySample.java'], enable_proxy_mocks=True)
 
   def testRequireProxyMocks(self):
-    input_java_files = ['TinySample.java']
-    options = JniRegistrationGeneratorOptions()
-    options.enable_proxy_mocks = True
-    options.require_mocks = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'TinySample_require_mocks_GenJni.java.golden',
-    }
-    self._TestEndToEndRegistration(input_java_files, options, name_to_goldens)
+    self._TestEndToEndRegistration(['TinySample.java'],
+                                   enable_proxy_mocks=True,
+                                   require_mocks=True)
 
   def testPackagePrefixGenerator(self):
-    options = JniGeneratorOptions()
-    options.package_prefix = 'this.is.a.package.prefix'
-    self._TestEndToEndGeneration('SampleForTests.java', options,
-                                 'SampleForTests_package_prefix_jni.h.golden')
+    self._TestEndToEndGeneration('SampleForTests.java',
+                                 srcjar=True,
+                                 package_prefix='this.is.a.package.prefix')
 
   def testPackagePrefixWithManualRegistration(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.package_prefix = 'this.is.a.package.prefix'
-    options.manual_jni_registration = True
-    name_to_goldens = {
-        'this/is/a/package/prefix/org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessor_package_prefix_manual_GenJni.java.golden',
-    }
-    self._TestEndToEndRegistration(
-        input_java_files,
-        options,
-        name_to_goldens,
-        header_golden=
-        'SampleForAnnotationProcessor_package_prefix_manual.h.golden')
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   package_prefix='this.is.a.package.prefix',
+                                   manual_jni_registration=True)
 
   def testPackagePrefixWithProxyHash(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.package_prefix = 'this.is.a.package.prefix'
-    options.use_proxy_hash = True
-    name_to_goldens = {
-        'this/is/a/package/prefix/org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessor_package_prefix_proxy_GenJni.java.golden',
-        'this/is/a/package/prefix/J/N.java':
-        'SampleForAnnotationProcessor_package_prefix_proxy_JN.java.golden',
-    }
-    self._TestEndToEndRegistration(input_java_files, options, name_to_goldens)
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   package_prefix='this.is.a.package.prefix',
+                                   use_proxy_hash=True)
 
   def testPackagePrefixWithManualRegistrationWithProxyHash(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.package_prefix = 'this.is.a.package.prefix'
-    options.use_proxy_hash = True
-    options.manual_jni_registration = True
-    name_to_goldens = {
-        'this/is/a/package/prefix/org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessor_package_prefix_proxy_manual_GenJni.java.golden',
-        'this/is/a/package/prefix/J/N.java':
-        'SampleForAnnotationProcessor_package_prefix_proxy_manual_JN.java.golden',
-    }
-    self._TestEndToEndRegistration(
-        input_java_files,
-        options,
-        name_to_goldens,
-        header_golden=
-        'SampleForAnnotationProcessor_package_prefix_proxy_manual.h.golden')
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   package_prefix='this.is.a.package.prefix',
+                                   use_proxy_hash=True,
+                                   manual_jni_registration=True)
 
   def testMultiplexing(self):
-    input_java_files = ['SampleForAnnotationProcessor.java']
-    options = JniRegistrationGeneratorOptions()
-    options.enable_jni_multiplexing = True
-    options.use_proxy_hash = True
-    name_to_goldens = {
-        'org/chromium/base/natives/GEN_JNI.java':
-        'SampleForAnnotationProcessor_multiplexing_GenJni.java.golden',
-        'J/N.java': 'SampleForAnnotationProcessor_multiplexing_JN.java.golden',
-    }
-    self._TestEndToEndRegistration(
-        input_java_files,
-        options,
-        name_to_goldens,
-        header_golden='SampleForAnnotationProcessor_multiplexing.h.golden')
+    self._TestEndToEndRegistration(['SampleForAnnotationProcessor.java'],
+                                   enable_jni_multiplexing=True,
+                                   use_proxy_hash=True)
+
+
+def main():
+  try:
+    unittest.main()
+  finally:
+    if _REBASELINE and not any(not x.startswith('-') for x in sys.argv[1:]):
+      for path in glob.glob(os.path.join(_GOLDENS_DIR, '*.golden')):
+        if path not in _accessed_goldens:
+          print('Removing obsolete golden:', path)
+          os.unlink(path)
 
 
 if __name__ == '__main__':
-  unittest.main()
+  main()
diff --git a/base/android/jni_generator/jni_registration_generator.pydeps b/base/android/jni_generator/jni_registration_generator.pydeps
index dd984a4e..75ea530 100644
--- a/base/android/jni_generator/jni_registration_generator.pydeps
+++ b/base/android/jni_generator/jni_registration_generator.pydeps
@@ -5,6 +5,8 @@
 ../../../build/android/gyp/util/build_utils.py
 ../../../build/gn_helpers.py
 ../../../build/zip_helpers.py
+codegen/placeholder_gen_jni_java.py
+codegen/proxy_impl_java.py
 common.py
 java_lang_classes.py
 jni_generator.py
diff --git a/base/android/jni_generator/models.py b/base/android/jni_generator/models.py
index a4be753..a609bf6 100644
--- a/base/android/jni_generator/models.py
+++ b/base/android/jni_generator/models.py
@@ -28,14 +28,18 @@
     return self.full_name_with_dots
 
   @property
-  def nested_name(self):
-    return self.name.rsplit('$', 1)[-1]
-
-  @property
   def name(self):
     return self._fqn.rsplit('/', 1)[-1]
 
   @property
+  def name_with_dots(self):
+    return self.name.replace('$', '.')
+
+  @property
+  def nested_name(self):
+    return self.name.rsplit('$', 1)[-1]
+
+  @property
   def package_with_slashes(self):
     return self._fqn.rsplit('/', 1)[0]
 
@@ -49,7 +53,7 @@
 
   @property
   def full_name_with_dots(self):
-    return self._fqn.replace('/', '.')
+    return self._fqn.replace('/', '.').replace('$', '.')
 
   @property
   def is_public(self):
diff --git a/base/android/jni_generator/parse.py b/base/android/jni_generator/parse.py
index b3a4801..996ef26 100644
--- a/base/android/jni_generator/parse.py
+++ b/base/android/jni_generator/parse.py
@@ -163,7 +163,7 @@
 
 _NATIVE_PROXY_EXTRACTION_REGEX = re.compile(
     r'@NativeMethods(?:\(\s*"(?P<module_name>\w+)"\s*\))?[\S\s]+?'
-    r'(?P<visibility>public)?\binterface\s*'
+    r'(?P<visibility>public)?\s*\binterface\s*'
     r'(?P<interface_name>\w*)\s*(?P<interface_body>{(\s*.*)+?\s*})')
 
 # Matches on method declarations unlike _EXTRACT_NATIVES_REGEX
@@ -188,7 +188,7 @@
 
   match = matches[0]
   ret = _ParsedProxyNatives(interface_name=match.group('interface_name'),
-                            visibility=match.group('visibility') == 'public',
+                            visibility=match.group('visibility'),
                             module_name=match.group('module_name'),
                             methods=[])
   interface_body = match.group('interface_body')
diff --git a/base/android/jni_utils.cc b/base/android/jni_utils.cc
index 09f7172..740d875 100644
--- a/base/android/jni_utils.cc
+++ b/base/android/jni_utils.cc
@@ -10,7 +10,7 @@
 #include "base/no_destructor.h"
 #include "base/synchronization/lock.h"
 
-#include "base/base_jni_headers/JNIUtils_jni.h"
+#include "base/base_jni/JNIUtils_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/library_loader/library_loader_hooks.cc b/base/android/library_loader/library_loader_hooks.cc
index b6453a2..d8ce033 100644
--- a/base/android/library_loader/library_loader_hooks.cc
+++ b/base/android/library_loader/library_loader_hooks.cc
@@ -12,7 +12,7 @@
 #include "base/android/orderfile/orderfile_buildflags.h"
 #include "base/android/sys_utils.h"
 #include "base/at_exit.h"
-#include "base/base_jni_headers/LibraryLoader_jni.h"
+#include "base/base_jni/LibraryLoader_jni.h"
 #include "base/base_switches.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_functions.h"
diff --git a/base/android/library_loader/library_prefetcher_hooks.cc b/base/android/library_loader/library_prefetcher_hooks.cc
index 50968432..37e3b57 100644
--- a/base/android/library_loader/library_prefetcher_hooks.cc
+++ b/base/android/library_loader/library_prefetcher_hooks.cc
@@ -10,7 +10,7 @@
 #include "base/android/library_loader/library_loader_hooks.h"
 #include "base/android/library_loader/library_prefetcher.h"
 #include "base/android/scoped_java_ref.h"
-#include "base/base_jni_headers/LibraryPrefetcher_jni.h"
+#include "base/base_jni/LibraryPrefetcher_jni.h"
 #include "base/logging.h"
 
 namespace base {
diff --git a/base/android/locale_utils.cc b/base/android/locale_utils.cc
index 9cc22bf..f11e61d 100644
--- a/base/android/locale_utils.cc
+++ b/base/android/locale_utils.cc
@@ -6,7 +6,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/LocaleUtils_jni.h"
+#include "base/base_jni/LocaleUtils_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/meminfo_dump_provider.cc b/base/android/meminfo_dump_provider.cc
index 387a4d7..aeaa62e0 100644
--- a/base/android/meminfo_dump_provider.cc
+++ b/base/android/meminfo_dump_provider.cc
@@ -10,7 +10,7 @@
 #include "base/trace_event/base_tracing.h"
 
 #if BUILDFLAG(ENABLE_BASE_TRACING)
-#include "base/base_jni_headers/MemoryInfoBridge_jni.h"
+#include "base/base_jni/MemoryInfoBridge_jni.h"
 #endif  // BUILDFLAG(ENABLE_BASE_TRACING)
 
 namespace base::android {
diff --git a/base/android/memory_pressure_listener_android.cc b/base/android/memory_pressure_listener_android.cc
index 248777fd..739f35e 100644
--- a/base/android/memory_pressure_listener_android.cc
+++ b/base/android/memory_pressure_listener_android.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/memory_pressure_listener_android.h"
 
-#include "base/base_jni_headers/MemoryPressureListener_jni.h"
+#include "base/base_jni/MemoryPressureListener_jni.h"
 #include "base/memory/memory_pressure_listener.h"
 
 using base::android::JavaParamRef;
diff --git a/base/android/native_uma_recorder.cc b/base/android/native_uma_recorder.cc
index 4714fd9..bb1d66a8 100644
--- a/base/android/native_uma_recorder.cc
+++ b/base/android/native_uma_recorder.cc
@@ -6,7 +6,7 @@
 #include "base/android/jni_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/NativeUmaRecorder_jni.h"
+#include "base/base_jni/NativeUmaRecorder_jni.h"
 #include "base/format_macros.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/histogram_base.h"
diff --git a/base/android/path_service_android.cc b/base/android/path_service_android.cc
index cefa43d61..3ca3ea1c 100644
--- a/base/android/path_service_android.cc
+++ b/base/android/path_service_android.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/PathService_jni.h"
+#include "base/base_jni/PathService_jni.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 
diff --git a/base/android/path_utils.cc b/base/android/path_utils.cc
index 048d2b8..e39cf7c 100644
--- a/base/android/path_utils.cc
+++ b/base/android/path_utils.cc
@@ -10,7 +10,7 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/files/file_path.h"
 
-#include "base/base_jni_headers/PathUtils_jni.h"
+#include "base/base_jni/PathUtils_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/radio_utils.cc b/base/android/radio_utils.cc
index 0e082eae..bddced2 100644
--- a/base/android/radio_utils.cc
+++ b/base/android/radio_utils.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/radio_utils.h"
 
-#include "base/base_jni_headers/RadioUtils_jni.h"
+#include "base/base_jni/RadioUtils_jni.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace base {
diff --git a/base/android/statistics_recorder_android.cc b/base/android/statistics_recorder_android.cc
index 4d7fc80..fdfcbfca 100644
--- a/base/android/statistics_recorder_android.cc
+++ b/base/android/statistics_recorder_android.cc
@@ -5,7 +5,7 @@
 #include <string>
 
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/StatisticsRecorderAndroid_jni.h"
+#include "base/base_jni/StatisticsRecorderAndroid_jni.h"
 #include "base/metrics/histogram_base.h"
 #include "base/metrics/statistics_recorder.h"
 #include "base/system/sys_info.h"
diff --git a/base/android/sys_utils.cc b/base/android/sys_utils.cc
index 51c9fa0e..6ad419da 100644
--- a/base/android/sys_utils.cc
+++ b/base/android/sys_utils.cc
@@ -7,7 +7,7 @@
 #include <memory>
 
 #include "base/android/build_info.h"
-#include "base/base_jni_headers/SysUtils_jni.h"
+#include "base/base_jni/SysUtils_jni.h"
 #include "base/process/process_metrics.h"
 #include "base/system/sys_info.h"
 #include "base/trace_event/base_tracing.h"
diff --git a/base/android/task_scheduler/post_task_android.cc b/base/android/task_scheduler/post_task_android.cc
index 8367fae3..c47be55 100644
--- a/base/android/task_scheduler/post_task_android.cc
+++ b/base/android/task_scheduler/post_task_android.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/task_scheduler/post_task_android.h"
 
-#include "base/base_jni_headers/PostTask_jni.h"
+#include "base/base_jni/PostTask_jni.h"
 
 namespace base {
 
diff --git a/base/android/task_scheduler/task_runner_android.cc b/base/android/task_scheduler/task_runner_android.cc
index 93782d9..e0a120c 100644
--- a/base/android/task_scheduler/task_runner_android.cc
+++ b/base/android/task_scheduler/task_runner_android.cc
@@ -10,7 +10,7 @@
 
 #include "base/android/jni_string.h"
 #include "base/android_runtime_unchecked_jni_headers/Runnable_jni.h"
-#include "base/base_jni_headers/TaskRunnerImpl_jni.h"
+#include "base/base_jni/TaskRunnerImpl_jni.h"
 #include "base/check.h"
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
diff --git a/base/android/timezone_utils.cc b/base/android/timezone_utils.cc
index 529ad003..20441b72 100644
--- a/base/android/timezone_utils.cc
+++ b/base/android/timezone_utils.cc
@@ -8,7 +8,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/TimezoneUtils_jni.h"
+#include "base/base_jni/TimezoneUtils_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/android/trace_event_binding.cc b/base/android/trace_event_binding.cc
index a2fe414..b36b988 100644
--- a/base/android/trace_event_binding.cc
+++ b/base/android/trace_event_binding.cc
@@ -8,7 +8,7 @@
 
 #include "base/android/jni_string.h"
 #include "base/android/trace_event_binding.h"
-#include "base/base_jni_headers/TraceEvent_jni.h"
+#include "base/base_jni/TraceEvent_jni.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/trace_event/base_tracing.h"
 #include "base/tracing_buildflags.h"
diff --git a/base/android/unguessable_token_android.cc b/base/android/unguessable_token_android.cc
index efff14b..ae4b642d 100644
--- a/base/android/unguessable_token_android.cc
+++ b/base/android/unguessable_token_android.cc
@@ -4,7 +4,7 @@
 
 #include "base/android/unguessable_token_android.h"
 
-#include "base/base_jni_headers/UnguessableToken_jni.h"
+#include "base/base_jni/UnguessableToken_jni.h"
 
 namespace base {
 namespace android {
diff --git a/base/files/file_util_android.cc b/base/files/file_util_android.cc
index 1f921f5..fa09a57 100644
--- a/base/files/file_util_android.cc
+++ b/base/files/file_util_android.cc
@@ -6,7 +6,7 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/base_jni_headers/FileUtils_jni.h"
+#include "base/base_jni/FileUtils_jni.h"
 #include "base/files/file_path.h"
 #include "base/path_service.h"
 
diff --git a/base/power_monitor/power_monitor_device_source_android.cc b/base/power_monitor/power_monitor_device_source_android.cc
index 5d0523e..82eae92 100644
--- a/base/power_monitor/power_monitor_device_source_android.cc
+++ b/base/power_monitor/power_monitor_device_source_android.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/base_jni_headers/PowerMonitor_jni.h"
+#include "base/base_jni/PowerMonitor_jni.h"
 #include "base/power_monitor/power_monitor.h"
 #include "base/power_monitor/power_monitor_device_source.h"
 #include "base/power_monitor/power_monitor_source.h"
diff --git a/base/profiler/stack_sampling_profiler_java_test_util.cc b/base/profiler/stack_sampling_profiler_java_test_util.cc
index cf585d9..77bb9a2e 100644
--- a/base/profiler/stack_sampling_profiler_java_test_util.cc
+++ b/base/profiler/stack_sampling_profiler_java_test_util.cc
@@ -4,7 +4,7 @@
 
 #include "base/profiler/stack_sampling_profiler_java_test_util.h"
 
-#include "base/base_profiler_test_support_jni_headers/TestSupport_jni.h"
+#include "base/base_profiler_test_support_jni/TestSupport_jni.h"
 #include "base/location.h"
 
 namespace base {
diff --git a/base/test/library_loader/early_native_test_helper.cc b/base/test/library_loader/early_native_test_helper.cc
index 0b7c2077..7877c27 100644
--- a/base/test/library_loader/early_native_test_helper.cc
+++ b/base/test/library_loader/early_native_test_helper.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "base/base_javatests_jni_headers/EarlyNativeTest_jni.h"
+#include "base/base_javatests_jni/EarlyNativeTest_jni.h"
 #include "base/command_line.h"
 #include "base/process/current_process.h"
 #include "base/trace_event/trace_log.h"
diff --git a/base/threading/platform_thread_android.cc b/base/threading/platform_thread_android.cc
index 13453e1..594bae9 100644
--- a/base/threading/platform_thread_android.cc
+++ b/base/threading/platform_thread_android.cc
@@ -11,7 +11,7 @@
 #include <unistd.h>
 
 #include "base/android/jni_android.h"
-#include "base/base_jni_headers/ThreadUtils_jni.h"
+#include "base/base_jni/ThreadUtils_jni.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/threading/platform_thread_internal_posix.h"
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index 2c0d1ce..0c6f5a3 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -133,7 +133,7 @@
   }
 
   # JNI target implementation. See generate_jni or generate_jar_jni for usage.
-  template("generate_jni_impl") {
+  template("_generate_jni_impl") {
     _prev_jni_output_dir = "$target_gen_dir/$target_name"
     _subdir = rebase_path(target_gen_dir, root_gen_dir)
     _jni_output_dir = "$jni_headers_dir/$_subdir/$target_name"
@@ -171,6 +171,7 @@
       public_deps += _jni_generator_include_deps
 
       inputs = []
+      outputs = []
       args = [
         "--ptr_type=long",
 
@@ -207,6 +208,12 @@
         }
       } else {
         assert(defined(invoker.sources))
+        _srcjar_output = "$target_gen_dir/$target_name.srcjar"
+        args += [
+          "--srcjar-path",
+          rebase_path(_srcjar_output, root_build_dir),
+        ]
+        outputs += [ _srcjar_output ]
         inputs += invoker.sources
         _input_args = rebase_path(invoker.sources, root_build_dir)
         _input_names = invoker.sources
@@ -226,7 +233,6 @@
         args += [ "--split_name=${invoker.split_name}" ]
       }
 
-      outputs = []
       foreach(_name, _input_names) {
         _name = get_path_info(_name, "name") + "_jni.h"
         outputs += [ "$_jni_output_dir/$_name" ]
@@ -301,7 +307,7 @@
   #     ]
   #   }
   template("generate_jni") {
-    generate_jni_impl(target_name) {
+    _generate_jni_impl(target_name) {
       forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
       forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
       metadata = {
@@ -336,7 +342,7 @@
   #     ]
   #   }
   template("generate_jar_jni") {
-    generate_jni_impl(target_name) {
+    _generate_jni_impl(target_name) {
       forward_variables_from(invoker, "*", TESTONLY_AND_VISIBILITY)
       forward_variables_from(invoker, TESTONLY_AND_VISIBILITY)
     }