[go: nahoru, domu]

blob: a7ede2db968055153f752a5569e761f0c0e3a05b [file] [log] [blame]
#!/usr/bin/env python
# Copyright 2017 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Generate JNI registration entry points
Creates a header file with two static functions: RegisterMainDexNatives() and
RegisterNonMainDexNatives(). Together, these will use manual JNI registration
to register all native methods that exist within an application."""
import argparse
import jni_generator
import os
import string
import sys
from util import build_utils
def GenerateJNIHeader(java_file_paths, output_file, args):
"""Generate a header file including two registration functions.
Forward declares all JNI registration functions created by jni_generator.py.
Calls the functions in RegisterMainDexNatives() if they are main dex. And
calls them in RegisterNonMainDexNatives() if they are non-main dex.
Args:
java_file_paths: A list of java file paths.
output_file: A relative path to output file.
args: All input arguments.
"""
registration_dict = {
'FORWARD_DECLARATIONS': '',
'REGISTER_MAIN_DEX_NATIVES': '',
'REGISTER_NON_MAIN_DEX_NATIVES': ''
}
# Sort the file list to make sure the order is deterministic.
java_file_paths.sort()
for path in java_file_paths:
if path in args.no_register_java:
continue
with open(path) as f:
contents = f.read()
natives = jni_generator.ExtractNatives(contents, 'long')
if len(natives) == 0:
continue
fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
path, contents)
main_dex = jni_generator.IsMainDexJavaClass(contents)
header_generator = HeaderGenerator(
fully_qualified_class, registration_dict, main_dex)
registration_dict = header_generator.GetContent()
header_content = CreateFromDict(registration_dict)
if output_file:
jni_generator.WriteOutput(output_file, header_content)
else:
print header_content
def CreateFromDict(registration_dict):
"""Returns the content of the header file."""
template = string.Template("""\
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file is autogenerated by
// base/android/jni_generator/jni_registration_generator.py
// Please do not change its content.
#ifndef HEADER_GUARD
#define HEADER_GUARD
#include <jni.h>
#include "base/android/jni_generator/jni_generator_helper.h"
#include "base/android/jni_int_wrapper.h"
// Step 1: Forward declaration.
${FORWARD_DECLARATIONS}
// Step 2: Main dex and non-main dex registration functions.
bool RegisterMainDexNatives(JNIEnv* env) {
${REGISTER_MAIN_DEX_NATIVES}
return true;
}
bool RegisterNonMainDexNatives(JNIEnv* env) {
${REGISTER_NON_MAIN_DEX_NATIVES}
return true;
}
#endif // HEADER_GUARD
""")
if len(registration_dict['FORWARD_DECLARATIONS']) == 0:
return ''
return jni_generator.WrapOutput(template.substitute(registration_dict))
class HeaderGenerator(object):
"""Generates an inline header file for JNI registration."""
def __init__(self, fully_qualified_class, registration_dict, main_dex):
self.fully_qualified_class = fully_qualified_class
self.class_name = self.fully_qualified_class.split('/')[-1]
self.registration_dict = registration_dict
self.main_dex = main_dex
def GetContent(self):
self._AddForwardDeclaration()
self._AddRegisterNatives()
return self.registration_dict
def _AddForwardDeclaration(self):
"""Add the content of the forward declaration to the dictionary."""
template = string.Template('JNI_REGISTRATION_EXPORT bool ${METHOD_NAME}('
'JNIEnv* env);\n')
value = {
'METHOD_NAME':
jni_generator.GetRegistrationFunctionName(
self.fully_qualified_class)
}
self.registration_dict['FORWARD_DECLARATIONS'] += template.substitute(value)
def _AddRegisterNatives(self):
"""Add the body of the RegisterNativesImpl method to the dictionary."""
template = string.Template("""
if (!${REGISTER_NAME}(env))
return false;
""")
value = {
'REGISTER_NAME':
jni_generator.GetRegistrationFunctionName(
self.fully_qualified_class)
}
register_body = template.substitute(value)
if self.main_dex:
self.registration_dict['REGISTER_MAIN_DEX_NATIVES'] += register_body
else:
self.registration_dict['REGISTER_NON_MAIN_DEX_NATIVES'] += register_body
def main(argv):
arg_parser = argparse.ArgumentParser()
build_utils.AddDepfileOption(arg_parser)
arg_parser.add_argument('--sources_files',
help='A list of .sources files which contain Java '
'file paths. Must be used with --output.')
arg_parser.add_argument('--output',
help='The output file path.')
arg_parser.add_argument('--no_register_java',
help='A list of Java files which should be ignored '
'by the parser.')
args = arg_parser.parse_args(build_utils.ExpandFileArgs(argv[1:]))
args.sources_files = build_utils.ParseGnList(args.sources_files)
if args.sources_files:
java_file_paths = []
for f in args.sources_files:
# java_file_paths stores each Java file path as a string.
java_file_paths += build_utils.ReadSourcesList(f)
else:
print '\nError: Must specify --sources_files.'
return 1
output_file = args.output
GenerateJNIHeader(java_file_paths, output_file, args)
if args.depfile:
build_utils.WriteDepfile(args.depfile, output_file)
if __name__ == '__main__':
sys.exit(main(sys.argv))