2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Tests for jni_generator.py.
8 This test suite contains various tests for the JNI generator.
9 It exercises the low-level parser all the way up to the
10 code generator and ensures the output matches a golden
21 from jni_generator
import CalledByNative
, JniParams
, NativeMethod
, Param
24 SCRIPT_NAME
= 'base/android/jni_generator/jni_generator.py'
26 'base/android/jni_generator/jni_generator_helper.h'
29 # Set this environment variable in order to regenerate the golden text
31 REBASELINE_ENV
= 'REBASELINE'
33 class TestOptions(object):
34 """The mock options object which is passed to the jni_generator.py script."""
38 self
.script_name
= SCRIPT_NAME
39 self
.includes
= INCLUDES
40 self
.pure_native_methods
= False
41 self
.ptr_type
= 'long'
42 self
.jni_init_native_name
= None
43 self
.eager_called_by_natives
= False
46 self
.native_exports
= False
47 self
.native_exports_optional
= False
49 class TestGenerator(unittest
.TestCase
):
50 def assertObjEquals(self
, first
, second
):
51 dict_first
= first
.__dict
__
52 dict_second
= second
.__dict
__
53 self
.assertEquals(dict_first
.keys(), dict_second
.keys())
54 for key
, value
in dict_first
.iteritems():
55 if (type(value
) is list and len(value
) and
56 isinstance(type(value
[0]), object)):
57 self
.assertListEquals(value
, second
.__getattribute
__(key
))
59 actual
= second
.__getattribute
__(key
)
60 self
.assertEquals(value
, actual
,
61 'Key ' + key
+ ': ' + str(value
) + '!=' + str(actual
))
63 def assertListEquals(self
, first
, second
):
64 self
.assertEquals(len(first
), len(second
))
65 for i
in xrange(len(first
)):
66 if isinstance(first
[i
], object):
67 self
.assertObjEquals(first
[i
], second
[i
])
69 self
.assertEquals(first
[i
], second
[i
])
71 def assertTextEquals(self
, golden_text
, generated_text
):
72 if not self
.compareText(golden_text
, generated_text
):
73 self
.fail('Golden text mismatch.')
75 def compareText(self
, golden_text
, generated_text
):
78 l
.strip() for l
in text
.split('\n')
79 if not l
.startswith('// Copyright')
81 stripped_golden
= FilterText(golden_text
)
82 stripped_generated
= FilterText(generated_text
)
83 if stripped_golden
== stripped_generated
:
86 for line
in difflib
.context_diff(stripped_golden
, stripped_generated
):
93 print 'REBASELINE=1', sys
.argv
[0]
94 print 'to regenerate the data files.'
96 def _ReadGoldenFile(self
, golden_file
):
97 if not os
.path
.exists(golden_file
):
99 with
file(golden_file
, 'r') as f
:
102 def assertGoldenTextEquals(self
, generated_text
):
103 script_dir
= os
.path
.dirname(sys
.argv
[0])
104 # This is the caller test method.
105 caller
= inspect
.stack()[1][3]
106 self
.assertTrue(caller
.startswith('test'),
107 'assertGoldenTextEquals can only be called from a '
108 'test* method, not %s' % caller
)
109 golden_file
= os
.path
.join(script_dir
, caller
+ '.golden')
110 golden_text
= self
._ReadGoldenFile
(golden_file
)
111 if os
.environ
.get(REBASELINE_ENV
):
112 if golden_text
!= generated_text
:
113 with
file(golden_file
, 'w') as f
:
114 f
.write(generated_text
)
116 self
.assertTextEquals(golden_text
, generated_text
)
118 def testInspectCaller(self
):
120 # This function can only be called from a test* method.
121 self
.assertGoldenTextEquals('')
122 self
.assertRaises(AssertionError, willRaise
)
124 def testNatives(self
):
126 interface OnFrameAvailableListener {}
127 private native int nativeInit();
128 private native void nativeDestroy(int nativeChromeBrowserProvider);
129 private native long nativeAddBookmark(
130 int nativeChromeBrowserProvider,
131 String url, String title, boolean isFolder, long parentId);
132 private static native String nativeGetDomainAndRegistry(String url);
133 private static native void nativeCreateHistoricalTabFromState(
134 byte[] state, int tab_index);
135 private native byte[] nativeGetStateAsByteArray(View view);
136 private static native String[] nativeGetAutofillProfileGUIDs();
137 private native void nativeSetRecognitionResults(
138 int sessionId, String[] results);
139 private native long nativeAddBookmarkFromAPI(
140 int nativeChromeBrowserProvider,
141 String url, Long created, Boolean isBookmark,
142 Long date, byte[] favicon, String title, Integer visits);
143 native int nativeFindAll(String find);
144 private static native OnFrameAvailableListener nativeGetInnerClass();
145 private native Bitmap nativeQueryBitmap(
146 int nativeChromeBrowserProvider,
147 String[] projection, String selection,
148 String[] selectionArgs, String sortOrder);
149 private native void nativeGotOrientation(
150 int nativeDataFetcherImplAndroid,
151 double alpha, double beta, double gamma);
152 private static native Throwable nativeMessWithJavaException(Throwable e);
154 jni_generator
.JniParams
.SetFullyQualifiedClass(
155 'org/chromium/example/jni_generator/SampleForTests')
156 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
157 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
159 NativeMethod(return_type
='int', static
=False,
162 java_class_name
=None,
164 NativeMethod(return_type
='void', static
=False, name
='Destroy',
165 params
=[Param(datatype
='int',
166 name
='nativeChromeBrowserProvider')],
167 java_class_name
=None,
169 p0_type
='ChromeBrowserProvider'),
170 NativeMethod(return_type
='long', static
=False, name
='AddBookmark',
171 params
=[Param(datatype
='int',
172 name
='nativeChromeBrowserProvider'),
173 Param(datatype
='String',
175 Param(datatype
='String',
177 Param(datatype
='boolean',
179 Param(datatype
='long',
181 java_class_name
=None,
183 p0_type
='ChromeBrowserProvider'),
184 NativeMethod(return_type
='String', static
=True,
185 name
='GetDomainAndRegistry',
186 params
=[Param(datatype
='String',
188 java_class_name
=None,
190 NativeMethod(return_type
='void', static
=True,
191 name
='CreateHistoricalTabFromState',
192 params
=[Param(datatype
='byte[]',
194 Param(datatype
='int',
196 java_class_name
=None,
198 NativeMethod(return_type
='byte[]', static
=False,
199 name
='GetStateAsByteArray',
200 params
=[Param(datatype
='View', name
='view')],
201 java_class_name
=None,
203 NativeMethod(return_type
='String[]', static
=True,
204 name
='GetAutofillProfileGUIDs', params
=[],
205 java_class_name
=None,
207 NativeMethod(return_type
='void', static
=False,
208 name
='SetRecognitionResults',
209 params
=[Param(datatype
='int', name
='sessionId'),
210 Param(datatype
='String[]', name
='results')],
211 java_class_name
=None,
213 NativeMethod(return_type
='long', static
=False,
214 name
='AddBookmarkFromAPI',
215 params
=[Param(datatype
='int',
216 name
='nativeChromeBrowserProvider'),
217 Param(datatype
='String',
219 Param(datatype
='Long',
221 Param(datatype
='Boolean',
223 Param(datatype
='Long',
225 Param(datatype
='byte[]',
227 Param(datatype
='String',
229 Param(datatype
='Integer',
231 java_class_name
=None,
233 p0_type
='ChromeBrowserProvider'),
234 NativeMethod(return_type
='int', static
=False,
236 params
=[Param(datatype
='String',
238 java_class_name
=None,
240 NativeMethod(return_type
='OnFrameAvailableListener', static
=True,
241 name
='GetInnerClass',
243 java_class_name
=None,
245 NativeMethod(return_type
='Bitmap',
248 params
=[Param(datatype
='int',
249 name
='nativeChromeBrowserProvider'),
250 Param(datatype
='String[]',
252 Param(datatype
='String',
254 Param(datatype
='String[]',
255 name
='selectionArgs'),
256 Param(datatype
='String',
259 java_class_name
=None,
261 p0_type
='ChromeBrowserProvider'),
262 NativeMethod(return_type
='void', static
=False,
263 name
='GotOrientation',
264 params
=[Param(datatype
='int',
265 name
='nativeDataFetcherImplAndroid'),
266 Param(datatype
='double',
268 Param(datatype
='double',
270 Param(datatype
='double',
273 java_class_name
=None,
275 p0_type
='content::DataFetcherImplAndroid'),
276 NativeMethod(return_type
='Throwable', static
=True,
277 name
='MessWithJavaException',
278 params
=[Param(datatype
='Throwable', name
='e')],
279 java_class_name
=None,
282 self
.assertListEquals(golden_natives
, natives
)
283 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
284 natives
, [], [], TestOptions())
285 self
.assertGoldenTextEquals(h
.GetContent())
287 def testInnerClassNatives(self
):
290 @NativeCall("MyInnerClass")
291 private native int nativeInit();
294 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
296 NativeMethod(return_type
='int', static
=False,
297 name
='Init', params
=[],
298 java_class_name
='MyInnerClass',
301 self
.assertListEquals(golden_natives
, natives
)
302 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
303 natives
, [], [], TestOptions())
304 self
.assertGoldenTextEquals(h
.GetContent())
306 def testInnerClassNativesMultiple(self
):
309 @NativeCall("MyInnerClass")
310 private native int nativeInit();
312 class MyOtherInnerClass {
313 @NativeCall("MyOtherInnerClass")
314 private native int nativeInit();
317 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
319 NativeMethod(return_type
='int', static
=False,
320 name
='Init', params
=[],
321 java_class_name
='MyInnerClass',
323 NativeMethod(return_type
='int', static
=False,
324 name
='Init', params
=[],
325 java_class_name
='MyOtherInnerClass',
328 self
.assertListEquals(golden_natives
, natives
)
329 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
330 natives
, [], [], TestOptions())
331 self
.assertGoldenTextEquals(h
.GetContent())
333 def testInnerClassNativesBothInnerAndOuter(self
):
336 private native int nativeInit();
337 class MyOtherInnerClass {
338 @NativeCall("MyOtherInnerClass")
339 private native int nativeInit();
343 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
345 NativeMethod(return_type
='int', static
=False,
346 name
='Init', params
=[],
347 java_class_name
=None,
349 NativeMethod(return_type
='int', static
=False,
350 name
='Init', params
=[],
351 java_class_name
='MyOtherInnerClass',
354 self
.assertListEquals(golden_natives
, natives
)
355 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
356 natives
, [], [], TestOptions())
357 self
.assertGoldenTextEquals(h
.GetContent())
359 def testCalledByNatives(self
):
361 import android.graphics.Bitmap;
362 import android.view.View;
363 import java.io.InputStream;
364 import java.util.List;
369 InnerClass showConfirmInfoBar(int nativeInfoBar,
370 String buttonOk, String buttonCancel, String title, Bitmap icon) {
371 InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext,
372 buttonOk, buttonCancel,
377 InnerClass showAutoLoginInfoBar(int nativeInfoBar,
378 String realm, String account, String args) {
379 AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext,
380 realm, account, args);
381 if (infobar.displayedAccountCount() == 0)
385 @CalledByNative("InfoBar")
387 @SuppressWarnings("unused")
389 private static boolean shouldShowAutoLogin(View view,
390 String realm, String account, String args) {
391 AccountManagerContainer accountManagerContainer =
392 new AccountManagerContainer((Activity)contentView.getContext(),
393 realm, account, args);
394 String[] logins = accountManagerContainer.getAccountLogins(null);
395 return logins.length != 0;
398 static InputStream openUrl(String url) {
402 private void activateHardwareAcceleration(final boolean activated,
403 final int iPid, final int iType,
404 final int iPrimaryID, final int iSecondaryID) {
409 @CalledByNativeUnchecked
410 private void uncheckedCall(int iParam);
413 public byte[] returnByteArray();
416 public boolean[] returnBooleanArray();
419 public char[] returnCharArray();
422 public short[] returnShortArray();
425 public int[] returnIntArray();
428 public long[] returnLongArray();
431 public double[] returnDoubleArray();
434 public Object[] returnObjectArray();
437 public byte[][] returnArrayOfByteArray();
440 public Bitmap.CompressFormat getCompressFormat();
443 public List<Bitmap.CompressFormat> getCompressFormatList();
445 jni_generator
.JniParams
.SetFullyQualifiedClass('org/chromium/Foo')
446 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
447 called_by_natives
= jni_generator
.ExtractCalledByNatives(test_data
)
448 golden_called_by_natives
= [
450 return_type
='InnerClass',
453 name
='showConfirmInfoBar',
454 method_id_var_name
='showConfirmInfoBar',
456 params
=[Param(datatype
='int', name
='nativeInfoBar'),
457 Param(datatype
='String', name
='buttonOk'),
458 Param(datatype
='String', name
='buttonCancel'),
459 Param(datatype
='String', name
='title'),
460 Param(datatype
='Bitmap', name
='icon')],
461 env_call
=('Object', ''),
465 return_type
='InnerClass',
468 name
='showAutoLoginInfoBar',
469 method_id_var_name
='showAutoLoginInfoBar',
471 params
=[Param(datatype
='int', name
='nativeInfoBar'),
472 Param(datatype
='String', name
='realm'),
473 Param(datatype
='String', name
='account'),
474 Param(datatype
='String', name
='args')],
475 env_call
=('Object', ''),
483 method_id_var_name
='dismiss',
484 java_class_name
='InfoBar',
486 env_call
=('Void', ''),
490 return_type
='boolean',
493 name
='shouldShowAutoLogin',
494 method_id_var_name
='shouldShowAutoLogin',
496 params
=[Param(datatype
='View', name
='view'),
497 Param(datatype
='String', name
='realm'),
498 Param(datatype
='String', name
='account'),
499 Param(datatype
='String', name
='args')],
500 env_call
=('Boolean', ''),
504 return_type
='InputStream',
508 method_id_var_name
='openUrl',
510 params
=[Param(datatype
='String', name
='url')],
511 env_call
=('Object', ''),
518 name
='activateHardwareAcceleration',
519 method_id_var_name
='activateHardwareAcceleration',
521 params
=[Param(datatype
='boolean', name
='activated'),
522 Param(datatype
='int', name
='iPid'),
523 Param(datatype
='int', name
='iType'),
524 Param(datatype
='int', name
='iPrimaryID'),
525 Param(datatype
='int', name
='iSecondaryID'),
527 env_call
=('Void', ''),
534 name
='uncheckedCall',
535 method_id_var_name
='uncheckedCall',
537 params
=[Param(datatype
='int', name
='iParam')],
538 env_call
=('Void', ''),
542 return_type
='byte[]',
545 name
='returnByteArray',
546 method_id_var_name
='returnByteArray',
549 env_call
=('Void', ''),
553 return_type
='boolean[]',
556 name
='returnBooleanArray',
557 method_id_var_name
='returnBooleanArray',
560 env_call
=('Void', ''),
564 return_type
='char[]',
567 name
='returnCharArray',
568 method_id_var_name
='returnCharArray',
571 env_call
=('Void', ''),
575 return_type
='short[]',
578 name
='returnShortArray',
579 method_id_var_name
='returnShortArray',
582 env_call
=('Void', ''),
589 name
='returnIntArray',
590 method_id_var_name
='returnIntArray',
593 env_call
=('Void', ''),
597 return_type
='long[]',
600 name
='returnLongArray',
601 method_id_var_name
='returnLongArray',
604 env_call
=('Void', ''),
608 return_type
='double[]',
611 name
='returnDoubleArray',
612 method_id_var_name
='returnDoubleArray',
615 env_call
=('Void', ''),
619 return_type
='Object[]',
622 name
='returnObjectArray',
623 method_id_var_name
='returnObjectArray',
626 env_call
=('Void', ''),
630 return_type
='byte[][]',
633 name
='returnArrayOfByteArray',
634 method_id_var_name
='returnArrayOfByteArray',
637 env_call
=('Void', ''),
641 return_type
='Bitmap.CompressFormat',
644 name
='getCompressFormat',
645 method_id_var_name
='getCompressFormat',
648 env_call
=('Void', ''),
652 return_type
='List<Bitmap.CompressFormat>',
655 name
='getCompressFormatList',
656 method_id_var_name
='getCompressFormatList',
659 env_call
=('Void', ''),
663 self
.assertListEquals(golden_called_by_natives
, called_by_natives
)
664 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
665 [], called_by_natives
, [],
667 self
.assertGoldenTextEquals(h
.GetContent())
669 def testCalledByNativeParseError(self
):
671 jni_generator
.ExtractCalledByNatives("""
673 public static int foo(); // This one is fine
678 self
.fail('Expected a ParseError')
679 except jni_generator
.ParseError
, e
:
680 self
.assertEquals(('@CalledByNative', 'scooby doo'), e
.context_lines
)
682 def testFullyQualifiedClassName(self
):
684 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
685 // Use of this source code is governed by a BSD-style license that can be
686 // found in the LICENSE file.
688 package org.chromium.content.browser;
690 import org.chromium.base.BuildInfo;
692 self
.assertEquals('org/chromium/content/browser/Foo',
693 jni_generator
.ExtractFullyQualifiedJavaClassName(
694 'org/chromium/content/browser/Foo.java', contents
))
695 self
.assertEquals('org/chromium/content/browser/Foo',
696 jni_generator
.ExtractFullyQualifiedJavaClassName(
697 'frameworks/Foo.java', contents
))
698 self
.assertRaises(SyntaxError,
699 jni_generator
.ExtractFullyQualifiedJavaClassName
,
700 'com/foo/Bar', 'no PACKAGE line')
702 def testMethodNameMangling(self
):
703 self
.assertEquals('closeV',
704 jni_generator
.GetMangledMethodName('close', [], 'void'))
705 self
.assertEquals('readI_AB_I_I',
706 jni_generator
.GetMangledMethodName('read',
714 self
.assertEquals('openJIIS_JLS',
715 jni_generator
.GetMangledMethodName('open',
717 datatype
='java/lang/String'),],
718 'java/io/InputStream'))
720 def testFromJavaPGenerics(self
):
722 public abstract class java.util.HashSet<T> extends java.util.AbstractSet<E>
723 implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
728 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
730 self
.assertEquals(1, len(jni_from_javap
.called_by_natives
))
731 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
733 def testSnippnetJavap6_7_8(self
):
735 public class java.util.HashSet {
736 public boolean add(java.lang.Object);
737 Signature: (Ljava/lang/Object;)Z
742 public class java.util.HashSet {
743 public boolean add(E);
744 Signature: (Ljava/lang/Object;)Z
749 public class java.util.HashSet {
750 public boolean add(E);
751 descriptor: (Ljava/lang/Object;)Z
755 jni_from_javap6
= jni_generator
.JNIFromJavaP(content_javap6
.split('\n'),
757 jni_from_javap7
= jni_generator
.JNIFromJavaP(content_javap7
.split('\n'),
759 jni_from_javap8
= jni_generator
.JNIFromJavaP(content_javap8
.split('\n'),
761 self
.assertTrue(jni_from_javap6
.GetContent())
762 self
.assertTrue(jni_from_javap7
.GetContent())
763 self
.assertTrue(jni_from_javap8
.GetContent())
764 # Ensure the javap7 is correctly parsed and uses the Signature field rather
765 # than the "E" parameter.
766 self
.assertTextEquals(jni_from_javap6
.GetContent(),
767 jni_from_javap7
.GetContent())
768 # Ensure the javap8 is correctly parsed and uses the descriptor field.
769 self
.assertTextEquals(jni_from_javap7
.GetContent(),
770 jni_from_javap8
.GetContent())
772 def testFromJavaP(self
):
773 contents
= self
._ReadGoldenFile
(os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
774 'testInputStream.javap'))
775 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
777 self
.assertEquals(10, len(jni_from_javap
.called_by_natives
))
778 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
780 def testConstantsFromJavaP(self
):
781 for f
in ['testMotionEvent.javap', 'testMotionEvent.javap7']:
782 contents
= self
._ReadGoldenFile
(os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
784 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
786 self
.assertEquals(86, len(jni_from_javap
.called_by_natives
))
787 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
789 def testREForNatives(self
):
790 # We should not match "native SyncSetupFlow" inside the comment.
793 * Invoked when the setup process is complete so we can disconnect from the
794 * native-side SyncSetupFlowHandler.
796 public void destroy() {
797 Log.v(TAG, "Destroying native SyncSetupFlow");
798 if (mNativeSyncSetupFlow != 0) {
799 nativeSyncSetupEnded(mNativeSyncSetupFlow);
800 mNativeSyncSetupFlow = 0;
803 private native void nativeSyncSetupEnded(
804 int nativeAndroidSyncSetupFlowHandler);
806 jni_from_java
= jni_generator
.JNIFromJavaSource(
807 test_data
, 'foo/bar', TestOptions())
809 def testRaisesOnNonJNIMethod(self
):
812 private int Foo(int p0) {
816 self
.assertRaises(SyntaxError,
817 jni_generator
.JNIFromJavaSource
,
818 test_data
, 'foo/bar', TestOptions())
820 def testJniSelfDocumentingExample(self
):
821 script_dir
= os
.path
.dirname(sys
.argv
[0])
822 content
= file(os
.path
.join(script_dir
,
823 'java/src/org/chromium/example/jni_generator/SampleForTests.java')
825 golden_file
= os
.path
.join(script_dir
, 'golden_sample_for_tests_jni.h')
826 golden_content
= file(golden_file
).read()
827 jni_from_java
= jni_generator
.JNIFromJavaSource(
828 content
, 'org/chromium/example/jni_generator/SampleForTests',
830 generated_text
= jni_from_java
.GetContent()
831 if not self
.compareText(golden_content
, generated_text
):
832 if os
.environ
.get(REBASELINE_ENV
):
833 with
file(golden_file
, 'w') as f
:
834 f
.write(generated_text
)
836 self
.fail('testJniSelfDocumentingExample')
838 def testNoWrappingPreprocessorLines(self
):
840 package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday;
842 class ReallyLongClassNamesAreAllTheRage {
843 private static native int nativeTest();
846 jni_from_java
= jni_generator
.JNIFromJavaSource(
847 test_data
, ('com/google/lookhowextremelylongiam/snarf/'
848 'icankeepthisupallday/ReallyLongClassNamesAreAllTheRage'),
850 jni_lines
= jni_from_java
.GetContent().split('\n')
851 line
= filter(lambda line
: line
.lstrip().startswith('#ifndef'),
853 self
.assertTrue(len(line
) > 80,
854 ('Expected #ifndef line to be > 80 chars: ', line
))
856 def testJarJarRemapping(self
):
858 package org.chromium.example.jni_generator;
860 import org.chromium.example2.Test;
862 import org.chromium.example3.PrefixFoo;
863 import org.chromium.example3.Prefix;
864 import org.chromium.example3.Bar$Inner;
867 private static native void nativeTest(Test t);
868 private static native void nativeTest2(PrefixFoo t);
869 private static native void nativeTest3(Prefix t);
870 private static native void nativeTest4(Bar$Inner t);
873 jni_generator
.JniParams
.SetJarJarMappings(
874 """rule org.chromium.example.** com.test.@1
875 rule org.chromium.example2.** org.test2.@1
876 rule org.chromium.example3.Prefix org.test3.Test
877 rule org.chromium.example3.Bar$** org.test3.TestBar$@1""")
878 jni_from_java
= jni_generator
.JNIFromJavaSource(
879 test_data
, 'org/chromium/example/jni_generator/Example', TestOptions())
880 jni_generator
.JniParams
.SetJarJarMappings('')
881 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
883 def testImports(self
):
885 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
886 // Use of this source code is governed by a BSD-style license that can be
887 // found in the LICENSE file.
889 package org.chromium.content.app;
891 import android.app.Service;
892 import android.content.Context;
893 import android.content.Intent;
894 import android.graphics.SurfaceTexture;
895 import android.os.Bundle;
896 import android.os.IBinder;
897 import android.os.ParcelFileDescriptor;
898 import android.os.Process;
899 import android.os.RemoteException;
900 import android.util.Log;
901 import android.view.Surface;
903 import java.util.ArrayList;
905 import org.chromium.base.annotations.CalledByNative;
906 import org.chromium.base.annotations.JNINamespace;
907 import org.chromium.content.app.ContentMain;
908 import org.chromium.content.browser.SandboxedProcessConnection;
909 import org.chromium.content.common.ISandboxedProcessCallback;
910 import org.chromium.content.common.ISandboxedProcessService;
911 import org.chromium.content.common.WillNotRaise.AnException;
912 import org.chromium.content.common.WillRaise.AnException;
914 import static org.chromium.Bar.Zoo;
917 public static class BookmarkNode implements Parcelable {
919 public interface PasswordListObserver {
923 jni_generator
.JniParams
.SetFullyQualifiedClass(
924 'org/chromium/content/app/Foo')
925 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(import_header
)
926 self
.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in
927 jni_generator
.JniParams
._imports
)
928 self
.assertTrue('Lorg/chromium/Bar/Zoo' in
929 jni_generator
.JniParams
._imports
)
930 self
.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in
931 jni_generator
.JniParams
._inner
_classes
)
932 self
.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in
933 jni_generator
.JniParams
._inner
_classes
)
934 self
.assertEquals('Lorg/chromium/content/app/ContentMain$Inner;',
935 jni_generator
.JniParams
.JavaToJni('ContentMain.Inner'))
936 self
.assertRaises(SyntaxError,
937 jni_generator
.JniParams
.JavaToJni
,
940 def testJniParamsJavaToJni(self
):
941 self
.assertTextEquals('I', JniParams
.JavaToJni('int'))
942 self
.assertTextEquals('[B', JniParams
.JavaToJni('byte[]'))
943 self
.assertTextEquals(
944 '[Ljava/nio/ByteBuffer;', JniParams
.JavaToJni('java/nio/ByteBuffer[]'))
946 def testNativesLong(self
):
947 test_options
= TestOptions()
948 test_options
.ptr_type
= 'long'
950 private native void nativeDestroy(long nativeChromeBrowserProvider);
952 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
953 natives
= jni_generator
.ExtractNatives(test_data
, test_options
.ptr_type
)
955 NativeMethod(return_type
='void', static
=False, name
='Destroy',
956 params
=[Param(datatype
='long',
957 name
='nativeChromeBrowserProvider')],
958 java_class_name
=None,
960 p0_type
='ChromeBrowserProvider',
961 ptr_type
=test_options
.ptr_type
),
963 self
.assertListEquals(golden_natives
, natives
)
964 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
965 natives
, [], [], test_options
)
966 self
.assertGoldenTextEquals(h
.GetContent())
968 def testPureNativeMethodsOption(self
):
970 package org.chromium.example.jni_generator;
972 /** The pointer to the native Test. */
976 private static native long nativeMethod(long nativeTest, int arg1);
979 options
= TestOptions()
980 options
.pure_native_methods
= True
981 jni_from_java
= jni_generator
.JNIFromJavaSource(
982 test_data
, 'org/chromium/example/jni_generator/Test', options
)
983 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
985 def testJNIInitNativeNameOption(self
):
987 package org.chromium.example.jni_generator;
989 /** The pointer to the native Test. */
993 private static native boolean nativeInitNativeClass();
994 private static native int nativeMethod(long nativeTest, int arg1);
997 options
= TestOptions()
998 options
.jni_init_native_name
= 'nativeInitNativeClass'
999 jni_from_java
= jni_generator
.JNIFromJavaSource(
1000 test_data
, 'org/chromium/example/jni_generator/Test', options
)
1001 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1003 def testEagerCalledByNativesOption(self
):
1005 package org.chromium.example.jni_generator;
1007 /** The pointer to the native Test. */
1011 private static native boolean nativeInitNativeClass();
1012 private static native int nativeMethod(long nativeTest, int arg1);
1014 private void testMethodWithParam(int iParam);
1016 private static int testStaticMethodWithParam(int iParam);
1018 private static double testMethodWithNoParam();
1020 private static String testStaticMethodWithNoParam();
1023 options
= TestOptions()
1024 options
.jni_init_native_name
= 'nativeInitNativeClass'
1025 options
.eager_called_by_natives
= True
1026 jni_from_java
= jni_generator
.JNIFromJavaSource(
1027 test_data
, 'org/chromium/example/jni_generator/Test', options
)
1028 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1030 def runNativeExportsOption(self
, optional
):
1032 package org.chromium.example.jni_generator;
1034 /** The pointer to the native Test. */
1038 private static native boolean nativeInitNativeClass();
1039 private static native int nativeStaticMethod(long nativeTest, int arg1);
1040 private native int nativeMethod(long nativeTest, int arg1);
1042 private void testMethodWithParam(int iParam);
1044 private String testMethodWithParamAndReturn(int iParam);
1046 private static int testStaticMethodWithParam(int iParam);
1048 private static double testMethodWithNoParam();
1050 private static String testStaticMethodWithNoParam();
1052 class MyInnerClass {
1053 @NativeCall("MyInnerClass")
1054 private native int nativeInit();
1056 class MyOtherInnerClass {
1057 @NativeCall("MyOtherInnerClass")
1058 private native int nativeInit();
1062 options
= TestOptions()
1063 options
.jni_init_native_name
= 'nativeInitNativeClass'
1064 options
.native_exports
= True
1065 options
.native_exports_optional
= optional
1066 jni_from_java
= jni_generator
.JNIFromJavaSource(
1067 test_data
, 'org/chromium/example/jni_generator/SampleForTests', options
)
1068 return jni_from_java
.GetContent()
1070 def testNativeExportsOption(self
):
1071 content
= self
.runNativeExportsOption(False)
1072 self
.assertGoldenTextEquals(content
)
1074 def testNativeExportsOptionalOption(self
):
1075 content
= self
.runNativeExportsOption(True)
1076 self
.assertGoldenTextEquals(content
)
1078 def testOuterInnerRaises(self
):
1080 package org.chromium.media;
1083 static int getCaptureFormatWidth(VideoCapture.CaptureFormat format) {
1084 return format.getWidth();
1088 jni_generator
.JNIFromJavaSource(
1090 'org/chromium/media/VideoCaptureFactory',
1092 self
.assertRaises(SyntaxError, willRaise
)
1094 def testSingleJNIAdditionalImport(self
):
1096 package org.chromium.foo;
1098 @JNIAdditionalImport(Bar.class)
1102 private static void calledByNative(Bar.Callback callback) {
1105 private static native void nativeDoSomething(Bar.Callback callback);
1108 jni_from_java
= jni_generator
.JNIFromJavaSource(test_data
,
1109 'org/chromium/foo/Foo',
1111 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1113 def testMultipleJNIAdditionalImport(self
):
1115 package org.chromium.foo;
1117 @JNIAdditionalImport({Bar1.class, Bar2.class})
1121 private static void calledByNative(Bar1.Callback callback1,
1122 Bar2.Callback callback2) {
1125 private static native void nativeDoSomething(Bar1.Callback callback1,
1126 Bar2.Callback callback2);
1129 jni_from_java
= jni_generator
.JNIFromJavaSource(test_data
,
1130 'org/chromium/foo/Foo',
1132 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1135 def TouchStamp(stamp_path
):
1136 dir_name
= os
.path
.dirname(stamp_path
)
1137 if not os
.path
.isdir(dir_name
):
1140 with
open(stamp_path
, 'a'):
1141 os
.utime(stamp_path
, None)
1145 parser
= optparse
.OptionParser()
1146 parser
.add_option('--stamp', help='Path to touch on success.')
1147 options
, _
= parser
.parse_args(argv
[1:])
1149 test_result
= unittest
.main(argv
=argv
[0:1], exit
=False)
1151 if test_result
.result
.wasSuccessful() and options
.stamp
:
1152 TouchStamp(options
.stamp
)
1154 return not test_result
.result
.wasSuccessful()
1157 if __name__
== '__main__':
1158 sys
.exit(main(sys
.argv
))