Ejemplo n.º 1
0
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 = {}
    # 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 = jni_generator.RemoveComments(f.read())
        natives = jni_generator.ExtractNatives(contents, 'long')
        if len(natives) == 0:
            continue
        namespace = jni_generator.ExtractJNINamespace(contents)
        fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
            path, contents)
        jni_params = jni_generator.JniParams(fully_qualified_class)
        jni_params.ExtractImportsAndInnerClasses(contents)
        main_dex = jni_generator.IsMainDexJavaClass(contents)
        header_generator = HeaderGenerator(namespace, fully_qualified_class,
                                           natives, jni_params,
                                           registration_dict, main_dex)
        header_generator.AddContent()

    header_content = CreateFromDict(registration_dict)
    if output_file:
        jni_generator.WriteOutput(output_file, header_content)
    else:
        print header_content
Ejemplo n.º 2
0
    def testInnerClassNativesBothInnerAndOuter(self):
        test_data = """
    class MyOuterClass {
      private native int nativeInit();
      class MyOtherInnerClass {
        @NativeCall("MyOtherInnerClass")
        private native int nativeInit();
      }
    }
    """
        natives = jni_generator.ExtractNatives(test_data, 'int')
        golden_natives = [
            NativeMethod(return_type='int',
                         static=False,
                         name='Init',
                         params=[],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='int',
                         static=False,
                         name='Init',
                         params=[],
                         java_class_name='MyOtherInnerClass',
                         type='function')
        ]
        self.assertListEquals(golden_natives, natives)
        jni_params = jni_generator.JniParams('')
        h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                                 natives, [], [], jni_params,
                                                 TestOptions())
        self.assertGoldenTextEquals(h.GetContent())

        content = {}
        h2 = jni_registration_generator.HeaderGenerator(
            '', 'org/chromium/TestJni', natives, jni_params, content, True)
        h2.AddContent()
        self.assertGoldenTextEquals(
            jni_registration_generator.CreateFromDict(content),
            suffix='Registrations')
Ejemplo n.º 3
0
 def testInnerClassNatives(self):
     test_data = """
 class MyInnerClass {
   @NativeCall("MyInnerClass")
   private native int nativeInit();
 }
 """
     natives = jni_generator.ExtractNatives(test_data, 'int')
     golden_natives = [
         NativeMethod(return_type='int',
                      static=False,
                      name='Init',
                      params=[],
                      java_class_name='MyInnerClass',
                      type='function')
     ]
     self.assertListEquals(golden_natives, natives)
     jni_params = jni_generator.JniParams('')
     h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                              natives, [], [], jni_params,
                                              TestOptions())
     self.assertGoldenTextEquals(h.GetContent())
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
Ejemplo n.º 5
0
 def testNativesLong(self):
   test_options = TestOptions()
   test_options.ptr_type = 'long'
   test_data = """"
   private native void nativeDestroy(long nativeChromeBrowserProvider);
   """
   jni_params = jni_generator.JniParams('')
   jni_params.ExtractImportsAndInnerClasses(test_data)
   natives = jni_generator.ExtractNatives(test_data, test_options.ptr_type)
   golden_natives = [
       NativeMethod(return_type='void', static=False, name='Destroy',
                    params=[Param(datatype='long',
                                  name='nativeChromeBrowserProvider')],
                    java_class_name=None,
                    type='method',
                    p0_type='ChromeBrowserProvider',
                    ptr_type=test_options.ptr_type),
   ]
   self.assertListEquals(golden_natives, natives)
   h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                            natives, [], [], jni_params,
                                            test_options)
   self.assertGoldenTextEquals(h.GetContent())
