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);
153 jni_generator
.JniParams
.SetFullyQualifiedClass(
154 'org/chromium/example/jni_generator/SampleForTests')
155 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
156 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
158 NativeMethod(return_type
='int', static
=False,
161 java_class_name
=None,
163 NativeMethod(return_type
='void', static
=False, name
='Destroy',
164 params
=[Param(datatype
='int',
165 name
='nativeChromeBrowserProvider')],
166 java_class_name
=None,
168 p0_type
='ChromeBrowserProvider'),
169 NativeMethod(return_type
='long', static
=False, name
='AddBookmark',
170 params
=[Param(datatype
='int',
171 name
='nativeChromeBrowserProvider'),
172 Param(datatype
='String',
174 Param(datatype
='String',
176 Param(datatype
='boolean',
178 Param(datatype
='long',
180 java_class_name
=None,
182 p0_type
='ChromeBrowserProvider'),
183 NativeMethod(return_type
='String', static
=True,
184 name
='GetDomainAndRegistry',
185 params
=[Param(datatype
='String',
187 java_class_name
=None,
189 NativeMethod(return_type
='void', static
=True,
190 name
='CreateHistoricalTabFromState',
191 params
=[Param(datatype
='byte[]',
193 Param(datatype
='int',
195 java_class_name
=None,
197 NativeMethod(return_type
='byte[]', static
=False,
198 name
='GetStateAsByteArray',
199 params
=[Param(datatype
='View', name
='view')],
200 java_class_name
=None,
202 NativeMethod(return_type
='String[]', static
=True,
203 name
='GetAutofillProfileGUIDs', params
=[],
204 java_class_name
=None,
206 NativeMethod(return_type
='void', static
=False,
207 name
='SetRecognitionResults',
208 params
=[Param(datatype
='int', name
='sessionId'),
209 Param(datatype
='String[]', name
='results')],
210 java_class_name
=None,
212 NativeMethod(return_type
='long', static
=False,
213 name
='AddBookmarkFromAPI',
214 params
=[Param(datatype
='int',
215 name
='nativeChromeBrowserProvider'),
216 Param(datatype
='String',
218 Param(datatype
='Long',
220 Param(datatype
='Boolean',
222 Param(datatype
='Long',
224 Param(datatype
='byte[]',
226 Param(datatype
='String',
228 Param(datatype
='Integer',
230 java_class_name
=None,
232 p0_type
='ChromeBrowserProvider'),
233 NativeMethod(return_type
='int', static
=False,
235 params
=[Param(datatype
='String',
237 java_class_name
=None,
239 NativeMethod(return_type
='OnFrameAvailableListener', static
=True,
240 name
='GetInnerClass',
242 java_class_name
=None,
244 NativeMethod(return_type
='Bitmap',
247 params
=[Param(datatype
='int',
248 name
='nativeChromeBrowserProvider'),
249 Param(datatype
='String[]',
251 Param(datatype
='String',
253 Param(datatype
='String[]',
254 name
='selectionArgs'),
255 Param(datatype
='String',
258 java_class_name
=None,
260 p0_type
='ChromeBrowserProvider'),
261 NativeMethod(return_type
='void', static
=False,
262 name
='GotOrientation',
263 params
=[Param(datatype
='int',
264 name
='nativeDataFetcherImplAndroid'),
265 Param(datatype
='double',
267 Param(datatype
='double',
269 Param(datatype
='double',
272 java_class_name
=None,
274 p0_type
='content::DataFetcherImplAndroid'),
276 self
.assertListEquals(golden_natives
, natives
)
277 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
278 natives
, [], [], TestOptions())
279 self
.assertGoldenTextEquals(h
.GetContent())
281 def testInnerClassNatives(self
):
284 @NativeCall("MyInnerClass")
285 private native int nativeInit();
288 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
290 NativeMethod(return_type
='int', static
=False,
291 name
='Init', params
=[],
292 java_class_name
='MyInnerClass',
295 self
.assertListEquals(golden_natives
, natives
)
296 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
297 natives
, [], [], TestOptions())
298 self
.assertGoldenTextEquals(h
.GetContent())
300 def testInnerClassNativesMultiple(self
):
303 @NativeCall("MyInnerClass")
304 private native int nativeInit();
306 class MyOtherInnerClass {
307 @NativeCall("MyOtherInnerClass")
308 private native int nativeInit();
311 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
313 NativeMethod(return_type
='int', static
=False,
314 name
='Init', params
=[],
315 java_class_name
='MyInnerClass',
317 NativeMethod(return_type
='int', static
=False,
318 name
='Init', params
=[],
319 java_class_name
='MyOtherInnerClass',
322 self
.assertListEquals(golden_natives
, natives
)
323 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
324 natives
, [], [], TestOptions())
325 self
.assertGoldenTextEquals(h
.GetContent())
327 def testInnerClassNativesBothInnerAndOuter(self
):
330 private native int nativeInit();
331 class MyOtherInnerClass {
332 @NativeCall("MyOtherInnerClass")
333 private native int nativeInit();
337 natives
= jni_generator
.ExtractNatives(test_data
, 'int')
339 NativeMethod(return_type
='int', static
=False,
340 name
='Init', params
=[],
341 java_class_name
=None,
343 NativeMethod(return_type
='int', static
=False,
344 name
='Init', params
=[],
345 java_class_name
='MyOtherInnerClass',
348 self
.assertListEquals(golden_natives
, natives
)
349 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
350 natives
, [], [], TestOptions())
351 self
.assertGoldenTextEquals(h
.GetContent())
353 def testCalledByNatives(self
):
355 import android.graphics.Bitmap;
356 import android.view.View;
357 import java.io.InputStream;
358 import java.util.List;
363 InnerClass showConfirmInfoBar(int nativeInfoBar,
364 String buttonOk, String buttonCancel, String title, Bitmap icon) {
365 InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext,
366 buttonOk, buttonCancel,
371 InnerClass showAutoLoginInfoBar(int nativeInfoBar,
372 String realm, String account, String args) {
373 AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext,
374 realm, account, args);
375 if (infobar.displayedAccountCount() == 0)
379 @CalledByNative("InfoBar")
381 @SuppressWarnings("unused")
383 private static boolean shouldShowAutoLogin(View view,
384 String realm, String account, String args) {
385 AccountManagerContainer accountManagerContainer =
386 new AccountManagerContainer((Activity)contentView.getContext(),
387 realm, account, args);
388 String[] logins = accountManagerContainer.getAccountLogins(null);
389 return logins.length != 0;
392 static InputStream openUrl(String url) {
396 private void activateHardwareAcceleration(final boolean activated,
397 final int iPid, final int iType,
398 final int iPrimaryID, final int iSecondaryID) {
403 @CalledByNativeUnchecked
404 private void uncheckedCall(int iParam);
407 public byte[] returnByteArray();
410 public boolean[] returnBooleanArray();
413 public char[] returnCharArray();
416 public short[] returnShortArray();
419 public int[] returnIntArray();
422 public long[] returnLongArray();
425 public double[] returnDoubleArray();
428 public Object[] returnObjectArray();
431 public byte[][] returnArrayOfByteArray();
434 public Bitmap.CompressFormat getCompressFormat();
437 public List<Bitmap.CompressFormat> getCompressFormatList();
439 jni_generator
.JniParams
.SetFullyQualifiedClass('org/chromium/Foo')
440 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
441 called_by_natives
= jni_generator
.ExtractCalledByNatives(test_data
)
442 golden_called_by_natives
= [
444 return_type
='InnerClass',
447 name
='showConfirmInfoBar',
448 method_id_var_name
='showConfirmInfoBar',
450 params
=[Param(datatype
='int', name
='nativeInfoBar'),
451 Param(datatype
='String', name
='buttonOk'),
452 Param(datatype
='String', name
='buttonCancel'),
453 Param(datatype
='String', name
='title'),
454 Param(datatype
='Bitmap', name
='icon')],
455 env_call
=('Object', ''),
459 return_type
='InnerClass',
462 name
='showAutoLoginInfoBar',
463 method_id_var_name
='showAutoLoginInfoBar',
465 params
=[Param(datatype
='int', name
='nativeInfoBar'),
466 Param(datatype
='String', name
='realm'),
467 Param(datatype
='String', name
='account'),
468 Param(datatype
='String', name
='args')],
469 env_call
=('Object', ''),
477 method_id_var_name
='dismiss',
478 java_class_name
='InfoBar',
480 env_call
=('Void', ''),
484 return_type
='boolean',
487 name
='shouldShowAutoLogin',
488 method_id_var_name
='shouldShowAutoLogin',
490 params
=[Param(datatype
='View', name
='view'),
491 Param(datatype
='String', name
='realm'),
492 Param(datatype
='String', name
='account'),
493 Param(datatype
='String', name
='args')],
494 env_call
=('Boolean', ''),
498 return_type
='InputStream',
502 method_id_var_name
='openUrl',
504 params
=[Param(datatype
='String', name
='url')],
505 env_call
=('Object', ''),
512 name
='activateHardwareAcceleration',
513 method_id_var_name
='activateHardwareAcceleration',
515 params
=[Param(datatype
='boolean', name
='activated'),
516 Param(datatype
='int', name
='iPid'),
517 Param(datatype
='int', name
='iType'),
518 Param(datatype
='int', name
='iPrimaryID'),
519 Param(datatype
='int', name
='iSecondaryID'),
521 env_call
=('Void', ''),
528 name
='uncheckedCall',
529 method_id_var_name
='uncheckedCall',
531 params
=[Param(datatype
='int', name
='iParam')],
532 env_call
=('Void', ''),
536 return_type
='byte[]',
539 name
='returnByteArray',
540 method_id_var_name
='returnByteArray',
543 env_call
=('Void', ''),
547 return_type
='boolean[]',
550 name
='returnBooleanArray',
551 method_id_var_name
='returnBooleanArray',
554 env_call
=('Void', ''),
558 return_type
='char[]',
561 name
='returnCharArray',
562 method_id_var_name
='returnCharArray',
565 env_call
=('Void', ''),
569 return_type
='short[]',
572 name
='returnShortArray',
573 method_id_var_name
='returnShortArray',
576 env_call
=('Void', ''),
583 name
='returnIntArray',
584 method_id_var_name
='returnIntArray',
587 env_call
=('Void', ''),
591 return_type
='long[]',
594 name
='returnLongArray',
595 method_id_var_name
='returnLongArray',
598 env_call
=('Void', ''),
602 return_type
='double[]',
605 name
='returnDoubleArray',
606 method_id_var_name
='returnDoubleArray',
609 env_call
=('Void', ''),
613 return_type
='Object[]',
616 name
='returnObjectArray',
617 method_id_var_name
='returnObjectArray',
620 env_call
=('Void', ''),
624 return_type
='byte[][]',
627 name
='returnArrayOfByteArray',
628 method_id_var_name
='returnArrayOfByteArray',
631 env_call
=('Void', ''),
635 return_type
='Bitmap.CompressFormat',
638 name
='getCompressFormat',
639 method_id_var_name
='getCompressFormat',
642 env_call
=('Void', ''),
646 return_type
='List<Bitmap.CompressFormat>',
649 name
='getCompressFormatList',
650 method_id_var_name
='getCompressFormatList',
653 env_call
=('Void', ''),
657 self
.assertListEquals(golden_called_by_natives
, called_by_natives
)
658 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
659 [], called_by_natives
, [],
661 self
.assertGoldenTextEquals(h
.GetContent())
663 def testCalledByNativeParseError(self
):
665 jni_generator
.ExtractCalledByNatives("""
667 public static int foo(); // This one is fine
672 self
.fail('Expected a ParseError')
673 except jni_generator
.ParseError
, e
:
674 self
.assertEquals(('@CalledByNative', 'scooby doo'), e
.context_lines
)
676 def testFullyQualifiedClassName(self
):
678 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
679 // Use of this source code is governed by a BSD-style license that can be
680 // found in the LICENSE file.
682 package org.chromium.content.browser;
684 import org.chromium.base.BuildInfo;
686 self
.assertEquals('org/chromium/content/browser/Foo',
687 jni_generator
.ExtractFullyQualifiedJavaClassName(
688 'org/chromium/content/browser/Foo.java', contents
))
689 self
.assertEquals('org/chromium/content/browser/Foo',
690 jni_generator
.ExtractFullyQualifiedJavaClassName(
691 'frameworks/Foo.java', contents
))
692 self
.assertRaises(SyntaxError,
693 jni_generator
.ExtractFullyQualifiedJavaClassName
,
694 'com/foo/Bar', 'no PACKAGE line')
696 def testMethodNameMangling(self
):
697 self
.assertEquals('closeV',
698 jni_generator
.GetMangledMethodName('close', [], 'void'))
699 self
.assertEquals('readI_AB_I_I',
700 jni_generator
.GetMangledMethodName('read',
708 self
.assertEquals('openJIIS_JLS',
709 jni_generator
.GetMangledMethodName('open',
711 datatype
='java/lang/String'),],
712 'java/io/InputStream'))
714 def testFromJavaPGenerics(self
):
716 public abstract class java.util.HashSet<T> extends java.util.AbstractSet<E>
717 implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
722 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
724 self
.assertEquals(1, len(jni_from_javap
.called_by_natives
))
725 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
727 def testSnippnetJavap6_7_8(self
):
729 public class java.util.HashSet {
730 public boolean add(java.lang.Object);
731 Signature: (Ljava/lang/Object;)Z
736 public class java.util.HashSet {
737 public boolean add(E);
738 Signature: (Ljava/lang/Object;)Z
743 public class java.util.HashSet {
744 public boolean add(E);
745 descriptor: (Ljava/lang/Object;)Z
749 jni_from_javap6
= jni_generator
.JNIFromJavaP(content_javap6
.split('\n'),
751 jni_from_javap7
= jni_generator
.JNIFromJavaP(content_javap7
.split('\n'),
753 jni_from_javap8
= jni_generator
.JNIFromJavaP(content_javap8
.split('\n'),
755 self
.assertTrue(jni_from_javap6
.GetContent())
756 self
.assertTrue(jni_from_javap7
.GetContent())
757 self
.assertTrue(jni_from_javap8
.GetContent())
758 # Ensure the javap7 is correctly parsed and uses the Signature field rather
759 # than the "E" parameter.
760 self
.assertTextEquals(jni_from_javap6
.GetContent(),
761 jni_from_javap7
.GetContent())
762 # Ensure the javap8 is correctly parsed and uses the descriptor field.
763 self
.assertTextEquals(jni_from_javap7
.GetContent(),
764 jni_from_javap8
.GetContent())
766 def testFromJavaP(self
):
767 contents
= self
._ReadGoldenFile
(os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
768 'testInputStream.javap'))
769 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
771 self
.assertEquals(10, len(jni_from_javap
.called_by_natives
))
772 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
774 def testConstantsFromJavaP(self
):
775 for f
in ['testMotionEvent.javap', 'testMotionEvent.javap7']:
776 contents
= self
._ReadGoldenFile
(os
.path
.join(os
.path
.dirname(sys
.argv
[0]),
778 jni_from_javap
= jni_generator
.JNIFromJavaP(contents
.split('\n'),
780 self
.assertEquals(86, len(jni_from_javap
.called_by_natives
))
781 self
.assertGoldenTextEquals(jni_from_javap
.GetContent())
783 def testREForNatives(self
):
784 # We should not match "native SyncSetupFlow" inside the comment.
787 * Invoked when the setup process is complete so we can disconnect from the
788 * native-side SyncSetupFlowHandler.
790 public void destroy() {
791 Log.v(TAG, "Destroying native SyncSetupFlow");
792 if (mNativeSyncSetupFlow != 0) {
793 nativeSyncSetupEnded(mNativeSyncSetupFlow);
794 mNativeSyncSetupFlow = 0;
797 private native void nativeSyncSetupEnded(
798 int nativeAndroidSyncSetupFlowHandler);
800 jni_from_java
= jni_generator
.JNIFromJavaSource(
801 test_data
, 'foo/bar', TestOptions())
803 def testRaisesOnNonJNIMethod(self
):
806 private int Foo(int p0) {
810 self
.assertRaises(SyntaxError,
811 jni_generator
.JNIFromJavaSource
,
812 test_data
, 'foo/bar', TestOptions())
814 def testJniSelfDocumentingExample(self
):
815 script_dir
= os
.path
.dirname(sys
.argv
[0])
816 content
= file(os
.path
.join(script_dir
,
817 'java/src/org/chromium/example/jni_generator/SampleForTests.java')
819 golden_file
= os
.path
.join(script_dir
, 'golden_sample_for_tests_jni.h')
820 golden_content
= file(golden_file
).read()
821 jni_from_java
= jni_generator
.JNIFromJavaSource(
822 content
, 'org/chromium/example/jni_generator/SampleForTests',
824 generated_text
= jni_from_java
.GetContent()
825 if not self
.compareText(golden_content
, generated_text
):
826 if os
.environ
.get(REBASELINE_ENV
):
827 with
file(golden_file
, 'w') as f
:
828 f
.write(generated_text
)
830 self
.fail('testJniSelfDocumentingExample')
832 def testNoWrappingPreprocessorLines(self
):
834 package com.google.lookhowextremelylongiam.snarf.icankeepthisupallday;
836 class ReallyLongClassNamesAreAllTheRage {
837 private static native int nativeTest();
840 jni_from_java
= jni_generator
.JNIFromJavaSource(
841 test_data
, ('com/google/lookhowextremelylongiam/snarf/'
842 'icankeepthisupallday/ReallyLongClassNamesAreAllTheRage'),
844 jni_lines
= jni_from_java
.GetContent().split('\n')
845 line
= filter(lambda line
: line
.lstrip().startswith('#ifndef'),
847 self
.assertTrue(len(line
) > 80,
848 ('Expected #ifndef line to be > 80 chars: ', line
))
850 def testJarJarRemapping(self
):
852 package org.chromium.example.jni_generator;
854 import org.chromium.example2.Test;
856 import org.chromium.example3.PrefixFoo;
857 import org.chromium.example3.Prefix;
858 import org.chromium.example3.Bar$Inner;
861 private static native void nativeTest(Test t);
862 private static native void nativeTest2(PrefixFoo t);
863 private static native void nativeTest3(Prefix t);
864 private static native void nativeTest4(Bar$Inner t);
867 jni_generator
.JniParams
.SetJarJarMappings(
868 """rule org.chromium.example.** com.test.@1
869 rule org.chromium.example2.** org.test2.@1
870 rule org.chromium.example3.Prefix org.test3.Test
871 rule org.chromium.example3.Bar$** org.test3.TestBar$@1""")
872 jni_from_java
= jni_generator
.JNIFromJavaSource(
873 test_data
, 'org/chromium/example/jni_generator/Example', TestOptions())
874 jni_generator
.JniParams
.SetJarJarMappings('')
875 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
877 def testImports(self
):
879 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
880 // Use of this source code is governed by a BSD-style license that can be
881 // found in the LICENSE file.
883 package org.chromium.content.app;
885 import android.app.Service;
886 import android.content.Context;
887 import android.content.Intent;
888 import android.graphics.SurfaceTexture;
889 import android.os.Bundle;
890 import android.os.IBinder;
891 import android.os.ParcelFileDescriptor;
892 import android.os.Process;
893 import android.os.RemoteException;
894 import android.util.Log;
895 import android.view.Surface;
897 import java.util.ArrayList;
899 import org.chromium.base.CalledByNative;
900 import org.chromium.base.JNINamespace;
901 import org.chromium.content.app.ContentMain;
902 import org.chromium.content.browser.SandboxedProcessConnection;
903 import org.chromium.content.common.ISandboxedProcessCallback;
904 import org.chromium.content.common.ISandboxedProcessService;
905 import org.chromium.content.common.WillNotRaise.AnException;
906 import org.chromium.content.common.WillRaise.AnException;
908 import static org.chromium.Bar.Zoo;
911 public static class BookmarkNode implements Parcelable {
913 public interface PasswordListObserver {
917 jni_generator
.JniParams
.SetFullyQualifiedClass(
918 'org/chromium/content/app/Foo')
919 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(import_header
)
920 self
.assertTrue('Lorg/chromium/content/common/ISandboxedProcessService' in
921 jni_generator
.JniParams
._imports
)
922 self
.assertTrue('Lorg/chromium/Bar/Zoo' in
923 jni_generator
.JniParams
._imports
)
924 self
.assertTrue('Lorg/chromium/content/app/Foo$BookmarkNode' in
925 jni_generator
.JniParams
._inner
_classes
)
926 self
.assertTrue('Lorg/chromium/content/app/Foo$PasswordListObserver' in
927 jni_generator
.JniParams
._inner
_classes
)
928 self
.assertEquals('Lorg/chromium/content/app/ContentMain$Inner;',
929 jni_generator
.JniParams
.JavaToJni('ContentMain.Inner'))
930 self
.assertRaises(SyntaxError,
931 jni_generator
.JniParams
.JavaToJni
,
934 def testJniParamsJavaToJni(self
):
935 self
.assertTextEquals('I', JniParams
.JavaToJni('int'))
936 self
.assertTextEquals('[B', JniParams
.JavaToJni('byte[]'))
937 self
.assertTextEquals(
938 '[Ljava/nio/ByteBuffer;', JniParams
.JavaToJni('java/nio/ByteBuffer[]'))
940 def testNativesLong(self
):
941 test_options
= TestOptions()
942 test_options
.ptr_type
= 'long'
944 private native void nativeDestroy(long nativeChromeBrowserProvider);
946 jni_generator
.JniParams
.ExtractImportsAndInnerClasses(test_data
)
947 natives
= jni_generator
.ExtractNatives(test_data
, test_options
.ptr_type
)
949 NativeMethod(return_type
='void', static
=False, name
='Destroy',
950 params
=[Param(datatype
='long',
951 name
='nativeChromeBrowserProvider')],
952 java_class_name
=None,
954 p0_type
='ChromeBrowserProvider',
955 ptr_type
=test_options
.ptr_type
),
957 self
.assertListEquals(golden_natives
, natives
)
958 h
= jni_generator
.InlHeaderFileGenerator('', 'org/chromium/TestJni',
959 natives
, [], [], test_options
)
960 self
.assertGoldenTextEquals(h
.GetContent())
962 def testPureNativeMethodsOption(self
):
964 package org.chromium.example.jni_generator;
966 /** The pointer to the native Test. */
970 private static native long nativeMethod(long nativeTest, int arg1);
973 options
= TestOptions()
974 options
.pure_native_methods
= True
975 jni_from_java
= jni_generator
.JNIFromJavaSource(
976 test_data
, 'org/chromium/example/jni_generator/Test', options
)
977 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
979 def testJNIInitNativeNameOption(self
):
981 package org.chromium.example.jni_generator;
983 /** The pointer to the native Test. */
987 private static native boolean nativeInitNativeClass();
988 private static native int nativeMethod(long nativeTest, int arg1);
991 options
= TestOptions()
992 options
.jni_init_native_name
= 'nativeInitNativeClass'
993 jni_from_java
= jni_generator
.JNIFromJavaSource(
994 test_data
, 'org/chromium/example/jni_generator/Test', options
)
995 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
997 def testEagerCalledByNativesOption(self
):
999 package org.chromium.example.jni_generator;
1001 /** The pointer to the native Test. */
1005 private static native boolean nativeInitNativeClass();
1006 private static native int nativeMethod(long nativeTest, int arg1);
1008 private void testMethodWithParam(int iParam);
1010 private static int testStaticMethodWithParam(int iParam);
1012 private static double testMethodWithNoParam();
1014 private static String testStaticMethodWithNoParam();
1017 options
= TestOptions()
1018 options
.jni_init_native_name
= 'nativeInitNativeClass'
1019 options
.eager_called_by_natives
= True
1020 jni_from_java
= jni_generator
.JNIFromJavaSource(
1021 test_data
, 'org/chromium/example/jni_generator/Test', options
)
1022 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1024 def runNativeExportsOption(self
, optional
):
1026 package org.chromium.example.jni_generator;
1028 /** The pointer to the native Test. */
1032 private static native boolean nativeInitNativeClass();
1033 private static native int nativeStaticMethod(long nativeTest, int arg1);
1034 private native int nativeMethod(long nativeTest, int arg1);
1036 private void testMethodWithParam(int iParam);
1038 private String testMethodWithParamAndReturn(int iParam);
1040 private static int testStaticMethodWithParam(int iParam);
1042 private static double testMethodWithNoParam();
1044 private static String testStaticMethodWithNoParam();
1046 class MyInnerClass {
1047 @NativeCall("MyInnerClass")
1048 private native int nativeInit();
1050 class MyOtherInnerClass {
1051 @NativeCall("MyOtherInnerClass")
1052 private native int nativeInit();
1056 options
= TestOptions()
1057 options
.jni_init_native_name
= 'nativeInitNativeClass'
1058 options
.native_exports
= True
1059 options
.native_exports_optional
= optional
1060 jni_from_java
= jni_generator
.JNIFromJavaSource(
1061 test_data
, 'org/chromium/example/jni_generator/SampleForTests', options
)
1062 return jni_from_java
.GetContent()
1064 def testNativeExportsOption(self
):
1065 content
= self
.runNativeExportsOption(False)
1066 self
.assertGoldenTextEquals(content
)
1068 def testNativeExportsOptionalOption(self
):
1069 content
= self
.runNativeExportsOption(True)
1070 self
.assertGoldenTextEquals(content
)
1072 def testOuterInnerRaises(self
):
1074 package org.chromium.media;
1077 static int getCaptureFormatWidth(VideoCapture.CaptureFormat format) {
1078 return format.getWidth();
1082 jni_generator
.JNIFromJavaSource(
1084 'org/chromium/media/VideoCaptureFactory',
1086 self
.assertRaises(SyntaxError, willRaise
)
1088 def testSingleJNIAdditionalImport(self
):
1090 package org.chromium.foo;
1092 @JNIAdditionalImport(Bar.class)
1096 private static void calledByNative(Bar.Callback callback) {
1099 private static native void nativeDoSomething(Bar.Callback callback);
1102 jni_from_java
= jni_generator
.JNIFromJavaSource(test_data
,
1103 'org/chromium/foo/Foo',
1105 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1107 def testMultipleJNIAdditionalImport(self
):
1109 package org.chromium.foo;
1111 @JNIAdditionalImport({Bar1.class, Bar2.class})
1115 private static void calledByNative(Bar1.Callback callback1,
1116 Bar2.Callback callback2) {
1119 private static native void nativeDoSomething(Bar1.Callback callback1,
1120 Bar2.Callback callback2);
1123 jni_from_java
= jni_generator
.JNIFromJavaSource(test_data
,
1124 'org/chromium/foo/Foo',
1126 self
.assertGoldenTextEquals(jni_from_java
.GetContent())
1129 def TouchStamp(stamp_path
):
1130 dir_name
= os
.path
.dirname(stamp_path
)
1131 if not os
.path
.isdir(dir_name
):
1134 with
open(stamp_path
, 'a'):
1135 os
.utime(stamp_path
, None)
1139 parser
= optparse
.OptionParser()
1140 parser
.add_option('--stamp', help='Path to touch on success.')
1141 options
, _
= parser
.parse_args(argv
[1:])
1143 test_result
= unittest
.main(argv
=argv
[0:1], exit
=False)
1145 if test_result
.result
.wasSuccessful() and options
.stamp
:
1146 TouchStamp(options
.stamp
)
1148 return not test_result
.result
.wasSuccessful()
1151 if __name__
== '__main__':
1152 sys
.exit(main(sys
.argv
))