Index: base/android/jni_generator/jni_generator_tests.py |
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0c5c0ced5e876a5289cd3c0ede74e70ffa18c2dd |
--- /dev/null |
+++ b/base/android/jni_generator/jni_generator_tests.py |
@@ -0,0 +1,1527 @@ |
+#!/usr/bin/python |
+# |
+# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Tests for jni_generator.py. |
+ |
+This test suite contains various tests for the JNI generator. |
+It exercises the low-level parser all the way up to the |
+code generator and ensures the output matches a golden |
+file. |
+""" |
+ |
+import difflib |
+import os |
+import sys |
+import unittest |
+import jni_generator |
+from jni_generator import CalledByNative, NativeMethod, Param |
+ |
+ |
+class TestGenerator(unittest.TestCase): |
+ def assertObjEquals(self, first, second): |
+ dict_first = first.__dict__ |
+ dict_second = second.__dict__ |
+ self.assertEquals(dict_first.keys(), dict_second.keys()) |
+ for key, value in dict_first.iteritems(): |
+ if (type(value) is list and len(value) and |
+ isinstance(type(value[0]), object)): |
+ self.assertListEquals(value, second.__getattribute__(key)) |
+ else: |
+ self.assertEquals(value, second.__getattribute__(key)) |
+ |
+ def assertListEquals(self, first, second): |
+ self.assertEquals(len(first), len(second)) |
+ for i in xrange(len(first)): |
+ if isinstance(first[i], object): |
+ self.assertObjEquals(first[i], second[i]) |
+ else: |
+ self.assertEquals(first[i], second[i]) |
+ |
+ def assertTextEquals(self, golden_text, generated_text): |
+ stripped_golden = [l.strip() for l in golden_text.split('\n')] |
+ stripped_generated = [l.strip() for l in generated_text.split('\n')] |
+ if stripped_golden != stripped_generated: |
+ print self.id() |
+ for line in difflib.context_diff(stripped_golden, stripped_generated): |
+ print line |
+ self.fail('Golden text mismatch') |
+ |
+ def testNatives(self): |
+ test_data = """" |
+ private native int nativeInit(); |
+ private native void nativeDestroy(int nativeChromeBrowserProvider); |
+ private native long nativeAddBookmark( |
+ int nativeChromeBrowserProvider, |
+ String url, String title, boolean isFolder, long parentId); |
+ private static native String nativeGetDomainAndRegistry(String url); |
+ private static native void nativeCreateHistoricalTabFromState( |
+ byte[] state, int tab_index); |
+ private native byte[] nativeGetStateAsByteArray(ChromeView view); |
+ private static native String[] nativeGetAutofillProfileGUIDs(); |
+ private native void nativeSetRecognitionResults( |
+ int sessionId, String[] results); |
+ private native long nativeAddBookmarkFromAPI( |
+ int nativeChromeBrowserProvider, |
+ String url, Long created, Boolean isBookmark, |
+ Long date, byte[] favicon, String title, Integer visits); |
+ native int nativeFindAll(String find); |
+ private static native BookmarkNode nativeGetDefaultBookmarkFolder(); |
+ private native SQLiteCursor nativeQueryBookmarkFromAPI( |
+ int nativeChromeBrowserProvider, |
+ String[] projection, String selection, |
+ String[] selectionArgs, String sortOrder); |
+ private native void nativeGotOrientation( |
+ int nativePtr /* device_orientation::DeviceOrientationAndroid */, |
+ double alpha, double beta, double gamma); |
+ """ |
+ natives = jni_generator.ExtractNatives(test_data) |
+ golden_natives = [ |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', |
+ params=[], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='void', static=False, name='Destroy', |
+ params=[Param(datatype='int', |
+ name='nativeChromeBrowserProvider')], |
+ java_class_name='', |
+ type='method', |
+ p0_type='ChromeBrowserProvider'), |
+ NativeMethod(return_type='long', static=False, name='AddBookmark', |
+ params=[Param(datatype='int', |
+ name='nativeChromeBrowserProvider'), |
+ Param(datatype='String', |
+ name='url'), |
+ Param(datatype='String', |
+ name='title'), |
+ Param(datatype='boolean', |
+ name='isFolder'), |
+ Param(datatype='long', |
+ name='parentId')], |
+ java_class_name='', |
+ type='method', |
+ p0_type='ChromeBrowserProvider'), |
+ NativeMethod(return_type='String', static=True, |
+ name='GetDomainAndRegistry', |
+ params=[Param(datatype='String', |
+ name='url')], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='void', static=True, |
+ name='CreateHistoricalTabFromState', |
+ params=[Param(datatype='byte[]', |
+ name='state'), |
+ Param(datatype='int', |
+ name='tab_index')], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='byte[]', static=False, |
+ name='GetStateAsByteArray', |
+ params=[Param(datatype='ChromeView', name='view')], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='String[]', static=True, |
+ name='GetAutofillProfileGUIDs', params=[], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='void', static=False, |
+ name='SetRecognitionResults', |
+ params=[Param(datatype='int', name='sessionId'), |
+ Param(datatype='String[]', name='results')], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='long', static=False, |
+ name='AddBookmarkFromAPI', |
+ params=[Param(datatype='int', |
+ name='nativeChromeBrowserProvider'), |
+ Param(datatype='String', |
+ name='url'), |
+ Param(datatype='Long', |
+ name='created'), |
+ Param(datatype='Boolean', |
+ name='isBookmark'), |
+ Param(datatype='Long', |
+ name='date'), |
+ Param(datatype='byte[]', |
+ name='favicon'), |
+ Param(datatype='String', |
+ name='title'), |
+ Param(datatype='Integer', |
+ name='visits')], |
+ java_class_name='', |
+ type='method', |
+ p0_type='ChromeBrowserProvider'), |
+ NativeMethod(return_type='int', static=False, |
+ name='FindAll', |
+ params=[Param(datatype='String', |
+ name='find')], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='BookmarkNode', static=True, |
+ name='GetDefaultBookmarkFolder', |
+ params=[], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='SQLiteCursor', |
+ static=False, |
+ name='QueryBookmarkFromAPI', |
+ params=[Param(datatype='int', |
+ name='nativeChromeBrowserProvider'), |
+ Param(datatype='String[]', |
+ name='projection'), |
+ Param(datatype='String', |
+ name='selection'), |
+ Param(datatype='String[]', |
+ name='selectionArgs'), |
+ Param(datatype='String', |
+ name='sortOrder'), |
+ ], |
+ java_class_name='', |
+ type='method', |
+ p0_type='ChromeBrowserProvider'), |
+ NativeMethod(return_type='void', static=False, |
+ name='GotOrientation', |
+ params=[Param(datatype='int', |
+ cpp_class_name= |
+ 'device_orientation::DeviceOrientationAndroid', |
+ name='nativePtr'), |
+ Param(datatype='double', |
+ name='alpha'), |
+ Param(datatype='double', |
+ name='beta'), |
+ Param(datatype='double', |
+ name='gamma'), |
+ ], |
+ java_class_name='', |
+ type='method', |
+ p0_type='device_orientation::DeviceOrientationAndroid'), |
+ ] |
+ self.assertListEquals(golden_natives, natives) |
+ h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
+ natives, []) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// org/chromium/TestJni |
+ |
+#ifndef org_chromium_TestJni_JNI |
+#define org_chromium_TestJni_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kTestJniClassPath = "org/chromium/TestJni"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_TestJni_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+static jstring GetDomainAndRegistry(JNIEnv* env, jclass clazz, |
+ jstring url); |
+ |
+ |
+static void CreateHistoricalTabFromState(JNIEnv* env, jclass clazz, |
+ jbyteArray state, |
+ jint tab_index); |
+ |
+ |
+static jbyteArray GetStateAsByteArray(JNIEnv* env, jobject obj, |
+ jobject view); |
+ |
+ |
+static jobjectArray GetAutofillProfileGUIDs(JNIEnv* env, jclass clazz); |
+ |
+ |
+static void SetRecognitionResults(JNIEnv* env, jobject obj, |
+ jint sessionId, |
+ jobjectArray results); |
+ |
+ |
+static jint FindAll(JNIEnv* env, jobject obj, |
+ jstring find); |
+ |
+ |
+static jobject GetDefaultBookmarkFolder(JNIEnv* env, jclass clazz); |
+ |
+ |
+// Step 2: method stubs. |
+static void Destroy(JNIEnv* env, jobject obj, |
+ jint nativeChromeBrowserProvider) { |
+ DCHECK(nativeChromeBrowserProvider) << "Destroy"; |
+ ChromeBrowserProvider* native = |
+ reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
+ return native->Destroy(env, obj); |
+} |
+ |
+static jlong AddBookmark(JNIEnv* env, jobject obj, |
+ jint nativeChromeBrowserProvider, |
+ jstring url, |
+ jstring title, |
+ jboolean isFolder, |
+ jlong parentId) { |
+ DCHECK(nativeChromeBrowserProvider) << "AddBookmark"; |
+ ChromeBrowserProvider* native = |
+ reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
+ return native->AddBookmark(env, obj, url, title, isFolder, parentId); |
+} |
+ |
+static jlong AddBookmarkFromAPI(JNIEnv* env, jobject obj, |
+ jint nativeChromeBrowserProvider, |
+ jstring url, |
+ jobject created, |
+ jobject isBookmark, |
+ jobject date, |
+ jbyteArray favicon, |
+ jstring title, |
+ jobject visits) { |
+ DCHECK(nativeChromeBrowserProvider) << "AddBookmarkFromAPI"; |
+ ChromeBrowserProvider* native = |
+ reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
+ return native->AddBookmarkFromAPI(env, obj, url, created, isBookmark, date, |
+ favicon, title, visits); |
+} |
+ |
+static jobject QueryBookmarkFromAPI(JNIEnv* env, jobject obj, |
+ jint nativeChromeBrowserProvider, |
+ jobjectArray projection, |
+ jstring selection, |
+ jobjectArray selectionArgs, |
+ jstring sortOrder) { |
+ DCHECK(nativeChromeBrowserProvider) << "QueryBookmarkFromAPI"; |
+ ChromeBrowserProvider* native = |
+ reinterpret_cast<ChromeBrowserProvider*>(nativeChromeBrowserProvider); |
+ return native->QueryBookmarkFromAPI(env, obj, projection, selection, |
+ selectionArgs, sortOrder).Release(); |
+} |
+ |
+static void GotOrientation(JNIEnv* env, jobject obj, |
+ jint nativePtr, |
+ jdouble alpha, |
+ jdouble beta, |
+ jdouble gamma) { |
+ DCHECK(nativePtr) << "GotOrientation"; |
+ device_orientation::DeviceOrientationAndroid* native = |
+ reinterpret_cast<device_orientation::DeviceOrientationAndroid*>(nativePtr); |
+ return native->GotOrientation(env, obj, alpha, beta, gamma); |
+} |
+ |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+ |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_TestJni_clazz.Reset( |
+ base::android::GetClass(env, kTestJniClassPath)); |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ GetMethodIDsImpl(env); |
+ |
+ static const JNINativeMethod kMethodsTestJni[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ { "nativeDestroy", |
+"(" |
+"I" |
+")" |
+"V", reinterpret_cast<void*>(Destroy) }, |
+ { "nativeAddBookmark", |
+"(" |
+"I" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"Z" |
+"J" |
+")" |
+"J", reinterpret_cast<void*>(AddBookmark) }, |
+ { "nativeGetDomainAndRegistry", |
+"(" |
+"Ljava/lang/String;" |
+")" |
+"Ljava/lang/String;", reinterpret_cast<void*>(GetDomainAndRegistry) }, |
+ { "nativeCreateHistoricalTabFromState", |
+"(" |
+"[B" |
+"I" |
+")" |
+"V", reinterpret_cast<void*>(CreateHistoricalTabFromState) }, |
+ { "nativeGetStateAsByteArray", |
+"(" |
+"Lorg/chromium/chromeview/ChromeView;" |
+")" |
+"[B", reinterpret_cast<void*>(GetStateAsByteArray) }, |
+ { "nativeGetAutofillProfileGUIDs", |
+"(" |
+")" |
+"[Ljava/lang/String;", reinterpret_cast<void*>(GetAutofillProfileGUIDs) }, |
+ { "nativeSetRecognitionResults", |
+"(" |
+"I" |
+"[Ljava/lang/String;" |
+")" |
+"V", reinterpret_cast<void*>(SetRecognitionResults) }, |
+ { "nativeAddBookmarkFromAPI", |
+"(" |
+"I" |
+"Ljava/lang/String;" |
+"Ljava/lang/Long;" |
+"Ljava/lang/Boolean;" |
+"Ljava/lang/Long;" |
+"[B" |
+"Ljava/lang/String;" |
+"Ljava/lang/Integer;" |
+")" |
+"J", reinterpret_cast<void*>(AddBookmarkFromAPI) }, |
+ { "nativeFindAll", |
+"(" |
+"Ljava/lang/String;" |
+")" |
+"I", reinterpret_cast<void*>(FindAll) }, |
+ { "nativeGetDefaultBookmarkFolder", |
+"(" |
+")" |
+"Lcom/android/chrome/ChromeBrowserProvider$BookmarkNode;", |
+ reinterpret_cast<void*>(GetDefaultBookmarkFolder) }, |
+ { "nativeQueryBookmarkFromAPI", |
+"(" |
+"I" |
+"[Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"[Ljava/lang/String;" |
+"Ljava/lang/String;" |
+")" |
+"Lcom/android/chrome/database/SQLiteCursor;", |
+ reinterpret_cast<void*>(QueryBookmarkFromAPI) }, |
+ { "nativeGotOrientation", |
+"(" |
+"I" |
+"D" |
+"D" |
+"D" |
+")" |
+"V", reinterpret_cast<void*>(GotOrientation) }, |
+ }; |
+ const int kMethodsTestJniSize = arraysize(kMethodsTestJni); |
+ |
+ if (env->RegisterNatives(g_TestJni_clazz.obj(), |
+ kMethodsTestJni, |
+ kMethodsTestJniSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+#endif // org_chromium_TestJni_JNI |
+""" |
+ self.assertTextEquals(golden_content, h.GetContent()) |
+ |
+ def testInnerClassNatives(self): |
+ test_data = """ |
+ class MyInnerClass { |
+ @NativeCall("MyInnerClass") |
+ private native int nativeInit(); |
+ } |
+ """ |
+ natives = jni_generator.ExtractNatives(test_data) |
+ golden_natives = [ |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', params=[], |
+ java_class_name='MyInnerClass', |
+ type='function') |
+ ] |
+ self.assertListEquals(golden_natives, natives) |
+ h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
+ natives, []) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// org/chromium/TestJni |
+ |
+#ifndef org_chromium_TestJni_JNI |
+#define org_chromium_TestJni_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kTestJniClassPath = "org/chromium/TestJni"; |
+const char* const kMyInnerClassClassPath = "org/chromium/TestJni$MyInnerClass"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_TestJni_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+// Step 2: method stubs. |
+ |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+ |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_TestJni_clazz.Reset( |
+ base::android::GetClass(env, kTestJniClassPath)); |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ GetMethodIDsImpl(env); |
+ |
+ static const JNINativeMethod kMethodsMyInnerClass[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ }; |
+ const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); |
+ |
+ if (env->RegisterNatives(g_MyInnerClass_clazz.obj(), |
+ kMethodsMyInnerClass, |
+ kMethodsMyInnerClassSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+#endif // org_chromium_TestJni_JNI |
+""" |
+ self.assertTextEquals(golden_content, h.GetContent()) |
+ |
+ def testInnerClassNativesMultiple(self): |
+ test_data = """ |
+ class MyInnerClass { |
+ @NativeCall("MyInnerClass") |
+ private native int nativeInit(); |
+ } |
+ class MyOtherInnerClass { |
+ @NativeCall("MyOtherInnerClass") |
+ private native int nativeInit(); |
+ } |
+ """ |
+ natives = jni_generator.ExtractNatives(test_data) |
+ golden_natives = [ |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', params=[], |
+ java_class_name='MyInnerClass', |
+ type='function'), |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', params=[], |
+ java_class_name='MyOtherInnerClass', |
+ type='function') |
+ ] |
+ self.assertListEquals(golden_natives, natives) |
+ h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
+ natives, []) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// org/chromium/TestJni |
+ |
+#ifndef org_chromium_TestJni_JNI |
+#define org_chromium_TestJni_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kMyOtherInnerClassClassPath = |
+ "org/chromium/TestJni$MyOtherInnerClass"; |
+const char* const kTestJniClassPath = "org/chromium/TestJni"; |
+const char* const kMyInnerClassClassPath = "org/chromium/TestJni$MyInnerClass"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_TestJni_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+// Step 2: method stubs. |
+ |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+ |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_TestJni_clazz.Reset( |
+ base::android::GetClass(env, kTestJniClassPath)); |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ GetMethodIDsImpl(env); |
+ |
+ static const JNINativeMethod kMethodsMyOtherInnerClass[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ }; |
+ const int kMethodsMyOtherInnerClassSize = |
+ arraysize(kMethodsMyOtherInnerClass); |
+ |
+ if (env->RegisterNatives(g_MyOtherInnerClass_clazz.obj(), |
+ kMethodsMyOtherInnerClass, |
+ kMethodsMyOtherInnerClassSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ static const JNINativeMethod kMethodsMyInnerClass[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ }; |
+ const int kMethodsMyInnerClassSize = arraysize(kMethodsMyInnerClass); |
+ |
+ if (env->RegisterNatives(g_MyInnerClass_clazz.obj(), |
+ kMethodsMyInnerClass, |
+ kMethodsMyInnerClassSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+#endif // org_chromium_TestJni_JNI |
+""" |
+ self.assertTextEquals(golden_content, h.GetContent()) |
+ |
+ def testInnerClassNativesBothInnerAndOuter(self): |
+ test_data = """ |
+ class MyOuterClass { |
+ private native int nativeInit(); |
+ class MyOtherInnerClass { |
+ @NativeCall("MyOtherInnerClass") |
+ private native int nativeInit(); |
+ } |
+ } |
+ """ |
+ natives = jni_generator.ExtractNatives(test_data) |
+ golden_natives = [ |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', params=[], |
+ java_class_name='', |
+ type='function'), |
+ NativeMethod(return_type='int', static=False, |
+ name='Init', params=[], |
+ java_class_name='MyOtherInnerClass', |
+ type='function') |
+ ] |
+ self.assertListEquals(golden_natives, natives) |
+ h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
+ natives, []) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// org/chromium/TestJni |
+ |
+#ifndef org_chromium_TestJni_JNI |
+#define org_chromium_TestJni_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kMyOtherInnerClassClassPath = |
+ "org/chromium/TestJni$MyOtherInnerClass"; |
+const char* const kTestJniClassPath = "org/chromium/TestJni"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_TestJni_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+static jint Init(JNIEnv* env, jobject obj); |
+ |
+ |
+// Step 2: method stubs. |
+ |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+ |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_TestJni_clazz.Reset( |
+ base::android::GetClass(env, kTestJniClassPath)); |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ GetMethodIDsImpl(env); |
+ |
+ static const JNINativeMethod kMethodsMyOtherInnerClass[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ }; |
+ const int kMethodsMyOtherInnerClassSize = |
+ arraysize(kMethodsMyOtherInnerClass); |
+ |
+ if (env->RegisterNatives(g_MyOtherInnerClass_clazz.obj(), |
+ kMethodsMyOtherInnerClass, |
+ kMethodsMyOtherInnerClassSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ static const JNINativeMethod kMethodsTestJni[] = { |
+ { "nativeInit", |
+"(" |
+")" |
+"I", reinterpret_cast<void*>(Init) }, |
+ }; |
+ const int kMethodsTestJniSize = arraysize(kMethodsTestJni); |
+ |
+ if (env->RegisterNatives(g_TestJni_clazz.obj(), |
+ kMethodsTestJni, |
+ kMethodsTestJniSize) < 0) { |
+ LOG(ERROR) << "RegisterNatives failed in " << __FILE__; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+#endif // org_chromium_TestJni_JNI |
+""" |
+ self.assertTextEquals(golden_content, h.GetContent()) |
+ |
+ def testCalledByNatives(self): |
+ test_data = """" |
+ @CalledByNative |
+ NativeInfoBar showConfirmInfoBar(int nativeInfoBar, String buttonOk, |
+ String buttonCancel, String title, |
+ Bitmap icon) { |
+ InfoBar infobar = new ConfirmInfoBar(nativeInfoBar, mContext, |
+ buttonOk, buttonCancel, |
+ title, icon); |
+ return infobar; |
+ } |
+ @CalledByNative |
+ NativeInfoBar showAutoLoginInfoBar(int nativeInfoBar, |
+ String realm, String account, |
+ String args) { |
+ AutoLoginInfoBar infobar = new AutoLoginInfoBar(nativeInfoBar, mContext, |
+ realm, account, args); |
+ if (infobar.displayedAccountCount() == 0) |
+ infobar = null; |
+ return infobar; |
+ } |
+ @CalledByNative("InfoBar") |
+ void dismiss(); |
+ @SuppressWarnings("unused") |
+ @CalledByNative |
+ private static boolean shouldShowAutoLogin(ChromeView chromeView, |
+ String realm, String account, String args) { |
+ AccountManagerContainer accountManagerContainer = |
+ new AccountManagerContainer((Activity)chromeView.getContext(), |
+ realm, account, args); |
+ String[] logins = accountManagerContainer.getAccountLogins(null); |
+ return logins.length != 0; |
+ } |
+ @CalledByNative |
+ static InputStream openUrl(String url) { |
+ return null; |
+ } |
+ @CalledByNative |
+ private void activateHardwareAcceleration(final boolean activated, |
+ final int iPid, final int iType, |
+ final int iPrimaryID, final int iSecondaryID) { |
+ if (!activated) { |
+ return |
+ } |
+ } |
+ @CalledByNativeUnchecked |
+ private void uncheckedCall(int iParam); |
+ """ |
+ called_by_natives = jni_generator.ExtractCalledByNatives(test_data) |
+ golden_called_by_natives = [ |
+ CalledByNative( |
+ return_type='NativeInfoBar', |
+ system_class=False, |
+ static=False, |
+ name='showConfirmInfoBar', |
+ method_id_var_name='showConfirmInfoBar', |
+ java_class_name='', |
+ params=[Param(datatype='int', name='nativeInfoBar'), |
+ Param(datatype='String', name='buttonOk'), |
+ Param(datatype='String', name='buttonCancel'), |
+ Param(datatype='String', name='title'), |
+ Param(datatype='Bitmap', name='icon')], |
+ env_call=('Object', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='NativeInfoBar', |
+ system_class=False, |
+ static=False, |
+ name='showAutoLoginInfoBar', |
+ method_id_var_name='showAutoLoginInfoBar', |
+ java_class_name='', |
+ params=[Param(datatype='int', name='nativeInfoBar'), |
+ Param(datatype='String', name='realm'), |
+ Param(datatype='String', name='account'), |
+ Param(datatype='String', name='args')], |
+ env_call=('Object', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='void', |
+ system_class=False, |
+ static=False, |
+ name='dismiss', |
+ method_id_var_name='dismiss', |
+ java_class_name='InfoBar', |
+ params=[], |
+ env_call=('Void', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='boolean', |
+ system_class=False, |
+ static=True, |
+ name='shouldShowAutoLogin', |
+ method_id_var_name='shouldShowAutoLogin', |
+ java_class_name='', |
+ params=[Param(datatype='ChromeView', name='chromeView'), |
+ Param(datatype='String', name='realm'), |
+ Param(datatype='String', name='account'), |
+ Param(datatype='String', name='args')], |
+ env_call=('Boolean', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='InputStream', |
+ system_class=False, |
+ static=True, |
+ name='openUrl', |
+ method_id_var_name='openUrl', |
+ java_class_name='', |
+ params=[Param(datatype='String', name='url')], |
+ env_call=('Object', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='void', |
+ system_class=False, |
+ static=False, |
+ name='activateHardwareAcceleration', |
+ method_id_var_name='activateHardwareAcceleration', |
+ java_class_name='', |
+ params=[Param(datatype='boolean', name='activated'), |
+ Param(datatype='int', name='iPid'), |
+ Param(datatype='int', name='iType'), |
+ Param(datatype='int', name='iPrimaryID'), |
+ Param(datatype='int', name='iSecondaryID'), |
+ ], |
+ env_call=('Void', ''), |
+ unchecked=False, |
+ ), |
+ CalledByNative( |
+ return_type='void', |
+ system_class=False, |
+ static=False, |
+ name='uncheckedCall', |
+ method_id_var_name='uncheckedCall', |
+ java_class_name='', |
+ params=[Param(datatype='int', name='iParam')], |
+ env_call=('Void', ''), |
+ unchecked=True, |
+ ), |
+ ] |
+ self.assertListEquals(golden_called_by_natives, called_by_natives) |
+ h = jni_generator.InlHeaderFileGenerator('', 'org/chromium/TestJni', |
+ [], called_by_natives) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// org/chromium/TestJni |
+ |
+#ifndef org_chromium_TestJni_JNI |
+#define org_chromium_TestJni_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kTestJniClassPath = "org/chromium/TestJni"; |
+const char* const kInfoBarClassPath = "org/chromium/TestJni$InfoBar"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_TestJni_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_InfoBar_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+ |
+// Step 2: method stubs. |
+ |
+static jmethodID g_TestJni_showConfirmInfoBar = 0; |
+static ScopedJavaLocalRef<jobject> Java_TestJni_showConfirmInfoBar(JNIEnv* env, |
+ jobject obj, jint nativeInfoBar, |
+ jstring buttonOk, |
+ jstring buttonCancel, |
+ jstring title, |
+ jobject icon) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_showConfirmInfoBar); |
+ jobject ret = |
+ env->CallObjectMethod(obj, |
+ g_TestJni_showConfirmInfoBar, nativeInfoBar, buttonOk, buttonCancel, |
+ title, icon); |
+ base::android::CheckException(env); |
+ return ScopedJavaLocalRef<jobject>(env, ret); |
+} |
+ |
+static jmethodID g_TestJni_showAutoLoginInfoBar = 0; |
+static ScopedJavaLocalRef<jobject> Java_TestJni_showAutoLoginInfoBar(JNIEnv* |
+ env, jobject obj, jint nativeInfoBar, |
+ jstring realm, |
+ jstring account, |
+ jstring args) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_showAutoLoginInfoBar); |
+ jobject ret = |
+ env->CallObjectMethod(obj, |
+ g_TestJni_showAutoLoginInfoBar, nativeInfoBar, realm, account, args); |
+ base::android::CheckException(env); |
+ return ScopedJavaLocalRef<jobject>(env, ret); |
+} |
+ |
+static jmethodID g_InfoBar_dismiss = 0; |
+static void Java_InfoBar_dismiss(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InfoBar_clazz.is_null()); |
+ DCHECK(g_InfoBar_dismiss); |
+ |
+ env->CallVoidMethod(obj, |
+ g_InfoBar_dismiss); |
+ base::android::CheckException(env); |
+ |
+} |
+ |
+static jmethodID g_TestJni_shouldShowAutoLogin = 0; |
+static jboolean Java_TestJni_shouldShowAutoLogin(JNIEnv* env, jobject |
+ chromeView, |
+ jstring realm, |
+ jstring account, |
+ jstring args) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_shouldShowAutoLogin); |
+ jboolean ret = |
+ env->CallStaticBooleanMethod(g_TestJni_clazz.obj(), |
+ g_TestJni_shouldShowAutoLogin, chromeView, realm, account, args); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_TestJni_openUrl = 0; |
+static ScopedJavaLocalRef<jobject> Java_TestJni_openUrl(JNIEnv* env, jstring |
+ url) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_openUrl); |
+ jobject ret = |
+ env->CallStaticObjectMethod(g_TestJni_clazz.obj(), |
+ g_TestJni_openUrl, url); |
+ base::android::CheckException(env); |
+ return ScopedJavaLocalRef<jobject>(env, ret); |
+} |
+ |
+static jmethodID g_TestJni_activateHardwareAcceleration = 0; |
+static void Java_TestJni_activateHardwareAcceleration(JNIEnv* env, jobject obj, |
+ jboolean activated, |
+ jint iPid, |
+ jint iType, |
+ jint iPrimaryID, |
+ jint iSecondaryID) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_activateHardwareAcceleration); |
+ |
+ env->CallVoidMethod(obj, |
+ g_TestJni_activateHardwareAcceleration, activated, iPid, iType, |
+ iPrimaryID, iSecondaryID); |
+ base::android::CheckException(env); |
+ |
+} |
+ |
+static jmethodID g_TestJni_uncheckedCall = 0; |
+static void Java_TestJni_uncheckedCall(JNIEnv* env, jobject obj, jint iParam) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_TestJni_clazz.is_null()); |
+ DCHECK(g_TestJni_uncheckedCall); |
+ |
+ env->CallVoidMethod(obj, |
+ g_TestJni_uncheckedCall, iParam); |
+ |
+ |
+} |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+ |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_TestJni_clazz.Reset( |
+ base::android::GetClass(env, kTestJniClassPath)); |
+ g_InfoBar_clazz.Reset( |
+ base::android::GetClass(env, kInfoBarClassPath)); |
+ g_TestJni_showConfirmInfoBar = base::android::GetMethodID( |
+ env, g_TestJni_clazz, |
+ "showConfirmInfoBar", |
+ |
+"(" |
+"I" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"Landroid/graphics/Bitmap;" |
+")" |
+"Lcom/android/chrome/infobar/InfoBarContainer$NativeInfoBar;"); |
+ |
+ g_TestJni_showAutoLoginInfoBar = base::android::GetMethodID( |
+ env, g_TestJni_clazz, |
+ "showAutoLoginInfoBar", |
+ |
+"(" |
+"I" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+")" |
+"Lcom/android/chrome/infobar/InfoBarContainer$NativeInfoBar;"); |
+ |
+ g_InfoBar_dismiss = base::android::GetMethodID( |
+ env, g_InfoBar_clazz, |
+ "dismiss", |
+ |
+"(" |
+")" |
+"V"); |
+ |
+ g_TestJni_shouldShowAutoLogin = base::android::GetStaticMethodID( |
+ env, g_TestJni_clazz, |
+ "shouldShowAutoLogin", |
+ |
+"(" |
+"Lorg/chromium/chromeview/ChromeView;" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+"Ljava/lang/String;" |
+")" |
+"Z"); |
+ |
+ g_TestJni_openUrl = base::android::GetStaticMethodID( |
+ env, g_TestJni_clazz, |
+ "openUrl", |
+ |
+"(" |
+"Ljava/lang/String;" |
+")" |
+"Ljava/io/InputStream;"); |
+ |
+ g_TestJni_activateHardwareAcceleration = base::android::GetMethodID( |
+ env, g_TestJni_clazz, |
+ "activateHardwareAcceleration", |
+ |
+"(" |
+"Z" |
+"I" |
+"I" |
+"I" |
+"I" |
+")" |
+"V"); |
+ |
+ g_TestJni_uncheckedCall = base::android::GetMethodID( |
+ env, g_TestJni_clazz, |
+ "uncheckedCall", |
+ |
+"(" |
+"I" |
+")" |
+"V"); |
+ |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ GetMethodIDsImpl(env); |
+ |
+ return true; |
+} |
+ |
+#endif // org_chromium_TestJni_JNI |
+""" |
+ self.assertTextEquals(golden_content, h.GetContent()) |
+ |
+ def testCalledByNativeParseError(self): |
+ try: |
+ jni_generator.ExtractCalledByNatives(""" |
+@CalledByNative |
+public static int foo(); // This one is fine |
+ |
+@CalledByNative |
+scooby doo |
+""") |
+ self.fail('Expected a ParseError') |
+ except jni_generator.ParseError, e: |
+ self.assertEquals(('@CalledByNative', 'scooby doo'), e.context_lines) |
+ |
+ def testFullyQualifiedClassName(self): |
+ contents = """ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chromeview; |
+ |
+import org.chromium.chromeview.legacy.DownloadListener; |
+""" |
+ self.assertEquals('org/chromium/chromeview/Foo', |
+ jni_generator.ExtractFullyQualifiedJavaClassName( |
+ 'org/chromium/chromeview/Foo.java', contents)) |
+ self.assertEquals('org/chromium/chromeview/Foo', |
+ jni_generator.ExtractFullyQualifiedJavaClassName( |
+ 'frameworks/Foo.java', contents)) |
+ self.assertRaises(SyntaxError, |
+ jni_generator.ExtractFullyQualifiedJavaClassName, |
+ 'com/foo/Bar', 'no PACKAGE line') |
+ |
+ def testMethodNameMangling(self): |
+ self.assertEquals('close_pqV', |
+ jni_generator.GetMangledMethodName('close', '()V')) |
+ self.assertEquals('read_paBIIqI', |
+ jni_generator.GetMangledMethodName('read', '([BII)I')) |
+ self.assertEquals('open_pLjava_lang_StringxqLjava_io_InputStreamx', |
+ jni_generator.GetMangledMethodName( |
+ 'open', |
+ '(Ljava/lang/String;)Ljava/io/InputStream;')) |
+ |
+ def testFromJavaP(self): |
+ contents = """ |
+public abstract class java.io.InputStream extends java.lang.Object |
+ implements java.io.Closeable{ |
+ public java.io.InputStream(); |
+ public int available() throws java.io.IOException; |
+ public void close() throws java.io.IOException; |
+ public void mark(int); |
+ public boolean markSupported(); |
+ public abstract int read() throws java.io.IOException; |
+ public int read(byte[]) throws java.io.IOException; |
+ public int read(byte[], int, int) throws java.io.IOException; |
+ public synchronized void reset() throws java.io.IOException; |
+ public long skip(long) throws java.io.IOException; |
+} |
+""" |
+ jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'), None) |
+ self.assertEquals(9, len(jni_from_javap.called_by_natives)) |
+ golden_content = """\ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+ |
+// This file is autogenerated by |
+// base/android/jni_generator/jni_generator_tests.py |
+// For |
+// java/io/InputStream |
+ |
+#ifndef java_io_InputStream_JNI |
+#define java_io_InputStream_JNI |
+ |
+#include <jni.h> |
+ |
+#include "base/android/jni_android.h" |
+#include "base/android/scoped_java_ref.h" |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+ |
+using base::android::ScopedJavaLocalRef; |
+ |
+// Step 1: forward declarations. |
+namespace { |
+const char* const kInputStreamClassPath = "java/io/InputStream"; |
+// Leaking this JavaRef as we cannot use LazyInstance from some threads. |
+base::android::ScopedJavaGlobalRef<jclass>& |
+ g_InputStream_clazz = |
+ *(new base::android::ScopedJavaGlobalRef<jclass>()); |
+} // namespace |
+ |
+ |
+// Step 2: method stubs. |
+ |
+static jmethodID g_InputStream_available = 0; |
+static jint Java_InputStream_available(JNIEnv* env, jobject obj) __attribute__ |
+ ((unused)); |
+static jint Java_InputStream_available(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_available); |
+ jint ret = |
+ env->CallIntMethod(obj, |
+ g_InputStream_available); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_InputStream_close = 0; |
+static void Java_InputStream_close(JNIEnv* env, jobject obj) __attribute__ |
+ ((unused)); |
+static void Java_InputStream_close(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_close); |
+ |
+ env->CallVoidMethod(obj, |
+ g_InputStream_close); |
+ base::android::CheckException(env); |
+ |
+} |
+ |
+static jmethodID g_InputStream_mark = 0; |
+static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) |
+ __attribute__ ((unused)); |
+static void Java_InputStream_mark(JNIEnv* env, jobject obj, jint p0) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_mark); |
+ |
+ env->CallVoidMethod(obj, |
+ g_InputStream_mark, p0); |
+ base::android::CheckException(env); |
+ |
+} |
+ |
+static jmethodID g_InputStream_markSupported = 0; |
+static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) |
+ __attribute__ ((unused)); |
+static jboolean Java_InputStream_markSupported(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_markSupported); |
+ jboolean ret = |
+ env->CallBooleanMethod(obj, |
+ g_InputStream_markSupported); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_InputStream_read_pqI = 0; |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj) __attribute__ |
+ ((unused)); |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_read_pqI); |
+ jint ret = |
+ env->CallIntMethod(obj, |
+ g_InputStream_read_pqI); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_InputStream_read_paBqI = 0; |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0) |
+ __attribute__ ((unused)); |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_read_paBqI); |
+ jint ret = |
+ env->CallIntMethod(obj, |
+ g_InputStream_read_paBqI, p0); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_InputStream_read_paBIIqI = 0; |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0, |
+ jint p1, |
+ jint p2) __attribute__ ((unused)); |
+static jint Java_InputStream_read(JNIEnv* env, jobject obj, jbyteArray p0, |
+ jint p1, |
+ jint p2) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_read_paBIIqI); |
+ jint ret = |
+ env->CallIntMethod(obj, |
+ g_InputStream_read_paBIIqI, p0, p1, p2); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+static jmethodID g_InputStream_reset = 0; |
+static void Java_InputStream_reset(JNIEnv* env, jobject obj) __attribute__ |
+ ((unused)); |
+static void Java_InputStream_reset(JNIEnv* env, jobject obj) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_reset); |
+ |
+ env->CallVoidMethod(obj, |
+ g_InputStream_reset); |
+ base::android::CheckException(env); |
+ |
+} |
+ |
+static jmethodID g_InputStream_skip = 0; |
+static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) |
+ __attribute__ ((unused)); |
+static jlong Java_InputStream_skip(JNIEnv* env, jobject obj, jlong p0) { |
+ /* Must call RegisterNativesImpl() */ |
+ DCHECK(!g_InputStream_clazz.is_null()); |
+ DCHECK(g_InputStream_skip); |
+ jlong ret = |
+ env->CallLongMethod(obj, |
+ g_InputStream_skip, p0); |
+ base::android::CheckException(env); |
+ return ret; |
+} |
+ |
+// Step 3: GetMethodIDs and RegisterNatives. |
+namespace JNI_InputStream { |
+ |
+static void GetMethodIDsImpl(JNIEnv* env) { |
+ g_InputStream_clazz.Reset( |
+ base::android::GetClass(env, kInputStreamClassPath)); |
+ g_InputStream_available = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "available", |
+ |
+"(" |
+")" |
+"I"); |
+ |
+ g_InputStream_close = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "close", |
+ |
+"(" |
+")" |
+"V"); |
+ |
+ g_InputStream_mark = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "mark", |
+ |
+"(" |
+"I" |
+")" |
+"V"); |
+ |
+ g_InputStream_markSupported = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "markSupported", |
+ |
+"(" |
+")" |
+"Z"); |
+ |
+ g_InputStream_read_pqI = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "read", |
+ |
+"(" |
+")" |
+"I"); |
+ |
+ g_InputStream_read_paBqI = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "read", |
+ |
+"(" |
+"[B" |
+")" |
+"I"); |
+ |
+ g_InputStream_read_paBIIqI = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "read", |
+ |
+"(" |
+"[B" |
+"I" |
+"I" |
+")" |
+"I"); |
+ |
+ g_InputStream_reset = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "reset", |
+ |
+"(" |
+")" |
+"V"); |
+ |
+ g_InputStream_skip = base::android::GetMethodID( |
+ env, g_InputStream_clazz, |
+ "skip", |
+ |
+"(" |
+"J" |
+")" |
+"J"); |
+ |
+} |
+ |
+static bool RegisterNativesImpl(JNIEnv* env) { |
+ JNI_InputStream::GetMethodIDsImpl(env); |
+ |
+ return true; |
+} |
+} // namespace JNI_InputStream |
+ |
+#endif // java_io_InputStream_JNI |
+""" |
+ self.assertTextEquals(golden_content, jni_from_javap.GetContent()) |
+ |
+ def testREForNatives(self): |
+ # We should not match "native SyncSetupFlow" inside the comment. |
+ test_data = """ |
+ /** |
+ * Invoked when the setup process is complete so we can disconnect from the |
+ * native-side SyncSetupFlowHandler. |
+ */ |
+ public void destroy() { |
+ Log.v(TAG, "Destroying native SyncSetupFlow"); |
+ if (mNativeSyncSetupFlow != 0) { |
+ nativeSyncSetupEnded(mNativeSyncSetupFlow); |
+ mNativeSyncSetupFlow = 0; |
+ } |
+ } |
+ private native void nativeSyncSetupEnded( |
+ int nativeAndroidSyncSetupFlowHandler); |
+ """ |
+ jni_from_java = jni_generator.JNIFromJavaSource(test_data, 'foo/bar') |
+ |
+ def testRaisesOnUnknownDatatype(self): |
+ test_data = """ |
+ class MyInnerClass { |
+ private native int nativeInit(AnUnknownDatatype p0); |
+ } |
+ """ |
+ self.assertRaises(SyntaxError, |
+ jni_generator.JNIFromJavaSource, |
+ test_data, 'foo/bar') |
+ |
+ def testJniSelfDocumentingExample(self): |
+ script_dir = os.path.dirname(sys.argv[0]) |
+ content = file(os.path.join(script_dir, 'SampleForTests.java')).read() |
+ golden_content = file(os.path.join(script_dir, |
+ 'golden_sample_for_tests_jni.h')).read() |
+ jni_from_java = jni_generator.JNIFromJavaSource( |
+ content, 'org/chromium/example/jni_generator/SampleForTests') |
+ self.assertTextEquals(golden_content, jni_from_java.GetContent()) |
+ |
+ def testCheckFilenames(self): |
+ self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
+ ['more', 'input', 'than'], ['output']) |
+ self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
+ ['more'], ['output', 'than', 'input']) |
+ self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
+ ['NotTheSame.java'], ['not_good.h']) |
+ self.assertRaises(SystemExit, jni_generator.CheckFilenames, |
+ ['MissingJniSuffix.java'], ['missing_jni_suffix.h']) |
+ jni_generator.CheckFilenames(['ThisIsFine.java'], ['this_is_fine_jni.h']) |
+ jni_generator.CheckFilenames([], []) |
+ |
+ |
+if __name__ == '__main__': |
+ unittest.main() |