def _DictForPath(path, use_proxy_hash=False):
  with open(path) as f:
    contents = jni_generator.RemoveComments(f.read())
    if '@JniIgnoreNatives' in contents:
      return None

  fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
      path, contents)
  natives = jni_generator.ExtractNatives(contents, 'long')

  natives += jni_generator.ProxyHelpers.ExtractStaticProxyNatives(
      fully_qualified_class=fully_qualified_class,
      contents=contents,
      ptr_type='long')
  if len(natives) == 0:
    return None
  namespace = jni_generator.ExtractJNINamespace(contents)
  jni_params = jni_generator.JniParams(fully_qualified_class)
  jni_params.ExtractImportsAndInnerClasses(contents)
  is_main_dex = jni_generator.IsMainDexJavaClass(contents)
  header_generator = HeaderGenerator(namespace, fully_qualified_class, natives,
                                     jni_params, is_main_dex, use_proxy_hash)
  return header_generator.Generate()
Ejemplo n.º 7
0
def convert_file_to_proxy_natives(java_file_name, dry=False, verbose=True):
    if not os.path.isfile(java_file_name):
        if verbose:
            print('%s does not exist', java_file_name)
        return

    with open(java_file_name, 'r') as f:
        contents = f.read()

    no_comment_content = jni_generator.RemoveComments(contents)
    natives = jni_generator.ExtractNatives(no_comment_content, 'long')

    static_natives = [n for n in natives if n.static]

    if not static_natives:
        if verbose:
            print('%s has no static natives.', java_file_name)
        return

    contents = add_chromium_import_to_java_file(contents, JNI_IMPORT_STRING)

    # Extract comments and annotations above native methods.
    native_map = {}
    for itr in re.finditer(_NATIVES_REGEX, contents):
        n_dict = {}
        n_dict['annotations'] = itr.group('annotations').strip()
        n_dict['comments'] = itr.group('comments').strip()
        n_dict['params'] = itr.group('params').strip()
        native_map[itr.group('name')] = n_dict

    # Using static natives here ensures all the methods that are picked up by
    # the JNI generator are also caught by our own regex.
    methods = []
    for n in static_natives:
        new_name = n.name[0].lower() + n.name[1:]
        n_dict = native_map['native' + n.name]
        params = n_dict['params']
        comments = n_dict['comments']
        annotations = n_dict['annotations']
        methods.append(
            build_method_declaration(n.return_type, new_name, params,
                                     annotations, comments))

    fully_qualified_class = jni_generator.ExtractFullyQualifiedJavaClassName(
        java_file_name, contents)
    class_name = fully_qualified_class.split('/')[-1]
    jni_class_name = class_name + 'Jni'

    # Remove all old declarations.
    for n in static_natives:
        pattern = _NATIVES_REGEX
        contents = re.sub(pattern, '', contents)

    # Replace occurences with new signature.
    for n in static_natives:
        # Okay not to match first (.
        # Since even if natives share a prefix, the replacement is the same.
        # E.g. if nativeFoo() and nativeFooBar() are both statics
        # and in nativeFooBar() we replace nativeFoo -> AJni.get().foo
        # the result is the same as replacing nativeFooBar() -> AJni.get().fooBar
        pattern = r'native%s' % n.name
        lower_name = n.name[0].lower() + n.name[1:]
        contents = re.sub(pattern,
                          '%s.get().%s' % (jni_class_name, lower_name),
                          contents)

    # Build and insert the @NativeMethods interface.
    interface = _JNI_INTERFACE_TEMPLATES.substitute({
        'INTERFACE_NAME': 'Natives',
        'METHODS': ''.join(methods)
    })

    # Insert the interface at the bottom of the top level class.
    # Most of the time this will be before the last }.
    insertion_point = contents.rfind('}')
    contents = contents[:insertion_point] + '\n' + interface + contents[
        insertion_point:]

    if not dry:
        with open(java_file_name, 'w') as f:
            f.write(contents)
    else:
        print(contents)
    return contents
