def testInnerClassNativesMultiple(self): test_data = """ class MyInnerClass { @NativeCall("MyInnerClass") 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='MyInnerClass', 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())
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')
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', use_hash=use_proxy_hash) 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()
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 testImports(self): import_header = """ // 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. package org.chromium.content.app; import android.app.Service; import android.content.Context; import android.content.Intent; import android.graphics.SurfaceTexture; import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; import android.util.Log; import android.view.Surface; import java.util.ArrayList; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; import org.chromium.content.app.ContentMain; import org.chromium.content.browser.SandboxedProcessConnection; import org.chromium.content.common.ISandboxedProcessCallback; import org.chromium.content.common.ISandboxedProcessService; import org.chromium.content.common.WillNotRaise.AnException; import org.chromium.content.common.WillRaise.AnException; import static org.chromium.Bar.Zoo; class Foo { public static class BookmarkNode implements Parcelable { } public interface PasswordListObserver { } } """ jni_params = jni_generator.JniParams('org/chromium/content/app/Foo') jni_params.ExtractImportsAndInnerClasses(import_header) self.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in jni_params._imports) self.assertTrue('Lorg/chromium/Bar/Zoo' in jni_params._imports) self.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in jni_params._inner_classes) self.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in jni_params._inner_classes) self.assertEquals('Lorg/chromium/content/app/ContentMain$Inner;', jni_params.JavaToJni('ContentMain.Inner')) self.assertRaises(SyntaxError, jni_params.JavaToJni, 'AnException')
def testCalledByNativeParseError(self): try: jni_params = jni_generator.JniParams('') jni_generator.ExtractCalledByNatives(jni_params, """ @CalledByNative public static int foo(); // This one is fine @CalledByNative scooby doo """) self.fail('Expected a ParseError') except jni_generator.ParseError, e: self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines)
def _DictForPath(path): with open(path) as f: contents = jni_generator.RemoveComments(f.read()) natives = jni_generator.ExtractNatives(contents, 'long') if len(natives) == 0: return None 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, main_dex) return header_generator.Generate()
def testMethodNameMangling(self): jni_params = jni_generator.JniParams('') self.assertEquals('closeV', jni_generator.GetMangledMethodName(jni_params, 'close', [], 'void')) self.assertEquals('readI_AB_I_I', jni_generator.GetMangledMethodName(jni_params, 'read', [Param(name='p1', datatype='byte[]'), Param(name='p2', datatype='int'), Param(name='p3', datatype='int'),], 'int')) self.assertEquals('openJIIS_JLS', jni_generator.GetMangledMethodName(jni_params, 'open', [Param(name='p1', datatype='java/lang/String'),], 'java/io/InputStream'))
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
def testJniParamsJavaToJni(self): jni_params = jni_generator.JniParams('') self.assertTextEquals('I', jni_params.JavaToJni('int')) self.assertTextEquals('[B', jni_params.JavaToJni('byte[]')) self.assertTextEquals( '[Ljava/nio/ByteBuffer;', jni_params.JavaToJni('java/nio/ByteBuffer[]'))
def testCalledByNatives(self): test_data = """" import android.graphics.Bitmap; import android.view.View; import java.io.InputStream; import java.util.List; class InnerClass {} @CalledByNative InnerClass showConfirmInfoBar(int nativeInfoBar, String buttonOk, String buttonCancel, String title, Bitmap icon) { InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext, buttonOk, buttonCancel, title, icon); return infobar; } @CalledByNative InnerClass showAutoLoginInfoBar(int nativeInfoBar, String realm, String account, String args) { AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext, realm, account, args); if (infobar.displayedAccountCount() == 0) infobar = null; return infobar; } @CalledByNative("InfoBar") void dismiss(); @SuppressWarnings("unused") @CalledByNative private static boolean shouldShowAutoLogin(View view, String realm, String account, String args) { AccountManagerContainer accountManagerContainer = new AccountManagerContainer((Activity)contentView.getContext(), realm, account, args); String[] logins = accountManagerContainer.getAccountLogins(null); return logins.length != 0; } @CalledByNative static InputStream openUrl(String url) { return null; } @CalledByNative private void activateHardwareAcceleration(final boolean activated, final int iPid, final int iType, final int iPrimaryID, final int iSecondaryID) { if (!activated) { return } } @CalledByNative public static @Status int updateStatus(@Status int status) { return getAndUpdateStatus(status); } @CalledByNativeUnchecked private void uncheckedCall(int iParam); @CalledByNative public byte[] returnByteArray(); @CalledByNative public boolean[] returnBooleanArray(); @CalledByNative public char[] returnCharArray(); @CalledByNative public short[] returnShortArray(); @CalledByNative public int[] returnIntArray(); @CalledByNative public long[] returnLongArray(); @CalledByNative public double[] returnDoubleArray(); @CalledByNative public Object[] returnObjectArray(); @CalledByNative public byte[][] returnArrayOfByteArray(); @CalledByNative public Bitmap.CompressFormat getCompressFormat(); @CalledByNative public List<Bitmap.CompressFormat> getCompressFormatList(); """ jni_params = jni_generator.JniParams('org/chromium/Foo') jni_params.ExtractImportsAndInnerClasses(test_data) called_by_natives = jni_generator.ExtractCalledByNatives(jni_params, test_data) golden_called_by_natives = [ CalledByNative( return_type='InnerClass', system_class=False, static=False, name='showConfirmInfoBar', method_id_var_name='showConfirmInfoBar', java_class_name='', params=[Param(datatype='int', name='nativeInfoBar'), Param(datatype='String', name='buttonOk'), Param(datatype='String', name='buttonCancel'), Param(datatype='String', name='title'), Param(datatype='Bitmap', name='icon')], env_call=('Object', ''), unchecked=False, ), CalledByNative( return_type='InnerClass', system_class=False, static=False, name='showAutoLoginInfoBar', method_id_var_name='showAutoLoginInfoBar', java_class_name='', params=[Param(datatype='int', name='nativeInfoBar'), Param(datatype='String', name='realm'), Param(datatype='String', name='account'), Param(datatype='String', name='args')], env_call=('Object', ''), unchecked=False, ), CalledByNative( return_type='void', system_class=False, static=False, name='dismiss', method_id_var_name='dismiss', java_class_name='InfoBar', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='boolean', system_class=False, static=True, name='shouldShowAutoLogin', method_id_var_name='shouldShowAutoLogin', java_class_name='', params=[Param(datatype='View', name='view'), Param(datatype='String', name='realm'), Param(datatype='String', name='account'), Param(datatype='String', name='args')], env_call=('Boolean', ''), unchecked=False, ), CalledByNative( return_type='InputStream', system_class=False, static=True, name='openUrl', method_id_var_name='openUrl', java_class_name='', params=[Param(datatype='String', name='url')], env_call=('Object', ''), unchecked=False, ), CalledByNative( return_type='void', system_class=False, static=False, name='activateHardwareAcceleration', method_id_var_name='activateHardwareAcceleration', java_class_name='', params=[Param(datatype='boolean', name='activated'), Param(datatype='int', name='iPid'), Param(datatype='int', name='iType'), Param(datatype='int', name='iPrimaryID'), Param(datatype='int', name='iSecondaryID'), ], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='int', system_class=False, static=True, name='updateStatus', method_id_var_name='updateStatus', java_class_name='', params=[Param(datatype='int', name='status')], env_call=('Integer', ''), unchecked=False, ), CalledByNative( return_type='void', system_class=False, static=False, name='uncheckedCall', method_id_var_name='uncheckedCall', java_class_name='', params=[Param(datatype='int', name='iParam')], env_call=('Void', ''), unchecked=True, ), CalledByNative( return_type='byte[]', system_class=False, static=False, name='returnByteArray', method_id_var_name='returnByteArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='boolean[]', system_class=False, static=False, name='returnBooleanArray', method_id_var_name='returnBooleanArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='char[]', system_class=False, static=False, name='returnCharArray', method_id_var_name='returnCharArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='short[]', system_class=False, static=False, name='returnShortArray', method_id_var_name='returnShortArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='int[]', system_class=False, static=False, name='returnIntArray', method_id_var_name='returnIntArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='long[]', system_class=False, static=False, name='returnLongArray', method_id_var_name='returnLongArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='double[]', system_class=False, static=False, name='returnDoubleArray', method_id_var_name='returnDoubleArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='Object[]', system_class=False, static=False, name='returnObjectArray', method_id_var_name='returnObjectArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='byte[][]', system_class=False, static=False, name='returnArrayOfByteArray', method_id_var_name='returnArrayOfByteArray', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='Bitmap.CompressFormat', system_class=False, static=False, name='getCompressFormat', method_id_var_name='getCompressFormat', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), CalledByNative( return_type='List<Bitmap.CompressFormat>', system_class=False, static=False, name='getCompressFormatList', method_id_var_name='getCompressFormatList', java_class_name='', params=[], env_call=('Void', ''), unchecked=False, ), ] self.assertListEquals(golden_called_by_natives, called_by_natives) h = jni_generator.InlHeaderFileGenerator( '', 'org/chromium/TestJni', [], called_by_natives, [], jni_params, TestOptions()) self.assertGoldenTextEquals(h.GetContent())
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')