OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/python |
| 2 # |
| 3 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 4 # Use of this source code is governed by a BSD-style license that can be |
| 5 # found in the LICENSE file. |
| 6 |
| 7 """Tests for jni_generator.py. |
| 8 |
| 9 This test suite contains various tests for the JNI generator. |
| 10 It exercises the low-level parser all the way up to the |
| 11 code generator and ensures the output matches a golden |
| 12 file. |
| 13 """ |
| 14 |
| 15 import difflib |
| 16 import os |
| 17 import sys |
| 18 import unittest |
| 19 import jni_generator |
| 20 from jni_generator import CalledByNative, NativeMethod, Param |
| 21 |
| 22 |
| 23 class TestGenerator(unittest.TestCase): |
| 24 def assertObjEquals(self, first, second): |
| 25 dict_first = first.__dict__ |
| 26 dict_second = second.__dict__ |
| 27 self.assertEquals(dict_first.keys(), dict_second.keys()) |
| 28 for key, value in dict_first.iteritems(): |
| 29 if (type(value) is list and len(value) and |
| 30 isinstance(type(value[0]), object)): |
| 31 self.assertListEquals(value, second.__getattribute__(key)) |
| 32 else: |
| 33 self.assertEquals(value, second.__getattribute__(key)) |
| 34 |
| 35 def assertListEquals(self, first, second): |
| 36 self.assertEquals(len(first), len(second)) |
| 37 for i in xrange(len(first)): |
| 38 if isinstance(first[i], object): |
| 39 self.assertObjEquals(first[i], second[i]) |
| 40 else: |
| 41 self.assertEquals(first[i], second[i]) |
| 42 |
| 43 def assertTextEquals(self, golden_text, generated_text): |
| 44 stripped_golden = [l.strip() for l in golden_text.split('\n')] |
| 45 stripped_generated = [l.strip() for l in generated_text.split('\n')] |
| 46 if stripped_golden != stripped_generated: |
| 47 print self.id() |
| 48 for line in difflib.context_diff(stripped_golden, stripped_generated): |
| 49 print line |
| 50 self.fail('Golden text mismatch') |
| 51 |
| 52 def testNatives(self): |
| 53 test_data = """" |
| 54 private native int nativeInit(); |
| 55 private native void nativeDestroy(int nativeChromeBrowserProvider); |
| 56 private native long nativeAddBookmark( |
| 57 int nativeChromeBrowserProvider, |
| 58 String url, String title, boolean isFolder, long parentId); |
| 59 private static native String nativeGetDomainAndRegistry(String url); |
| 60 private static native void nativeCreateHistoricalTabFromState( |
| 61 byte[] state, int tab_index); |
| 62 private native byte[] nativeGetStateAsByteArray(ChromeView view); |
| 63 private static native String[] nativeGetAutofillProfileGUIDs(); |
| 64 private native void nativeSetRecognitionResults( |
| 65 int sessionId, String[] results); |
| 66 private native long nativeAddBookmarkFromAPI( |
| 67 int nativeChromeBrowserProvider, |
| 68 String url, Long created, Boolean isBookmark, |
| 69 Long date, byte[] favicon, String title, Integer visits); |
| 70 native int nativeFindAll(String find); |
| 71 private static native BookmarkNode nativeGetDefaultBookmarkFolder(); |
| 72 private native SQLiteCursor nativeQueryBookmarkFromAPI( |
| 73 int nativeChromeBrowserProvider, |
| 74 String[] projection, String selection, |
| 75 String[] selectionArgs, String sortOrder); |
| 76 private native void nativeGotOrientation( |
| 77 int nativePtr /* device_orientation::DeviceOrientationAndroid */, |
| 78 double alpha, double beta, double gamma); |
| 79 """ |
| 80 natives = jni_generator.ExtractNatives(test_data) |
| 81 golden_natives = [ |
| 82 NativeMethod(return_type='int', static=False, |
| 83 name='Init', |
| 84 params=[], |
| 85 java_class_name='', |
| 86 type='function'), |
| 87 NativeMethod(return_type='void', static=False, name='Destroy', |
| 88 params=[Param(datatype='int', |
| 89 name='nativeChromeBrowserProvider')], |
| 90 java_class_name='', |
| 91 type='method', |
| 92 p0_type='ChromeBrowserProvider'), |
| 93 NativeMethod(return_type='long', static=False, name='AddBookmark', |
| 94 params=[Param(datatype='int', |
| 95 name='nativeChromeBrowserProvider'), |
| 96 Param(datatype='String', |
| 97 name='url'), |
| 98 Param(datatype='String', |
| 99 name='title'), |
| 100 Param(datatype='boolean', |
| 101 name='isFolder'), |
| 102 Param(datatype='long', |
| 103 name='parentId')], |
| 104 java_class_name='', |
| 105 type='method', |
| 106 p0_type='ChromeBrowserProvider'), |
| 107 NativeMethod(return_type='String', static=True, |
| 108 name='GetDomainAndRegistry', |
| 109 params=[Param(datatype='String', |
| 110 name='url')], |
| 111 java_class_name='', |
| 112 type='function'), |
| 113 NativeMethod(return_type='void', static=True, |
| 114 name='CreateHistoricalTabFromState', |
| 115 params=[Param(datatype='byte[]', |
| 116 name='state'), |
| 117 Param(datatype='int', |
| 118 name='tab_index')], |
| 119 java_class_name='', |
| 120 type='function'), |
| 121 NativeMethod(return_type='byte[]', static=False, |
| 122 name='GetStateAsByteArray', |
| 123 params=[Param(datatype='ChromeView', name='view')], |
| 124 java_class_name='', |
| 125 type='function'), |
| 126 NativeMethod(return_type='String[]', static=True, |
| 127 name='GetAutofillProfileGUIDs', params=[], |
| 128 java_class_name='', |
| 129 type='function'), |
| 130 NativeMethod(return_type='void', static=False, |
| 131 name='SetRecognitionResults', |
| 132 params=[Param(datatype='int', name='sessionId'), |
| 133 Param(datatype='String[]', name='results')], |
| 134 java_class_name='', |
| 135 type='function'), |
| 136 NativeMethod(return_type='long', static=False, |
| 137 name='AddBookmarkFromAPI', |
| 138 params=[Param(datatype='int', |
| 139 name='nativeChromeBrowserProvider'), |
| 140 Param(datatype='String', |
| 141 name='url'), |
| 142 Param(datatype='Long', |
| 143 name='created'), |
| 144 Param(datatype='Boolean', |
| 145 name='isBookmark'), |
| 146 Param(datatype='Long', |
| 147 name='date'), |
| 148 Param(datatype='byte[]', |
| 149 name='favicon'), |
| 150 Param(datatype='String', |
| 151 name='title'), |
| 152 Param(datatype='Integer', |
| 153 name='visits')], |
| 154 java_class_name='', |
| 155 type='method', |
| 156 p0_type='ChromeBrowserProvider'), |
| 157 NativeMethod(return_type='int', static=False, |
| 158 name='FindAll', |
| 159 params=[Param(datatype='String', |
| 160 name='find')], |
| 161 java_class_name='', |
| 162 type='function'), |
| 163 NativeMethod(return_type='BookmarkNode', static=True, |
| 164 name='GetDefaultBookmarkFolder', |
| 165 params=[], |
| 166 java_class_name='', |
| 167 type='function'), |
| 168 NativeMethod(return_type='SQLiteCursor', |
| 169 static=False, |
| 170 name='QueryBookmarkFromAPI', |
| 171 params=[Param(datatype='int', |
| 172 name='nativeChromeBrowserProvider'), |
| 173 Param(datatype='String[]', |
| 174 name='projection'), |
| 175 Param(datatype='String', |
| 176 name='selection'), |
| 177 Param(datatype='String[]', |
| 178 name='selectionArgs'), |
| 179 Param(datatype='String', |
| 180 name='sortOrder'), |
| 181 ], |
| 182 java_class_name='', |
| 183 type='method', |
| 184 p0_type='ChromeBrowserProvider'), |
| 185 NativeMethod(return_type='void', static=False, |
| 186 name='GotOrientation', |
| 187 params=[Param(datatype='int', |
| 188 cpp_class_name= |
| 189 'device_orientation::DeviceOrientationAndroid', |
| 190 name='nativePtr'), |
| 191 Param(datatype='double', |
| 192 name='alpha'), |
| 193 Param(datatype='double', |
| 194 name='beta'), |
| 195 Param(datatype='double', |
| 196 name='gamma'), |
| 197 ], |
| 198 java_class_name='', |
| 199 type='method', |
| 200 p0_type='device_orientation::DeviceOrientationAndroid'), |
| 201 ] |
| 202 self.assertListEquals(golden_natives, natives) |
| 203 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
| 204 natives, []) |
| 205 golden_content = """\ |
| 206 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 207 // Use of this source code is governed by a BSD-style license that can be |
| 208 // found in the LICENSE file. |
| 209 |
| 210 |
| 211 // This file is autogenerated by |
| 212 // base/android/jni_generator/jni_generator_tests.py |
| 213 // For |
| 214 // org/chromium/TestJni |
| 215 |
| 216 #ifndef org_chromium_TestJni_JNI |
| 217 #define org_chromium_TestJni_JNI |
| 218 |
| 219 #include <jni.h> |
| 220 |
| 221 #include "base/android/jni_android.h" |
| 222 #include "base/android/scoped_java_ref.h" |
| 223 #include "base/basictypes.h" |
| 224 #include "base/logging.h" |
| 225 |
| 226 using base::android::ScopedJavaLocalRef; |
| 227 |
| 228 // Step 1: forward declarations. |
| 229 namespace { |
| 230 const char* const kTestJniClassPath = "org/chromium/TestJni"; |
| 231 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 232 base::android::ScopedJavaGlobalRef<jclass>& |
| 233 g_TestJni_clazz = |
| 234 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 235 } // namespace |
| 236 |
| 237 static jint Init(JNIEnv* env, jobject obj); |
| 238 |
| 239 |
| 240 static jstring GetDomainAndRegistry(JNIEnv* env, jclass clazz, |
| 241 jstring url); |
| 242 |
| 243 |
| 244 static void CreateHistoricalTabFromState(JNIEnv* env, jclass clazz, |
| 245 jbyteArray state, |
| 246 jint tab_index); |
| 247 |
| 248 |
| 249 static jbyteArray GetStateAsByteArray(JNIEnv* env, jobject obj, |
| 250 jobject view); |
| 251 |
| 252 |
| 253 static jobjectArray GetAutofillProfileGUIDs(JNIEnv* env, jclass clazz); |
| 254 |
| 255 |
| 256 static void SetRecognitionResults(JNIEnv* env, jobject obj, |
| 257 jint sessionId, |
| 258 jobjectArray results); |
| 259 |
| 260 |
| 261 static jint FindAll(JNIEnv* env, jobject obj, |
| 262 jstring find); |
| 263 |
| 264 |
| 265 static jobject GetDefaultBookmarkFolder(JNIEnv* env, jclass clazz); |
| 266 |
| 267 |
| 268 // Step 2: method stubs. |
| 269 static void Destroy(JNIEnv* env, jobject obj, |
| 270 jint nativeChromeBrowserProvider) { |
| 271 DCHECK(nativeChromeBrowserProvider) << "Destroy"; |
| 272 ChromeBrowserProvider* native = |
| 273 reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
| 274 return native->Destroy(env, obj); |
| 275 } |
| 276 |
| 277 static jlong AddBookmark(JNIEnv* env, jobject obj, |
| 278 jint nativeChromeBrowserProvider, |
| 279 jstring url, |
| 280 jstring title, |
| 281 jboolean isFolder, |
| 282 jlong parentId) { |
| 283 DCHECK(nativeChromeBrowserProvider) << "AddBookmark"; |
| 284 ChromeBrowserProvider* native = |
| 285 reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
| 286 return native->AddBookmark(env, obj, url, title, isFolder, parentId); |
| 287 } |
| 288 |
| 289 static jlong AddBookmarkFromAPI(JNIEnv* env, jobject obj, |
| 290 jint nativeChromeBrowserProvider, |
| 291 jstring url, |
| 292 jobject created, |
| 293 jobject isBookmark, |
| 294 jobject date, |
| 295 jbyteArray favicon, |
| 296 jstring title, |
| 297 jobject visits) { |
| 298 DCHECK(nativeChromeBrowserProvider) << "AddBookmarkFromAPI"; |
| 299 ChromeBrowserProvider* native = |
| 300 reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
| 301 return native->AddBookmarkFromAPI(env, obj, url, created, isBookmark, date, |
| 302 favicon, title, visits); |
| 303 } |
| 304 |
| 305 static jobject QueryBookmarkFromAPI(JNIEnv* env, jobject obj, |
| 306 jint nativeChromeBrowserProvider, |
| 307 jobjectArray projection, |
| 308 jstring selection, |
| 309 jobjectArray selectionArgs, |
| 310 jstring sortOrder) { |
| 311 DCHECK(nativeChromeBrowserProvider) << "QueryBookmarkFromAPI"; |
| 312 ChromeBrowserProvider* native = |
| 313 reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
| 314 return native->QueryBookmarkFromAPI(env, obj, projection, selection, |
| 315 selectionArgs, sortOrder).Release(); |
| 316 } |
| 317 |
| 318 static void GotOrientation(JNIEnv* env, jobject obj, |
| 319 jint nativePtr, |
| 320 jdouble alpha, |
| 321 jdouble beta, |
| 322 jdouble gamma) { |
| 323 DCHECK(nativePtr) << "GotOrientation"; |
| 324 device_orientation::DeviceOrientationAndroid* native = |
| 325 reinterpret_cast<device_orientation::DeviceOrientationAndroid*>(nativePtr); |
| 326 return native->GotOrientation(env, obj, alpha, beta, gamma); |
| 327 } |
| 328 |
| 329 |
| 330 // Step 3: GetMethodIDs and RegisterNatives. |
| 331 |
| 332 |
| 333 static void GetMethodIDsImpl(JNIEnv* env) { |
| 334 g_TestJni_clazz.Reset( |
| 335 base::android::GetClass(env, kTestJniClassPath)); |
| 336 } |
| 337 |
| 338 static bool RegisterNativesImpl(JNIEnv* env) { |
| 339 GetMethodIDsImpl(env); |
| 340 |
| 341 static const JNINativeMethod kMethodsTestJni[] = { |
| 342 { "nativeInit", |
| 343 "(" |
| 344 ")" |
| 345 "I", reinterpret_cast<void*>(Init) }, |
| 346 { "nativeDestroy", |
| 347 "(" |
| 348 "I" |
| 349 ")" |
| 350 "V", reinterpret_cast<void*>(Destroy) }, |
| 351 { "nativeAddBookmark", |
| 352 "(" |
| 353 "I" |
| 354 "Ljava/lang/String;" |
| 355 "Ljava/lang/String;" |
| 356 "Z" |
| 357 "J" |
| 358 ")" |
| 359 "J", reinterpret_cast<void*>(AddBookmark) }, |
| 360 { "nativeGetDomainAndRegistry", |
| 361 "(" |
| 362 "Ljava/lang/String;" |
| 363 ")" |
| 364 "Ljava/lang/String;", reinterpret_cast<void*>(GetDomainAndRegistry) }, |
| 365 { "nativeCreateHistoricalTabFromState", |
| 366 "(" |
| 367 "[B" |
| 368 "I" |
| 369 ")" |
| 370 "V", reinterpret_cast<void*>(CreateHistoricalTabFromState) }, |
| 371 { "nativeGetStateAsByteArray", |
| 372 "(" |
| 373 "Lorg/chromium/chromeview/ChromeView;" |
| 374 ")" |
| 375 "[B", reinterpret_cast<void*>(GetStateAsByteArray) }, |
| 376 { "nativeGetAutofillProfileGUIDs", |
| 377 "(" |
| 378 ")" |
| 379 "[Ljava/lang/String;", reinterpret_cast<void*>(GetAutofillProfileGUIDs) }, |
| 380 { "nativeSetRecognitionResults", |
| 381 "(" |
| 382 "I" |
| 383 "[Ljava/lang/String;" |
| 384 ")" |
| 385 "V", reinterpret_cast<void*>(SetRecognitionResults) }, |
| 386 { "nativeAddBookmarkFromAPI", |
| 387 "(" |
| 388 "I" |
| 389 "Ljava/lang/String;" |
| 390 "Ljava/lang/Long;" |
| 391 "Ljava/lang/Boolean;" |
| 392 "Ljava/lang/Long;" |
| 393 "[B" |
| 394 "Ljava/lang/String;" |
| 395 "Ljava/lang/Integer;" |
| 396 ")" |
| 397 "J", reinterpret_cast<void*>(AddBookmarkFromAPI) }, |
| 398 { "nativeFindAll", |
| 399 "(" |
| 400 "Ljava/lang/String;" |
| 401 ")" |
| 402 "I", reinterpret_cast<void*>(FindAll) }, |
| 403 { "nativeGetDefaultBookmarkFolder", |
| 404 "(" |
| 405 ")" |
| 406 "Lcom/android/chrome/ChromeBrowserProvider$BookmarkNode;", |
| 407 reinterpret_cast<void*>(GetDefaultBookmarkFolder) }, |
| 408 { "nativeQueryBookmarkFromAPI", |
| 409 "(" |
| 410 "I" |
| 411 "[Ljava/lang/String;" |
| 412 "Ljava/lang/String;" |
| 413 "[Ljava/lang/String;" |
| 414 "Ljava/lang/String;" |
| 415 ")" |
| 416 "Lcom/android/chrome/database/SQLiteCursor;", |
| 417 reinterpret_cast<void*>(QueryBookmarkFromAPI) }, |
| 418 { "nativeGotOrientation", |
| 419 "(" |
| 420 "I" |
| 421 "D" |
| 422 "D" |
| 423 "D" |
| 424 ")" |
| 425 "V", reinterpret_cast<void*>(GotOrientation) }, |
| 426 }; |
| 427 const int kMethodsTestJniSize = arraysize(kMethodsTestJni); |
| 428 |
| 429 if (env->RegisterNatives(g_TestJni_clazz.obj(), |
| 430 kMethodsTestJni, |
| 431 kMethodsTestJniSize) < 0) { |
| 432 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 433 return false; |
| 434 } |
| 435 |
| 436 return true; |
| 437 } |
| 438 |
| 439 #endif // org_chromium_TestJni_JNI |
| 440 """ |
| 441 self.assertTextEquals(golden_content, h.GetContent()) |
| 442 |
| 443 def testInnerClassNatives(self): |
| 444 test_data = """ |
| 445 class MyInnerClass { |
| 446 @NativeCall("MyInnerClass") |
| 447 private native int nativeInit(); |
| 448 } |
| 449 """ |
| 450 natives = jni_generator.ExtractNatives(test_data) |
| 451 golden_natives = [ |
| 452 NativeMethod(return_type='int', static=False, |
| 453 name='Init', params=[], |
| 454 java_class_name='MyInnerClass', |
| 455 type='function') |
| 456 ] |
| 457 self.assertListEquals(golden_natives, natives) |
| 458 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
| 459 natives, []) |
| 460 golden_content = """\ |
| 461 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 462 // Use of this source code is governed by a BSD-style license that can be |
| 463 // found in the LICENSE file. |
| 464 |
| 465 |
| 466 // This file is autogenerated by |
| 467 // base/android/jni_generator/jni_generator_tests.py |
| 468 // For |
| 469 // org/chromium/TestJni |
| 470 |
| 471 #ifndef org_chromium_TestJni_JNI |
| 472 #define org_chromium_TestJni_JNI |
| 473 |
| 474 #include <jni.h> |
| 475 |
| 476 #include "base/android/jni_android.h" |
| 477 #include "base/android/scoped_java_ref.h" |
| 478 #include "base/basictypes.h" |
| 479 #include "base/logging.h" |
| 480 |
| 481 using base::android::ScopedJavaLocalRef; |
| 482 |
| 483 // Step 1: forward declarations. |
| 484 namespace { |
| 485 const char* const kTestJniClassPath = "org/chromium/TestJni"; |
| 486 const char* const kMyInnerClassClassPath = "org/chromium/TestJni$MyInnerClass"; |
| 487 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 488 base::android::ScopedJavaGlobalRef<jclass>& |
| 489 g_TestJni_clazz = |
| 490 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 491 } // namespace |
| 492 |
| 493 static jint Init(JNIEnv* env, jobject obj); |
| 494 |
| 495 |
| 496 // Step 2: method stubs. |
| 497 |
| 498 |
| 499 // Step 3: GetMethodIDs and RegisterNatives. |
| 500 |
| 501 |
| 502 static void GetMethodIDsImpl(JNIEnv* env) { |
| 503 g_TestJni_clazz.Reset( |
| 504 base::android::GetClass(env, kTestJniClassPath)); |
| 505 } |
| 506 |
| 507 static bool RegisterNativesImpl(JNIEnv* env) { |
| 508 GetMethodIDsImpl(env); |
| 509 |
| 510 static const JNINativeMethod kMethodsMyInnerClass[] = { |
| 511 { "nativeInit", |
| 512 "(" |
| 513 ")" |
| 514 "I", reinterpret_cast<void*>(Init) }, |
| 515 }; |
| 516 const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); |
| 517 |
| 518 if (env->RegisterNatives(g_MyInnerClass_clazz.obj(), |
| 519 kMethodsMyInnerClass, |
| 520 kMethodsMyInnerClassSize) < 0) { |
| 521 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 522 return false; |
| 523 } |
| 524 |
| 525 return true; |
| 526 } |
| 527 |
| 528 #endif // org_chromium_TestJni_JNI |
| 529 """ |
| 530 self.assertTextEquals(golden_content, h.GetContent()) |
| 531 |
| 532 def testInnerClassNativesMultiple(self): |
| 533 test_data = """ |
| 534 class MyInnerClass { |
| 535 @NativeCall("MyInnerClass") |
| 536 private native int nativeInit(); |
| 537 } |
| 538 class MyOtherInnerClass { |
| 539 @NativeCall("MyOtherInnerClass") |
| 540 private native int nativeInit(); |
| 541 } |
| 542 """ |
| 543 natives = jni_generator.ExtractNatives(test_data) |
| 544 golden_natives = [ |
| 545 NativeMethod(return_type='int', static=False, |
| 546 name='Init', params=[], |
| 547 java_class_name='MyInnerClass', |
| 548 type='function'), |
| 549 NativeMethod(return_type='int', static=False, |
| 550 name='Init', params=[], |
| 551 java_class_name='MyOtherInnerClass', |
| 552 type='function') |
| 553 ] |
| 554 self.assertListEquals(golden_natives, natives) |
| 555 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
| 556 natives, []) |
| 557 golden_content = """\ |
| 558 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 559 // Use of this source code is governed by a BSD-style license that can be |
| 560 // found in the LICENSE file. |
| 561 |
| 562 |
| 563 // This file is autogenerated by |
| 564 // base/android/jni_generator/jni_generator_tests.py |
| 565 // For |
| 566 // org/chromium/TestJni |
| 567 |
| 568 #ifndef org_chromium_TestJni_JNI |
| 569 #define org_chromium_TestJni_JNI |
| 570 |
| 571 #include <jni.h> |
| 572 |
| 573 #include "base/android/jni_android.h" |
| 574 #include "base/android/scoped_java_ref.h" |
| 575 #include "base/basictypes.h" |
| 576 #include "base/logging.h" |
| 577 |
| 578 using base::android::ScopedJavaLocalRef; |
| 579 |
| 580 // Step 1: forward declarations. |
| 581 namespace { |
| 582 const char* const kMyOtherInnerClassClassPath = |
| 583 "org/chromium/TestJni$MyOtherInnerClass"; |
| 584 const char* const kTestJniClassPath = "org/chromium/TestJni"; |
| 585 const char* const kMyInnerClassClassPath = "org/chromium/TestJni$MyInnerClass"; |
| 586 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 587 base::android::ScopedJavaGlobalRef<jclass>& |
| 588 g_TestJni_clazz = |
| 589 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 590 } // namespace |
| 591 |
| 592 static jint Init(JNIEnv* env, jobject obj); |
| 593 |
| 594 |
| 595 static jint Init(JNIEnv* env, jobject obj); |
| 596 |
| 597 |
| 598 // Step 2: method stubs. |
| 599 |
| 600 |
| 601 // Step 3: GetMethodIDs and RegisterNatives. |
| 602 |
| 603 |
| 604 static void GetMethodIDsImpl(JNIEnv* env) { |
| 605 g_TestJni_clazz.Reset( |
| 606 base::android::GetClass(env, kTestJniClassPath)); |
| 607 } |
| 608 |
| 609 static bool RegisterNativesImpl(JNIEnv* env) { |
| 610 GetMethodIDsImpl(env); |
| 611 |
| 612 static const JNINativeMethod kMethodsMyOtherInnerClass[] = { |
| 613 { "nativeInit", |
| 614 "(" |
| 615 ")" |
| 616 "I", reinterpret_cast<void*>(Init) }, |
| 617 }; |
| 618 const int kMethodsMyOtherInnerClassSize = |
| 619 arraysize(kMethodsMyOtherInnerClass); |
| 620 |
| 621 if (env->RegisterNatives(g_MyOtherInnerClass_clazz.obj(), |
| 622 kMethodsMyOtherInnerClass, |
| 623 kMethodsMyOtherInnerClassSize) < 0) { |
| 624 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 625 return false; |
| 626 } |
| 627 |
| 628 static const JNINativeMethod kMethodsMyInnerClass[] = { |
| 629 { "nativeInit", |
| 630 "(" |
| 631 ")" |
| 632 "I", reinterpret_cast<void*>(Init) }, |
| 633 }; |
| 634 const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); |
| 635 |
| 636 if (env->RegisterNatives(g_MyInnerClass_clazz.obj(), |
| 637 kMethodsMyInnerClass, |
| 638 kMethodsMyInnerClassSize) < 0) { |
| 639 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 640 return false; |
| 641 } |
| 642 |
| 643 return true; |
| 644 } |
| 645 |
| 646 #endif // org_chromium_TestJni_JNI |
| 647 """ |
| 648 self.assertTextEquals(golden_content, h.GetContent()) |
| 649 |
| 650 def testInnerClassNativesBothInnerAndOuter(self): |
| 651 test_data = """ |
| 652 class MyOuterClass { |
| 653 private native int nativeInit(); |
| 654 class MyOtherInnerClass { |
| 655 @NativeCall("MyOtherInnerClass") |
| 656 private native int nativeInit(); |
| 657 } |
| 658 } |
| 659 """ |
| 660 natives = jni_generator.ExtractNatives(test_data) |
| 661 golden_natives = [ |
| 662 NativeMethod(return_type='int', static=False, |
| 663 name='Init', params=[], |
| 664 java_class_name='', |
| 665 type='function'), |
| 666 NativeMethod(return_type='int', static=False, |
| 667 name='Init', params=[], |
| 668 java_class_name='MyOtherInnerClass', |
| 669 type='function') |
| 670 ] |
| 671 self.assertListEquals(golden_natives, natives) |
| 672 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
| 673 natives, []) |
| 674 golden_content = """\ |
| 675 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 676 // Use of this source code is governed by a BSD-style license that can be |
| 677 // found in the LICENSE file. |
| 678 |
| 679 |
| 680 // This file is autogenerated by |
| 681 // base/android/jni_generator/jni_generator_tests.py |
| 682 // For |
| 683 // org/chromium/TestJni |
| 684 |
| 685 #ifndef org_chromium_TestJni_JNI |
| 686 #define org_chromium_TestJni_JNI |
| 687 |
| 688 #include <jni.h> |
| 689 |
| 690 #include "base/android/jni_android.h" |
| 691 #include "base/android/scoped_java_ref.h" |
| 692 #include "base/basictypes.h" |
| 693 #include "base/logging.h" |
| 694 |
| 695 using base::android::ScopedJavaLocalRef; |
| 696 |
| 697 // Step 1: forward declarations. |
| 698 namespace { |
| 699 const char* const kMyOtherInnerClassClassPath = |
| 700 "org/chromium/TestJni$MyOtherInnerClass"; |
| 701 const char* const kTestJniClassPath = "org/chromium/TestJni"; |
| 702 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 703 base::android::ScopedJavaGlobalRef<jclass>& |
| 704 g_TestJni_clazz = |
| 705 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 706 } // namespace |
| 707 |
| 708 static jint Init(JNIEnv* env, jobject obj); |
| 709 |
| 710 |
| 711 static jint Init(JNIEnv* env, jobject obj); |
| 712 |
| 713 |
| 714 // Step 2: method stubs. |
| 715 |
| 716 |
| 717 // Step 3: GetMethodIDs and RegisterNatives. |
| 718 |
| 719 |
| 720 static void GetMethodIDsImpl(JNIEnv* env) { |
| 721 g_TestJni_clazz.Reset( |
| 722 base::android::GetClass(env, kTestJniClassPath)); |
| 723 } |
| 724 |
| 725 static bool RegisterNativesImpl(JNIEnv* env) { |
| 726 GetMethodIDsImpl(env); |
| 727 |
| 728 static const JNINativeMethod kMethodsMyOtherInnerClass[] = { |
| 729 { "nativeInit", |
| 730 "(" |
| 731 ")" |
| 732 "I", reinterpret_cast<void*>(Init) }, |
| 733 }; |
| 734 const int kMethodsMyOtherInnerClassSize = |
| 735 arraysize(kMethodsMyOtherInnerClass); |
| 736 |
| 737 if (env->RegisterNatives(g_MyOtherInnerClass_clazz.obj(), |
| 738 kMethodsMyOtherInnerClass, |
| 739 kMethodsMyOtherInnerClassSize) < 0) { |
| 740 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 741 return false; |
| 742 } |
| 743 |
| 744 static const JNINativeMethod kMethodsTestJni[] = { |
| 745 { "nativeInit", |
| 746 "(" |
| 747 ")" |
| 748 "I", reinterpret_cast<void*>(Init) }, |
| 749 }; |
| 750 const int kMethodsTestJniSize = arraysize(kMethodsTestJni); |
| 751 |
| 752 if (env->RegisterNatives(g_TestJni_clazz.obj(), |
| 753 kMethodsTestJni, |
| 754 kMethodsTestJniSize) < 0) { |
| 755 LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
| 756 return false; |
| 757 } |
| 758 |
| 759 return true; |
| 760 } |
| 761 |
| 762 #endif // org_chromium_TestJni_JNI |
| 763 """ |
| 764 self.assertTextEquals(golden_content, h.GetContent()) |
| 765 |
| 766 def testCalledByNatives(self): |
| 767 test_data = """" |
| 768 @CalledByNative |
| 769 NativeInfoBar showConfirmInfoBar(int nativeInfoBar, String buttonOk, |
| 770 String buttonCancel, String title, |
| 771 Bitmap icon) { |
| 772 InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext, |
| 773 buttonOk, buttonCancel, |
| 774 title, icon); |
| 775 return infobar; |
| 776 } |
| 777 @CalledByNative |
| 778 NativeInfoBar showAutoLoginInfoBar(int nativeInfoBar, |
| 779 String realm, String account, |
| 780 String args) { |
| 781 AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext, |
| 782 realm, account, args); |
| 783 if (infobar.displayedAccountCount() == 0) |
| 784 infobar = null; |
| 785 return infobar; |
| 786 } |
| 787 @CalledByNative("InfoBar") |
| 788 void dismiss(); |
| 789 @SuppressWarnings("unused") |
| 790 @CalledByNative |
| 791 private static boolean shouldShowAutoLogin(ChromeView chromeView, |
| 792 String realm, String account, String args) { |
| 793 AccountManagerContainer accountManagerContainer = |
| 794 new AccountManagerContainer((Activity)chromeView.getContext(), |
| 795 realm, account, args); |
| 796 String[] logins = accountManagerContainer.getAccountLogins(null); |
| 797 return logins.length != 0; |
| 798 } |
| 799 @CalledByNative |
| 800 static InputStream openUrl(String url) { |
| 801 return null; |
| 802 } |
| 803 @CalledByNative |
| 804 private void activateHardwareAcceleration(final boolean activated, |
| 805 final int iPid, final int iType, |
| 806 final int iPrimaryID, final int iSecondaryID) { |
| 807 if (!activated) { |
| 808 return |
| 809 } |
| 810 } |
| 811 @CalledByNativeUnchecked |
| 812 private void uncheckedCall(int iParam); |
| 813 """ |
| 814 called_by_natives = jni_generator.ExtractCalledByNatives(test_data) |
| 815 golden_called_by_natives = [ |
| 816 CalledByNative( |
| 817 return_type='NativeInfoBar', |
| 818 system_class=False, |
| 819 static=False, |
| 820 name='showConfirmInfoBar', |
| 821 method_id_var_name='showConfirmInfoBar', |
| 822 java_class_name='', |
| 823 params=[Param(datatype='int', name='nativeInfoBar'), |
| 824 Param(datatype='String', name='buttonOk'), |
| 825 Param(datatype='String', name='buttonCancel'), |
| 826 Param(datatype='String', name='title'), |
| 827 Param(datatype='Bitmap', name='icon')], |
| 828 env_call=('Object', ''), |
| 829 unchecked=False, |
| 830 ), |
| 831 CalledByNative( |
| 832 return_type='NativeInfoBar', |
| 833 system_class=False, |
| 834 static=False, |
| 835 name='showAutoLoginInfoBar', |
| 836 method_id_var_name='showAutoLoginInfoBar', |
| 837 java_class_name='', |
| 838 params=[Param(datatype='int', name='nativeInfoBar'), |
| 839 Param(datatype='String', name='realm'), |
| 840 Param(datatype='String', name='account'), |
| 841 Param(datatype='String', name='args')], |
| 842 env_call=('Object', ''), |
| 843 unchecked=False, |
| 844 ), |
| 845 CalledByNative( |
| 846 return_type='void', |
| 847 system_class=False, |
| 848 static=False, |
| 849 name='dismiss', |
| 850 method_id_var_name='dismiss', |
| 851 java_class_name='InfoBar', |
| 852 params=[], |
| 853 env_call=('Void', ''), |
| 854 unchecked=False, |
| 855 ), |
| 856 CalledByNative( |
| 857 return_type='boolean', |
| 858 system_class=False, |
| 859 static=True, |
| 860 name='shouldShowAutoLogin', |
| 861 method_id_var_name='shouldShowAutoLogin', |
| 862 java_class_name='', |
| 863 params=[Param(datatype='ChromeView', name='chromeView'), |
| 864 Param(datatype='String', name='realm'), |
| 865 Param(datatype='String', name='account'), |
| 866 Param(datatype='String', name='args')], |
| 867 env_call=('Boolean', ''), |
| 868 unchecked=False, |
| 869 ), |
| 870 CalledByNative( |
| 871 return_type='InputStream', |
| 872 system_class=False, |
| 873 static=True, |
| 874 name='openUrl', |
| 875 method_id_var_name='openUrl', |
| 876 java_class_name='', |
| 877 params=[Param(datatype='String', name='url')], |
| 878 env_call=('Object', ''), |
| 879 unchecked=False, |
| 880 ), |
| 881 CalledByNative( |
| 882 return_type='void', |
| 883 system_class=False, |
| 884 static=False, |
| 885 name='activateHardwareAcceleration', |
| 886 method_id_var_name='activateHardwareAcceleration', |
| 887 java_class_name='', |
| 888 params=[Param(datatype='boolean', name='activated'), |
| 889 Param(datatype='int', name='iPid'), |
| 890 Param(datatype='int', name='iType'), |
| 891 Param(datatype='int', name='iPrimaryID'), |
| 892 Param(datatype='int', name='iSecondaryID'), |
| 893 ], |
| 894 env_call=('Void', ''), |
| 895 unchecked=False, |
| 896 ), |
| 897 CalledByNative( |
| 898 return_type='void', |
| 899 system_class=False, |
| 900 static=False, |
| 901 name='uncheckedCall', |
| 902 method_id_var_name='uncheckedCall', |
| 903 java_class_name='', |
| 904 params=[Param(datatype='int', name='iParam')], |
| 905 env_call=('Void', ''), |
| 906 unchecked=True, |
| 907 ), |
| 908 ] |
| 909 self.assertListEquals(golden_called_by_natives, called_by_natives) |
| 910 h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
| 911 [], called_by_natives) |
| 912 golden_content = """\ |
| 913 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 914 // Use of this source code is governed by a BSD-style license that can be |
| 915 // found in the LICENSE file. |
| 916 |
| 917 |
| 918 // This file is autogenerated by |
| 919 // base/android/jni_generator/jni_generator_tests.py |
| 920 // For |
| 921 // org/chromium/TestJni |
| 922 |
| 923 #ifndef org_chromium_TestJni_JNI |
| 924 #define org_chromium_TestJni_JNI |
| 925 |
| 926 #include <jni.h> |
| 927 |
| 928 #include "base/android/jni_android.h" |
| 929 #include "base/android/scoped_java_ref.h" |
| 930 #include "base/basictypes.h" |
| 931 #include "base/logging.h" |
| 932 |
| 933 using base::android::ScopedJavaLocalRef; |
| 934 |
| 935 // Step 1: forward declarations. |
| 936 namespace { |
| 937 const char* const kTestJniClassPath = "org/chromium/TestJni"; |
| 938 const char* const kInfoBarClassPath = "org/chromium/TestJni$InfoBar"; |
| 939 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 940 base::android::ScopedJavaGlobalRef<jclass>& |
| 941 g_TestJni_clazz = |
| 942 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 943 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 944 base::android::ScopedJavaGlobalRef<jclass>& |
| 945 g_InfoBar_clazz = |
| 946 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 947 } // namespace |
| 948 |
| 949 |
| 950 // Step 2: method stubs. |
| 951 |
| 952 static jmethodID g_TestJni_showConfirmInfoBar = 0; |
| 953 static ScopedJavaLocalRef<jobject> Java_TestJni_showConfirmInfoBar(JNIEnv* env, |
| 954 jobject obj, jint nativeInfoBar, |
| 955 jstring buttonOk, |
| 956 jstring buttonCancel, |
| 957 jstring title, |
| 958 jobject icon) { |
| 959 /* Must call RegisterNativesImpl() */ |
| 960 DCHECK(!g_TestJni_clazz.is_null()); |
| 961 DCHECK(g_TestJni_showConfirmInfoBar); |
| 962 jobject ret = |
| 963 env->CallObjectMethod(obj, |
| 964 g_TestJni_showConfirmInfoBar, nativeInfoBar, buttonOk, buttonCancel, |
| 965 title, icon); |
| 966 base::android::CheckException(env); |
| 967 return ScopedJavaLocalRef<jobject>(env, ret); |
| 968 } |
| 969 |
| 970 static jmethodID g_TestJni_showAutoLoginInfoBar = 0; |
| 971 static ScopedJavaLocalRef<jobject> Java_TestJni_showAutoLoginInfoBar(JNIEnv* |
| 972 env, jobject obj, jint nativeInfoBar, |
| 973 jstring realm, |
| 974 jstring account, |
| 975 jstring args) { |
| 976 /* Must call RegisterNativesImpl() */ |
| 977 DCHECK(!g_TestJni_clazz.is_null()); |
| 978 DCHECK(g_TestJni_showAutoLoginInfoBar); |
| 979 jobject ret = |
| 980 env->CallObjectMethod(obj, |
| 981 g_TestJni_showAutoLoginInfoBar, nativeInfoBar, realm, account, args); |
| 982 base::android::CheckException(env); |
| 983 return ScopedJavaLocalRef<jobject>(env, ret); |
| 984 } |
| 985 |
| 986 static jmethodID g_InfoBar_dismiss = 0; |
| 987 static void Java_InfoBar_dismiss(JNIEnv* env, jobject obj) { |
| 988 /* Must call RegisterNativesImpl() */ |
| 989 DCHECK(!g_InfoBar_clazz.is_null()); |
| 990 DCHECK(g_InfoBar_dismiss); |
| 991 |
| 992 env->CallVoidMethod(obj, |
| 993 g_InfoBar_dismiss); |
| 994 base::android::CheckException(env); |
| 995 |
| 996 } |
| 997 |
| 998 static jmethodID g_TestJni_shouldShowAutoLogin = 0; |
| 999 static jboolean Java_TestJni_shouldShowAutoLogin(JNIEnv* env, jobject |
| 1000 chromeView, |
| 1001 jstring realm, |
| 1002 jstring account, |
| 1003 jstring args) { |
| 1004 /* Must call RegisterNativesImpl() */ |
| 1005 DCHECK(!g_TestJni_clazz.is_null()); |
| 1006 DCHECK(g_TestJni_shouldShowAutoLogin); |
| 1007 jboolean ret = |
| 1008 env->CallStaticBooleanMethod(g_TestJni_clazz.obj(), |
| 1009 g_TestJni_shouldShowAutoLogin, chromeView, realm, account, args); |
| 1010 base::android::CheckException(env); |
| 1011 return ret; |
| 1012 } |
| 1013 |
| 1014 static jmethodID g_TestJni_openUrl = 0; |
| 1015 static ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv* env, jstring |
| 1016 url) { |
| 1017 /* Must call RegisterNativesImpl() */ |
| 1018 DCHECK(!g_TestJni_clazz.is_null()); |
| 1019 DCHECK(g_TestJni_openUrl); |
| 1020 jobject ret = |
| 1021 env->CallStaticObjectMethod(g_TestJni_clazz.obj(), |
| 1022 g_TestJni_openUrl, url); |
| 1023 base::android::CheckException(env); |
| 1024 return ScopedJavaLocalRef<jobject>(env, ret); |
| 1025 } |
| 1026 |
| 1027 static jmethodID g_TestJni_activateHardwareAcceleration = 0; |
| 1028 static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, jobject obj, |
| 1029 jboolean activated, |
| 1030 jint iPid, |
| 1031 jint iType, |
| 1032 jint iPrimaryID, |
| 1033 jint iSecondaryID) { |
| 1034 /* Must call RegisterNativesImpl() */ |
| 1035 DCHECK(!g_TestJni_clazz.is_null()); |
| 1036 DCHECK(g_TestJni_activateHardwareAcceleration); |
| 1037 |
| 1038 env->CallVoidMethod(obj, |
| 1039 g_TestJni_activateHardwareAcceleration, activated, iPid, iType, |
| 1040 iPrimaryID, iSecondaryID); |
| 1041 base::android::CheckException(env); |
| 1042 |
| 1043 } |
| 1044 |
| 1045 static jmethodID g_TestJni_uncheckedCall = 0; |
| 1046 static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, jint iParam) { |
| 1047 /* Must call RegisterNativesImpl() */ |
| 1048 DCHECK(!g_TestJni_clazz.is_null()); |
| 1049 DCHECK(g_TestJni_uncheckedCall); |
| 1050 |
| 1051 env->CallVoidMethod(obj, |
| 1052 g_TestJni_uncheckedCall, iParam); |
| 1053 |
| 1054 |
| 1055 } |
| 1056 |
| 1057 // Step 3: GetMethodIDs and RegisterNatives. |
| 1058 |
| 1059 |
| 1060 static void GetMethodIDsImpl(JNIEnv* env) { |
| 1061 g_TestJni_clazz.Reset( |
| 1062 base::android::GetClass(env, kTestJniClassPath)); |
| 1063 g_InfoBar_clazz.Reset( |
| 1064 base::android::GetClass(env, kInfoBarClassPath)); |
| 1065 g_TestJni_showConfirmInfoBar = base::android::GetMethodID( |
| 1066 env, g_TestJni_clazz, |
| 1067 "showConfirmInfoBar", |
| 1068 |
| 1069 "(" |
| 1070 "I" |
| 1071 "Ljava/lang/String;" |
| 1072 "Ljava/lang/String;" |
| 1073 "Ljava/lang/String;" |
| 1074 "Landroid/graphics/Bitmap;" |
| 1075 ")" |
| 1076 "Lcom/android/chrome/infobar/InfoBarContainer$NativeInfoBar;"); |
| 1077 |
| 1078 g_TestJni_showAutoLoginInfoBar = base::android::GetMethodID( |
| 1079 env, g_TestJni_clazz, |
| 1080 "showAutoLoginInfoBar", |
| 1081 |
| 1082 "(" |
| 1083 "I" |
| 1084 "Ljava/lang/String;" |
| 1085 "Ljava/lang/String;" |
| 1086 "Ljava/lang/String;" |
| 1087 ")" |
| 1088 "Lcom/android/chrome/infobar/InfoBarContainer$NativeInfoBar;"); |
| 1089 |
| 1090 g_InfoBar_dismiss = base::android::GetMethodID( |
| 1091 env, g_InfoBar_clazz, |
| 1092 "dismiss", |
| 1093 |
| 1094 "(" |
| 1095 ")" |
| 1096 "V"); |
| 1097 |
| 1098 g_TestJni_shouldShowAutoLogin = base::android::GetStaticMethodID( |
| 1099 env, g_TestJni_clazz, |
| 1100 "shouldShowAutoLogin", |
| 1101 |
| 1102 "(" |
| 1103 "Lorg/chromium/chromeview/ChromeView;" |
| 1104 "Ljava/lang/String;" |
| 1105 "Ljava/lang/String;" |
| 1106 "Ljava/lang/String;" |
| 1107 ")" |
| 1108 "Z"); |
| 1109 |
| 1110 g_TestJni_openUrl = base::android::GetStaticMethodID( |
| 1111 env, g_TestJni_clazz, |
| 1112 "openUrl", |
| 1113 |
| 1114 "(" |
| 1115 "Ljava/lang/String;" |
| 1116 ")" |
| 1117 "Ljava/io/InputStream;"); |
| 1118 |
| 1119 g_TestJni_activateHardwareAcceleration = base::android::GetMethodID( |
| 1120 env, g_TestJni_clazz, |
| 1121 "activateHardwareAcceleration", |
| 1122 |
| 1123 "(" |
| 1124 "Z" |
| 1125 "I" |
| 1126 "I" |
| 1127 "I" |
| 1128 "I" |
| 1129 ")" |
| 1130 "V"); |
| 1131 |
| 1132 g_TestJni_uncheckedCall = base::android::GetMethodID( |
| 1133 env, g_TestJni_clazz, |
| 1134 "uncheckedCall", |
| 1135 |
| 1136 "(" |
| 1137 "I" |
| 1138 ")" |
| 1139 "V"); |
| 1140 |
| 1141 } |
| 1142 |
| 1143 static bool RegisterNativesImpl(JNIEnv* env) { |
| 1144 GetMethodIDsImpl(env); |
| 1145 |
| 1146 return true; |
| 1147 } |
| 1148 |
| 1149 #endif // org_chromium_TestJni_JNI |
| 1150 """ |
| 1151 self.assertTextEquals(golden_content, h.GetContent()) |
| 1152 |
| 1153 def testCalledByNativeParseError(self): |
| 1154 try: |
| 1155 jni_generator.ExtractCalledByNatives(""" |
| 1156 @CalledByNative |
| 1157 public static int foo(); // This one is fine |
| 1158 |
| 1159 @CalledByNative |
| 1160 scooby doo |
| 1161 """) |
| 1162 self.fail('Expected a ParseError') |
| 1163 except jni_generator.ParseError, e: |
| 1164 self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines) |
| 1165 |
| 1166 def testFullyQualifiedClassName(self): |
| 1167 contents = """ |
| 1168 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 1169 // Use of this source code is governed by a BSD-style license that can be |
| 1170 // found in the LICENSE file. |
| 1171 |
| 1172 package org.chromium.chromeview; |
| 1173 |
| 1174 import org.chromium.chromeview.legacy.DownloadListener; |
| 1175 """ |
| 1176 self.assertEquals('org/chromium/chromeview/Foo', |
| 1177 jni_generator.ExtractFullyQualifiedJavaClassName( |
| 1178 'org/chromium/chromeview/Foo.java', contents)) |
| 1179 self.assertEquals('org/chromium/chromeview/Foo', |
| 1180 jni_generator.ExtractFullyQualifiedJavaClassName( |
| 1181 'frameworks/Foo.java', contents)) |
| 1182 self.assertRaises(SyntaxError, |
| 1183 jni_generator.ExtractFullyQualifiedJavaClassName, |
| 1184 'com/foo/Bar', 'no PACKAGE line') |
| 1185 |
| 1186 def testMethodNameMangling(self): |
| 1187 self.assertEquals('close_pqV', |
| 1188 jni_generator.GetMangledMethodName('close', '()V')) |
| 1189 self.assertEquals('read_paBIIqI', |
| 1190 jni_generator.GetMangledMethodName('read', '([BII)I')) |
| 1191 self.assertEquals('open_pLjava_lang_StringxqLjava_io_InputStreamx', |
| 1192 jni_generator.GetMangledMethodName( |
| 1193 'open', |
| 1194 '(Ljava/lang/String;)Ljava/io/InputStream;')) |
| 1195 |
| 1196 def testFromJavaP(self): |
| 1197 contents = """ |
| 1198 public abstract class java.io.InputStream extends java.lang.Object |
| 1199 implements java.io.Closeable{ |
| 1200 public java.io.InputStream(); |
| 1201 public int available() throws java.io.IOException; |
| 1202 public void close() throws java.io.IOException; |
| 1203 public void mark(int); |
| 1204 public boolean markSupported(); |
| 1205 public abstract int read() throws java.io.IOException; |
| 1206 public int read(byte[]) throws java.io.IOException; |
| 1207 public int read(byte[], int, int) throws java.io.IOException; |
| 1208 public synchronized void reset() throws java.io.IOException; |
| 1209 public long skip(long) throws java.io.IOException; |
| 1210 } |
| 1211 """ |
| 1212 jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'), None) |
| 1213 self.assertEquals(9, len(jni_from_javap.called_by_natives)) |
| 1214 golden_content = """\ |
| 1215 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 1216 // Use of this source code is governed by a BSD-style license that can be |
| 1217 // found in the LICENSE file. |
| 1218 |
| 1219 |
| 1220 // This file is autogenerated by |
| 1221 // base/android/jni_generator/jni_generator_tests.py |
| 1222 // For |
| 1223 // java/io/InputStream |
| 1224 |
| 1225 #ifndef java_io_InputStream_JNI |
| 1226 #define java_io_InputStream_JNI |
| 1227 |
| 1228 #include <jni.h> |
| 1229 |
| 1230 #include "base/android/jni_android.h" |
| 1231 #include "base/android/scoped_java_ref.h" |
| 1232 #include "base/basictypes.h" |
| 1233 #include "base/logging.h" |
| 1234 |
| 1235 using base::android::ScopedJavaLocalRef; |
| 1236 |
| 1237 // Step 1: forward declarations. |
| 1238 namespace { |
| 1239 const char* const kInputStreamClassPath = "java/io/InputStream"; |
| 1240 // Leaking this JavaRef as we cannot use LazyInstance from some threads. |
| 1241 base::android::ScopedJavaGlobalRef<jclass>& |
| 1242 g_InputStream_clazz = |
| 1243 *(new base::android::ScopedJavaGlobalRef<jclass>()); |
| 1244 } // namespace |
| 1245 |
| 1246 |
| 1247 // Step 2: method stubs. |
| 1248 |
| 1249 static jmethodID g_InputStream_available = 0; |
| 1250 static jint Java_InputStream_available(JNIEnv* env, jobject obj) __attribute__ |
| 1251 ((unused)); |
| 1252 static jint Java_InputStream_available(JNIEnv* env, jobject obj) { |
| 1253 /* Must call RegisterNativesImpl() */ |
| 1254 DCHECK(!g_InputStream_clazz.is_null()); |
| 1255 DCHECK(g_InputStream_available); |
| 1256 jint ret = |
| 1257 env->CallIntMethod(obj, |
| 1258 g_InputStream_available); |
| 1259 base::android::CheckException(env); |
| 1260 return ret; |
| 1261 } |
| 1262 |
| 1263 static jmethodID g_InputStream_close = 0; |
| 1264 static void Java_InputStream_close(JNIEnv* env, jobject obj) __attribute__ |
| 1265 ((unused)); |
| 1266 static void Java_InputStream_close(JNIEnv* env, jobject obj) { |
| 1267 /* Must call RegisterNativesImpl() */ |
| 1268 DCHECK(!g_InputStream_clazz.is_null()); |
| 1269 DCHECK(g_InputStream_close); |
| 1270 |
| 1271 env->CallVoidMethod(obj, |
| 1272 g_InputStream_close); |
| 1273 base::android::CheckException(env); |
| 1274 |
| 1275 } |
| 1276 |
| 1277 static jmethodID g_InputStream_mark = 0; |
| 1278 static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) |
| 1279 __attribute__ ((unused)); |
| 1280 static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) { |
| 1281 /* Must call RegisterNativesImpl() */ |
| 1282 DCHECK(!g_InputStream_clazz.is_null()); |
| 1283 DCHECK(g_InputStream_mark); |
| 1284 |
| 1285 env->CallVoidMethod(obj, |
| 1286 g_InputStream_mark, p0); |
| 1287 base::android::CheckException(env); |
| 1288 |
| 1289 } |
| 1290 |
| 1291 static jmethodID g_InputStream_markSupported = 0; |
| 1292 static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) |
| 1293 __attribute__ ((unused)); |
| 1294 static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) { |
| 1295 /* Must call RegisterNativesImpl() */ |
| 1296 DCHECK(!g_InputStream_clazz.is_null()); |
| 1297 DCHECK(g_InputStream_markSupported); |
| 1298 jboolean ret = |
| 1299 env->CallBooleanMethod(obj, |
| 1300 g_InputStream_markSupported); |
| 1301 base::android::CheckException(env); |
| 1302 return ret; |
| 1303 } |
| 1304 |
| 1305 static jmethodID g_InputStream_read_pqI = 0; |
| 1306 static jint Java_InputStream_read(JNIEnv* env, jobject obj) __attribute__ |
| 1307 ((unused)); |
| 1308 static jint Java_InputStream_read(JNIEnv* env, jobject obj) { |
| 1309 /* Must call RegisterNativesImpl() */ |
| 1310 DCHECK(!g_InputStream_clazz.is_null()); |
| 1311 DCHECK(g_InputStream_read_pqI); |
| 1312 jint ret = |
| 1313 env->CallIntMethod(obj, |
| 1314 g_InputStream_read_pqI); |
| 1315 base::android::CheckException(env); |
| 1316 return ret; |
| 1317 } |
| 1318 |
| 1319 static jmethodID g_InputStream_read_paBqI = 0; |
| 1320 static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0) |
| 1321 __attribute__ ((unused)); |
| 1322 static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0) { |
| 1323 /* Must call RegisterNativesImpl() */ |
| 1324 DCHECK(!g_InputStream_clazz.is_null()); |
| 1325 DCHECK(g_InputStream_read_paBqI); |
| 1326 jint ret = |
| 1327 env->CallIntMethod(obj, |
| 1328 g_InputStream_read_paBqI, p0); |
| 1329 base::android::CheckException(env); |
| 1330 return ret; |
| 1331 } |
| 1332 |
| 1333 static jmethodID g_InputStream_read_paBIIqI = 0; |
| 1334 static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0, |
| 1335 jint p1, |
| 1336 jint p2) __attribute__ ((unused)); |
| 1337 static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0, |
| 1338 jint p1, |
| 1339 jint p2) { |
| 1340 /* Must call RegisterNativesImpl() */ |
| 1341 DCHECK(!g_InputStream_clazz.is_null()); |
| 1342 DCHECK(g_InputStream_read_paBIIqI); |
| 1343 jint ret = |
| 1344 env->CallIntMethod(obj, |
| 1345 g_InputStream_read_paBIIqI, p0, p1, p2); |
| 1346 base::android::CheckException(env); |
| 1347 return ret; |
| 1348 } |
| 1349 |
| 1350 static jmethodID g_InputStream_reset = 0; |
| 1351 static void Java_InputStream_reset(JNIEnv* env, jobject obj) __attribute__ |
| 1352 ((unused)); |
| 1353 static void Java_InputStream_reset(JNIEnv* env, jobject obj) { |
| 1354 /* Must call RegisterNativesImpl() */ |
| 1355 DCHECK(!g_InputStream_clazz.is_null()); |
| 1356 DCHECK(g_InputStream_reset); |
| 1357 |
| 1358 env->CallVoidMethod(obj, |
| 1359 g_InputStream_reset); |
| 1360 base::android::CheckException(env); |
| 1361 |
| 1362 } |
| 1363 |
| 1364 static jmethodID g_InputStream_skip = 0; |
| 1365 static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) |
| 1366 __attribute__ ((unused)); |
| 1367 static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) { |
| 1368 /* Must call RegisterNativesImpl() */ |
| 1369 DCHECK(!g_InputStream_clazz.is_null()); |
| 1370 DCHECK(g_InputStream_skip); |
| 1371 jlong ret = |
| 1372 env->CallLongMethod(obj, |
| 1373 g_InputStream_skip, p0); |
| 1374 base::android::CheckException(env); |
| 1375 return ret; |
| 1376 } |
| 1377 |
| 1378 // Step 3: GetMethodIDs and RegisterNatives. |
| 1379 namespace JNI_InputStream { |
| 1380 |
| 1381 static void GetMethodIDsImpl(JNIEnv* env) { |
| 1382 g_InputStream_clazz.Reset( |
| 1383 base::android::GetClass(env, kInputStreamClassPath)); |
| 1384 g_InputStream_available = base::android::GetMethodID( |
| 1385 env, g_InputStream_clazz, |
| 1386 "available", |
| 1387 |
| 1388 "(" |
| 1389 ")" |
| 1390 "I"); |
| 1391 |
| 1392 g_InputStream_close = base::android::GetMethodID( |
| 1393 env, g_InputStream_clazz, |
| 1394 "close", |
| 1395 |
| 1396 "(" |
| 1397 ")" |
| 1398 "V"); |
| 1399 |
| 1400 g_InputStream_mark = base::android::GetMethodID( |
| 1401 env, g_InputStream_clazz, |
| 1402 "mark", |
| 1403 |
| 1404 "(" |
| 1405 "I" |
| 1406 ")" |
| 1407 "V"); |
| 1408 |
| 1409 g_InputStream_markSupported = base::android::GetMethodID( |
| 1410 env, g_InputStream_clazz, |
| 1411 "markSupported", |
| 1412 |
| 1413 "(" |
| 1414 ")" |
| 1415 "Z"); |
| 1416 |
| 1417 g_InputStream_read_pqI = base::android::GetMethodID( |
| 1418 env, g_InputStream_clazz, |
| 1419 "read", |
| 1420 |
| 1421 "(" |
| 1422 ")" |
| 1423 "I"); |
| 1424 |
| 1425 g_InputStream_read_paBqI = base::android::GetMethodID( |
| 1426 env, g_InputStream_clazz, |
| 1427 "read", |
| 1428 |
| 1429 "(" |
| 1430 "[B" |
| 1431 ")" |
| 1432 "I"); |
| 1433 |
| 1434 g_InputStream_read_paBIIqI = base::android::GetMethodID( |
| 1435 env, g_InputStream_clazz, |
| 1436 "read", |
| 1437 |
| 1438 "(" |
| 1439 "[B" |
| 1440 "I" |
| 1441 "I" |
| 1442 ")" |
| 1443 "I"); |
| 1444 |
| 1445 g_InputStream_reset = base::android::GetMethodID( |
| 1446 env, g_InputStream_clazz, |
| 1447 "reset", |
| 1448 |
| 1449 "(" |
| 1450 ")" |
| 1451 "V"); |
| 1452 |
| 1453 g_InputStream_skip = base::android::GetMethodID( |
| 1454 env, g_InputStream_clazz, |
| 1455 "skip", |
| 1456 |
| 1457 "(" |
| 1458 "J" |
| 1459 ")" |
| 1460 "J"); |
| 1461 |
| 1462 } |
| 1463 |
| 1464 static bool RegisterNativesImpl(JNIEnv* env) { |
| 1465 JNI_InputStream::GetMethodIDsImpl(env); |
| 1466 |
| 1467 return true; |
| 1468 } |
| 1469 } // namespace JNI_InputStream |
| 1470 |
| 1471 #endif // java_io_InputStream_JNI |
| 1472 """ |
| 1473 self.assertTextEquals(golden_content, jni_from_javap.GetContent()) |
| 1474 |
| 1475 def testREForNatives(self): |
| 1476 # We should not match "native SyncSetupFlow" inside the comment. |
| 1477 test_data = """ |
| 1478 /** |
| 1479 * Invoked when the setup process is complete so we can disconnect from the |
| 1480 * native-side SyncSetupFlowHandler. |
| 1481 */ |
| 1482 public void destroy() { |
| 1483 Log.v(TAG, "Destroying native SyncSetupFlow"); |
| 1484 if (mNativeSyncSetupFlow != 0) { |
| 1485 nativeSyncSetupEnded(mNativeSyncSetupFlow); |
| 1486 mNativeSyncSetupFlow = 0; |
| 1487 } |
| 1488 } |
| 1489 private native void nativeSyncSetupEnded( |
| 1490 int nativeAndroidSyncSetupFlowHandler); |
| 1491 """ |
| 1492 jni_from_java = jni_generator.JNIFromJavaSource(test_data, 'foo/bar') |
| 1493 |
| 1494 def testRaisesOnUnknownDatatype(self): |
| 1495 test_data = """ |
| 1496 class MyInnerClass { |
| 1497 private native int nativeInit(AnUnknownDatatype p0); |
| 1498 } |
| 1499 """ |
| 1500 self.assertRaises(SyntaxError, |
| 1501 jni_generator.JNIFromJavaSource, |
| 1502 test_data, 'foo/bar') |
| 1503 |
| 1504 def testJniSelfDocumentingExample(self): |
| 1505 script_dir = os.path.dirname(sys.argv[0]) |
| 1506 content = file(os.path.join(script_dir, 'SampleForTests.java')).read() |
| 1507 golden_content = file(os.path.join(script_dir, |
| 1508 'golden_sample_for_tests_jni.h')).read() |
| 1509 jni_from_java = jni_generator.JNIFromJavaSource( |
| 1510 content, 'org/chromium/example/jni_generator/SampleForTests') |
| 1511 self.assertTextEquals(golden_content, jni_from_java.GetContent()) |
| 1512 |
| 1513 def testCheckFilenames(self): |
| 1514 self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
| 1515 ['more', 'input', 'than'], ['output']) |
| 1516 self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
| 1517 ['more'], ['output', 'than', 'input']) |
| 1518 self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
| 1519 ['NotTheSame.java'], ['not_good.h']) |
| 1520 self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
| 1521 ['MissingJniSuffix.java'], ['missing_jni_suffix.h']) |
| 1522 jni_generator.CheckFilenames(['ThisIsFine.java'], ['this_is_fine_jni.h']) |
| 1523 jni_generator.CheckFilenames([], []) |
| 1524 |
| 1525 |
| 1526 if __name__ == '__main__': |
| 1527 unittest.main() |
OLD | NEW |