Ejemplo n.º 8
0
def convert_nonstatic_to_static(java_file_name, dry=False, verbose=True):
    if java_file_name is None:
        return
    if not os.path.isfile(java_file_name):
        if verbose:
            print('%s does not exist', java_file_name)
        return

    with open(java_file_name, 'r') as f:
        contents = f.read()

    no_comment_content = jni_generator.RemoveComments(contents)
    parsed_natives = jni_generator.ExtractNatives(no_comment_content, 'long')
    non_static_natives = [n for n in parsed_natives if not n.static]
    if not non_static_natives:
        if verbose:
            print('no natives found')
        return

    class_name = jni_generator.ExtractFullyQualifiedJavaClassName(
        java_file_name, no_comment_content).split('/')[-1]

    replace_patterns = []
    should_add_comma = []

    new_contents = contents

    # 1. Change non-static -> static.
    insertion_offset = 0

    matches = []
    for match in _NON_STATIC_NATIVES_REGEX.finditer(contents):
        if not 'static' in match.group('qualifiers'):
            matches.append(match)
            # Insert static as a keyword.
            qual_end = match.end('qualifiers') + insertion_offset
            insert_str = ' static '
            new_contents = new_contents[:qual_end] + insert_str + new_contents[
                qual_end:]
            insertion_offset += len(insert_str)

            # Insert an object param.
            start = insertion_offset + match.end('params')
            insert_str = '%s caller' % class_name
            if match.group('params'):
                insert_str = ', ' + insert_str

            # Match lines that don't have a native keyword.
            replace_patterns.append(r'(^\s*' + match.group('name') +
                                    r'\(.*?(?=\)))')
            replace_patterns.append(r'(return ' + match.group('name') +
                                    r'\(.*?(?=\)))')
            replace_patterns.append(r'([\:\)\(\+\*\?\&\|,\.\-\=\!\/][ \t]*' +
                                    match.group('name') + r'\(.*?(?=\)))')

            add_comma = bool(match.group('params'))
            should_add_comma.extend([add_comma] * 3)

            new_contents = new_contents[:start] + insert_str + new_contents[
                start:]
            insertion_offset += len(insert_str)

    assert len(matches) == len(non_static_natives), (
        'Regex missed a native '
        'method that was found by '
        'the jni_generator.')

    # 2. Add a this param to all calls.
    for i, r in enumerate(replace_patterns):
        if should_add_comma[i]:
            new_contents = re.sub(r,
                                  '\g<1>, %s.this' % class_name,
                                  new_contents,
                                  flags=re.MULTILINE)
        else:
            new_contents = re.sub(r,
                                  '\g<1>%s.this' % class_name,
                                  new_contents,
                                  flags=re.MULTILINE)

    if dry:
        print(new_contents)
    else:
        with open(java_file_name, 'w') as f:
            f.write(new_contents)
Ejemplo n.º 9
0
  def testNatives(self):
    test_data = """"
    import android.graphics.Bitmap;
    import android.view.View;

    interface OnFrameAvailableListener {}
    private native int nativeInit();
    private native void nativeDestroy(int nativeChromeBrowserProvider);
    private native long nativeAddBookmark(
            int nativeChromeBrowserProvider,
            String url, String title, boolean isFolder, long parentId);
    private static native String nativeGetDomainAndRegistry(String url);
    private static native void nativeCreateHistoricalTabFromState(
            byte[] state, int tab_index);
    private native byte[] nativeGetStateAsByteArray(View view);
    private static native String[] nativeGetAutofillProfileGUIDs();
    private native void nativeSetRecognitionResults(
            int sessionId, String[] results);
    private native long nativeAddBookmarkFromAPI(
            int nativeChromeBrowserProvider,
            String url, Long created, Boolean isBookmark,
            Long date, byte[] favicon, String title, Integer visits);
    native int nativeFindAll(String find);
    private static native OnFrameAvailableListener nativeGetInnerClass();
    private native Bitmap nativeQueryBitmap(
            int nativeChromeBrowserProvider,
            String[] projection, String selection,
            String[] selectionArgs, String sortOrder);
    private native void nativeGotOrientation(
            int nativeDataFetcherImplAndroid,
            double alpha, double beta, double gamma);
    private static native Throwable nativeMessWithJavaException(Throwable e);
    """
    jni_params = jni_generator.JniParams(
        'org/chromium/example/jni_generator/SampleForTests')
    jni_params.ExtractImportsAndInnerClasses(test_data)
    natives = jni_generator.ExtractNatives(test_data, 'int')
    golden_natives = [
        NativeMethod(return_type='int', static=False,
                     name='Init',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False, name='Destroy',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='long', static=False, name='AddBookmark',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='boolean',
                                   name='isFolder'),
                             Param(datatype='long',
                                   name='parentId')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='String', static=True,
                     name='GetDomainAndRegistry',
                     params=[Param(datatype='String',
                                   name='url')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=True,
                     name='CreateHistoricalTabFromState',
                     params=[Param(datatype='byte[]',
                                   name='state'),
                             Param(datatype='int',
                                   name='tab_index')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='byte[]', static=False,
                     name='GetStateAsByteArray',
                     params=[Param(datatype='View', name='view')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='String[]', static=True,
                     name='GetAutofillProfileGUIDs', params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='void', static=False,
                     name='SetRecognitionResults',
                     params=[Param(datatype='int', name='sessionId'),
                             Param(datatype='String[]', name='results')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='long', static=False,
                     name='AddBookmarkFromAPI',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String',
                                   name='url'),
                             Param(datatype='Long',
                                   name='created'),
                             Param(datatype='Boolean',
                                   name='isBookmark'),
                             Param(datatype='Long',
                                   name='date'),
                             Param(datatype='byte[]',
                                   name='favicon'),
                             Param(datatype='String',
                                   name='title'),
                             Param(datatype='Integer',
                                   name='visits')],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='int', static=False,
                     name='FindAll',
                     params=[Param(datatype='String',
                                   name='find')],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='OnFrameAvailableListener', static=True,
                     name='GetInnerClass',
                     params=[],
                     java_class_name=None,
                     type='function'),
        NativeMethod(return_type='Bitmap',
                     static=False,
                     name='QueryBitmap',
                     params=[Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String[]',
                                   name='projection'),
                             Param(datatype='String',
                                   name='selection'),
                             Param(datatype='String[]',
                                   name='selectionArgs'),
                             Param(datatype='String',
                                   name='sortOrder'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='ChromeBrowserProvider'),
        NativeMethod(return_type='void', static=False,
                     name='GotOrientation',
                     params=[Param(datatype='int',
                                   name='nativeDataFetcherImplAndroid'),
                             Param(datatype='double',
                                   name='alpha'),
                             Param(datatype='double',
                                   name='beta'),
                             Param(datatype='double',
                                   name='gamma'),
                            ],
                     java_class_name=None,
                     type='method',
                     p0_type='content::DataFetcherImplAndroid'),
        NativeMethod(return_type='Throwable', static=True,
                     name='MessWithJavaException',
                     params=[Param(datatype='Throwable', name='e')],
                     java_class_name=None,
                     type='function')
    ]
    self.assertListEquals(golden_natives, natives)
    h1 = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                              natives, [], [], jni_params,
                                              TestOptions())
    self.assertGoldenTextEquals(h1.GetContent())
    content = {}
    h2 = jni_registration_generator.HeaderGenerator(
        '', 'org/chromium/TestJni', natives, jni_params, content, True)
    h2.AddContent()
    self.assertGoldenTextEquals(
        jni_registration_generator.CreateFromDict(content),
        suffix='Registrations')
Ejemplo n.º 10
0
    def testInnerClassNativesBothInnerAndOuter(self):
        test_data = """
    class MyOuterClass {
      private native int nativeInit();
      class MyOtherInnerClass {
        @NativeCall("MyOtherInnerClass")
        private native int nativeInit();
      }
    }
    """
        natives = jni_generator.ExtractNatives(test_data)
        golden_natives = [
            NativeMethod(return_type='int',
                         static=False,
                         name='Init',
                         params=[],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='int',
                         static=False,
                         name='Init',
                         params=[],
                         java_class_name='MyOtherInnerClass',
                         type='function')
        ]
        self.assertListEquals(golden_natives, natives)
        h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                                 natives, [])
        golden_content = """\
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is autogenerated by
//     base/android/jni_generator/jni_generator_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kMyOtherInnerClassClassPath[] =
    "org/chromium/TestJni$MyOtherInnerClass";
const char kTestJniClassPath[] = "org/chromium/TestJni";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

static jint Init(JNIEnv* env, jobject obj);

// Step 2: method stubs.

// Step 3: GetMethodIDs and RegisterNatives.
static void GetMethodIDsImpl(JNIEnv* env) {
  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
}

static bool RegisterNativesImpl(JNIEnv* env) {
  GetMethodIDsImpl(env);

  static const JNINativeMethod kMethodsMyOtherInnerClass[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsMyOtherInnerClassSize =
      arraysize(kMethodsMyOtherInnerClass);

  if (env->RegisterNatives(g_MyOtherInnerClass_clazz,
                           kMethodsMyOtherInnerClass,
                           kMethodsMyOtherInnerClassSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  static const JNINativeMethod kMethodsTestJni[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
  };
  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);

  if (env->RegisterNatives(g_TestJni_clazz,
                           kMethodsTestJni,
                           kMethodsTestJniSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
        self.assertTextEquals(golden_content, h.GetContent())
Ejemplo n.º 11
0
    def testNatives(self):
        test_data = """"
    private native int nativeInit();
    private native void nativeDestroy(int nativeChromeBrowserProvider);
    private native long nativeAddBookmark(
            int nativeChromeBrowserProvider,
            String url, String title, boolean isFolder, long parentId);
    private static native String nativeGetDomainAndRegistry(String url);
    private static native void nativeCreateHistoricalTabFromState(
            byte[] state, int tab_index);
    private native byte[] nativeGetStateAsByteArray(ContentView view);
    private static native String[] nativeGetAutofillProfileGUIDs();
    private native void nativeSetRecognitionResults(
            int sessionId, String[] results);
    private native long nativeAddBookmarkFromAPI(
            int nativeChromeBrowserProvider,
            String url, Long created, Boolean isBookmark,
            Long date, byte[] favicon, String title, Integer visits);
    native int nativeFindAll(String find);
    private static native BookmarkNode nativeGetDefaultBookmarkFolder();
    private native SQLiteCursor nativeQueryBookmarkFromAPI(
            int nativeChromeBrowserProvider,
            String[] projection, String selection,
            String[] selectionArgs, String sortOrder);
    private native void nativeGotOrientation(
            int nativeDataFetcherImplAndroid,
            double alpha, double beta, double gamma);
    """
        natives = jni_generator.ExtractNatives(test_data)
        golden_natives = [
            NativeMethod(return_type='int',
                         static=False,
                         name='Init',
                         params=[],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='void',
                         static=False,
                         name='Destroy',
                         params=[
                             Param(datatype='int',
                                   name='nativeChromeBrowserProvider')
                         ],
                         java_class_name=None,
                         type='method',
                         p0_type='ChromeBrowserProvider'),
            NativeMethod(return_type='long',
                         static=False,
                         name='AddBookmark',
                         params=[
                             Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String', name='url'),
                             Param(datatype='String', name='title'),
                             Param(datatype='boolean', name='isFolder'),
                             Param(datatype='long', name='parentId')
                         ],
                         java_class_name=None,
                         type='method',
                         p0_type='ChromeBrowserProvider'),
            NativeMethod(return_type='String',
                         static=True,
                         name='GetDomainAndRegistry',
                         params=[Param(datatype='String', name='url')],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='void',
                         static=True,
                         name='CreateHistoricalTabFromState',
                         params=[
                             Param(datatype='byte[]', name='state'),
                             Param(datatype='int', name='tab_index')
                         ],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='byte[]',
                         static=False,
                         name='GetStateAsByteArray',
                         params=[Param(datatype='ContentView', name='view')],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='String[]',
                         static=True,
                         name='GetAutofillProfileGUIDs',
                         params=[],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='void',
                         static=False,
                         name='SetRecognitionResults',
                         params=[
                             Param(datatype='int', name='sessionId'),
                             Param(datatype='String[]', name='results')
                         ],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='long',
                         static=False,
                         name='AddBookmarkFromAPI',
                         params=[
                             Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String', name='url'),
                             Param(datatype='Long', name='created'),
                             Param(datatype='Boolean', name='isBookmark'),
                             Param(datatype='Long', name='date'),
                             Param(datatype='byte[]', name='favicon'),
                             Param(datatype='String', name='title'),
                             Param(datatype='Integer', name='visits')
                         ],
                         java_class_name=None,
                         type='method',
                         p0_type='ChromeBrowserProvider'),
            NativeMethod(return_type='int',
                         static=False,
                         name='FindAll',
                         params=[Param(datatype='String', name='find')],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='BookmarkNode',
                         static=True,
                         name='GetDefaultBookmarkFolder',
                         params=[],
                         java_class_name=None,
                         type='function'),
            NativeMethod(return_type='SQLiteCursor',
                         static=False,
                         name='QueryBookmarkFromAPI',
                         params=[
                             Param(datatype='int',
                                   name='nativeChromeBrowserProvider'),
                             Param(datatype='String[]', name='projection'),
                             Param(datatype='String', name='selection'),
                             Param(datatype='String[]', name='selectionArgs'),
                             Param(datatype='String', name='sortOrder'),
                         ],
                         java_class_name=None,
                         type='method',
                         p0_type='ChromeBrowserProvider'),
            NativeMethod(return_type='void',
                         static=False,
                         name='GotOrientation',
                         params=[
                             Param(datatype='int',
                                   name='nativeDataFetcherImplAndroid'),
                             Param(datatype='double', name='alpha'),
                             Param(datatype='double', name='beta'),
                             Param(datatype='double', name='gamma'),
                         ],
                         java_class_name=None,
                         type='method',
                         p0_type='device_orientation::DataFetcherImplAndroid'),
        ]
        self.assertListEquals(golden_natives, natives)
        h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni',
                                                 natives, [])
        golden_content = """\
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// This file is autogenerated by
//     base/android/jni_generator/jni_generator_tests.py
// For
//     org/chromium/TestJni

#ifndef org_chromium_TestJni_JNI
#define org_chromium_TestJni_JNI

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/basictypes.h"
#include "base/logging.h"

using base::android::ScopedJavaLocalRef;

// Step 1: forward declarations.
namespace {
const char kTestJniClassPath[] = "org/chromium/TestJni";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_TestJni_clazz = NULL;
}  // namespace

static jint Init(JNIEnv* env, jobject obj);

static jstring GetDomainAndRegistry(JNIEnv* env, jclass clazz,
    jstring url);

static void CreateHistoricalTabFromState(JNIEnv* env, jclass clazz,
    jbyteArray state,
    jint tab_index);

static jbyteArray GetStateAsByteArray(JNIEnv* env, jobject obj,
    jobject view);

static jobjectArray GetAutofillProfileGUIDs(JNIEnv* env, jclass clazz);

static void SetRecognitionResults(JNIEnv* env, jobject obj,
    jint sessionId,
    jobjectArray results);

static jint FindAll(JNIEnv* env, jobject obj,
    jstring find);

static jobject GetDefaultBookmarkFolder(JNIEnv* env, jclass clazz);

// Step 2: method stubs.
static void Destroy(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider) {
  DCHECK(nativeChromeBrowserProvider) << "Destroy";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->Destroy(env, obj);
}

static jlong AddBookmark(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jstring url,
    jstring title,
    jboolean isFolder,
    jlong parentId) {
  DCHECK(nativeChromeBrowserProvider) << "AddBookmark";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->AddBookmark(env, obj, url, title, isFolder, parentId);
}

static jlong AddBookmarkFromAPI(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jstring url,
    jobject created,
    jobject isBookmark,
    jobject date,
    jbyteArray favicon,
    jstring title,
    jobject visits) {
  DCHECK(nativeChromeBrowserProvider) << "AddBookmarkFromAPI";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->AddBookmarkFromAPI(env, obj, url, created, isBookmark, date,
      favicon, title, visits);
}

static jobject QueryBookmarkFromAPI(JNIEnv* env, jobject obj,
    jint nativeChromeBrowserProvider,
    jobjectArray projection,
    jstring selection,
    jobjectArray selectionArgs,
    jstring sortOrder) {
  DCHECK(nativeChromeBrowserProvider) << "QueryBookmarkFromAPI";
  ChromeBrowserProvider* native =
      reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider);
  return native->QueryBookmarkFromAPI(env, obj, projection, selection,
      selectionArgs, sortOrder).Release();
}

static void GotOrientation(JNIEnv* env, jobject obj,
    jint nativeDataFetcherImplAndroid,
    jdouble alpha,
    jdouble beta,
    jdouble gamma) {
  DCHECK(nativeDataFetcherImplAndroid) << "GotOrientation";
  DataFetcherImplAndroid* native =
    reinterpret_cast<DataFetcherImplAndroid*>(nativeDataFetcherImplAndroid);
  return native->GotOrientation(env, obj, alpha, beta, gamma);
}

// Step 3: GetMethodIDs and RegisterNatives.
static void GetMethodIDsImpl(JNIEnv* env) {
  g_TestJni_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetUnscopedClass(env, kTestJniClassPath)));
}

static bool RegisterNativesImpl(JNIEnv* env) {
  GetMethodIDsImpl(env);

  static const JNINativeMethod kMethodsTestJni[] = {
    { "nativeInit",
"("
")"
"I", reinterpret_cast<void*>(Init) },
    { "nativeDestroy",
"("
"I"
")"
"V", reinterpret_cast<void*>(Destroy) },
    { "nativeAddBookmark",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/String;"
"Z"
"J"
")"
"J", reinterpret_cast<void*>(AddBookmark) },
    { "nativeGetDomainAndRegistry",
"("
"Ljava/lang/String;"
")"
"Ljava/lang/String;", reinterpret_cast<void*>(GetDomainAndRegistry) },
    { "nativeCreateHistoricalTabFromState",
"("
"[B"
"I"
")"
"V", reinterpret_cast<void*>(CreateHistoricalTabFromState) },
    { "nativeGetStateAsByteArray",
"("
"Lorg/chromium/content/browser/ContentView;"
")"
"[B", reinterpret_cast<void*>(GetStateAsByteArray) },
    { "nativeGetAutofillProfileGUIDs",
"("
")"
"[Ljava/lang/String;", reinterpret_cast<void*>(GetAutofillProfileGUIDs) },
    { "nativeSetRecognitionResults",
"("
"I"
"[Ljava/lang/String;"
")"
"V", reinterpret_cast<void*>(SetRecognitionResults) },
    { "nativeAddBookmarkFromAPI",
"("
"I"
"Ljava/lang/String;"
"Ljava/lang/Long;"
"Ljava/lang/Boolean;"
"Ljava/lang/Long;"
"[B"
"Ljava/lang/String;"
"Ljava/lang/Integer;"
")"
"J", reinterpret_cast<void*>(AddBookmarkFromAPI) },
    { "nativeFindAll",
"("
"Ljava/lang/String;"
")"
"I", reinterpret_cast<void*>(FindAll) },
    { "nativeGetDefaultBookmarkFolder",
"("
")"
"Lcom/google/android/apps/chrome/ChromeBrowserProvider$BookmarkNode;",
    reinterpret_cast<void*>(GetDefaultBookmarkFolder) },
    { "nativeQueryBookmarkFromAPI",
"("
"I"
"[Ljava/lang/String;"
"Ljava/lang/String;"
"[Ljava/lang/String;"
"Ljava/lang/String;"
")"
"Lcom/google/android/apps/chrome/database/SQLiteCursor;",
    reinterpret_cast<void*>(QueryBookmarkFromAPI) },
    { "nativeGotOrientation",
"("
"I"
"D"
"D"
"D"
")"
"V", reinterpret_cast<void*>(GotOrientation) },
  };
  const int kMethodsTestJniSize = arraysize(kMethodsTestJni);

  if (env->RegisterNatives(g_TestJni_clazz,
                           kMethodsTestJni,
                           kMethodsTestJniSize) < 0) {
    LOG(ERROR) << "RegisterNatives failed in " << __FILE__;
    return false;
  }

  return true;
}

#endif  // org_chromium_TestJni_JNI
"""
        self.assertTextEquals(golden_content, h.GetContent())
Ejemplo n.º 12
0
def convert_nonstatic_to_static(java_file_name,
                                skip_caller=False,
                                dry=False,
                                verbose=True):
    if java_file_name is None:
        return
    if not os.path.isfile(java_file_name):
        if verbose:
            print('%s does not exist', java_file_name)
        return

    with open(java_file_name, 'r') as f:
        contents = f.read()

    no_comment_content = jni_generator.RemoveComments(contents)
    parsed_natives = jni_generator.ExtractNatives(no_comment_content, 'long')
    non_static_natives = [n for n in parsed_natives if not n.static]
    if not non_static_natives:
        if verbose:
            print('no natives found')
        return

    class_name = jni_generator.ExtractFullyQualifiedJavaClassName(
        java_file_name, no_comment_content).split('/')[-1]

    # For fixing call sites.
    replace_patterns = []
    should_append_comma = []
    should_prepend_comma = []

    new_contents = contents

    # 1. Change non-static -> static.
    insertion_offset = 0

    matches = []
    for match in _NON_STATIC_NATIVES_REGEX.finditer(contents):
        if not 'static' in match.group('qualifiers'):
            matches.append(match)
            # Insert static as a keyword.
            qual_end = match.end('qualifiers') + insertion_offset
            insert_str = ' static '
            new_contents = new_contents[:qual_end] + insert_str + new_contents[
                qual_end:]
            insertion_offset += len(insert_str)

            if skip_caller:
                continue

            # Insert an object param.
            insert_str = '%s caller' % class_name
            # No params.
            if not match.group('params'):
                start = insertion_offset + match.start('params')
                append_comma = False
                prepend_comma = False

            # One or more params.
            else:
                # Has mNativePtr.
                if _NATIVE_PTR_REGEX.match(match.group('params')):
                    # Only 1 param, append to end of params.
                    if match.group('params').count(',') == 0:
                        start = insertion_offset + match.end('params')
                        append_comma = False
                        prepend_comma = True
                    # Multiple params, insert after first param.
                    else:
                        comma_pos = match.group('params').find(',')
                        start = insertion_offset + match.start(
                            'params') + comma_pos + 1
                        append_comma = True
                        prepend_comma = False
                else:
                    # No mNativePtr, insert as first param.
                    start = insertion_offset + match.start('params')
                    append_comma = True
                    prepend_comma = False

            if prepend_comma:
                insert_str = ', ' + insert_str
            if append_comma:
                insert_str = insert_str + ', '
            new_contents = new_contents[:start] + insert_str + new_contents[
                start:]

            # Match lines that don't have a native keyword.
            native_match = r'\((\s*?(([ms]Native\w+)|([ms]\w+Android(Ptr)?)),?)?)'
            replace_patterns.append(r'(^\s*' + match.group('name') +
                                    native_match)
            replace_patterns.append(r'(return ' + match.group('name') +
                                    native_match)
            replace_patterns.append(r'([\:\)\(\+\*\?\&\|,\.\-\=\!\/][ \t]*' +
                                    match.group('name') + native_match)

            should_append_comma.extend([append_comma] * 3)
            should_prepend_comma.extend([prepend_comma] * 3)
            insertion_offset += len(insert_str)

    assert len(matches) == len(non_static_natives), (
        'Regex missed a native '
        'method that was found by '
        'the jni_generator.')

    # 2. Add a this param to all calls.
    for i, r in enumerate(replace_patterns):
        prepend_comma = ', ' if should_prepend_comma[i] else ''
        append_comma = ', ' if should_append_comma[i] else ''
        repl_str = '\g<1>' + prepend_comma + ' %s.this' + append_comma
        new_contents = re.sub(r,
                              repl_str % class_name,
                              new_contents,
                              flags=re.MULTILINE)

    if dry:
        print(new_contents)
    else:
        with open(java_file_name, 'w') as f:
            f.write(new_contents)