Fix JNI generator handling of generics.

Instead of hardcoding startswith('Class') to try to deal with generics
(which doesn't work when disassembling a class file as the type is
java.lang.Class there), just use the existing _StripGenerics function to
remove generics from types before converting them to C types.

Bug: 787557
Change-Id: Iae2b760bcb8f1407e1e13ba9d692cd463a5a3ad2
Reviewed-on: https://chromium-review.googlesource.com/922501
Reviewed-by: agrieve <agrieve@chromium.org>
Commit-Queue: Richard Coles <torne@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537096}

CrOS-Libchrome-Original-Commit: 1257be13887e153bc570c0a3de05e743c651c8a2
diff --git a/base/android/jni_generator/jni_generator.py b/base/android/jni_generator/jni_generator.py
index 7a9494d..0e2b73d 100755
--- a/base/android/jni_generator/jni_generator.py
+++ b/base/android/jni_generator/jni_generator.py
@@ -127,12 +127,14 @@
   java_type_map = {
       'void': 'void',
       'String': 'jstring',
+      'Class': 'jclass',
       'Throwable': 'jthrowable',
       'java/lang/String': 'jstring',
       'java/lang/Class': 'jclass',
       'java/lang/Throwable': 'jthrowable',
   }
 
+  java_type = _StripGenerics(java_type)
   if java_type in java_pod_type_map:
     return java_pod_type_map[java_type]
   elif java_type in java_type_map:
@@ -141,10 +143,6 @@
     if java_type[:-2] in java_pod_type_map:
       return java_pod_type_map[java_type[:-2]] + 'Array'
     return 'jobjectArray'
-  elif java_type.startswith('Class'):
-    # Checking just the start of the name, rather than a direct comparison,
-    # in order to handle generics.
-    return 'jclass'
   else:
     return 'jobject'
 
@@ -497,6 +495,8 @@
 def GetStaticCastForReturnType(return_type):
   type_map = { 'String' : 'jstring',
                'java/lang/String' : 'jstring',
+               'Class': 'jclass',
+               'java/lang/Class': 'jclass',
                'Throwable': 'jthrowable',
                'java/lang/Throwable': 'jthrowable',
                'boolean[]': 'jbooleanArray',
@@ -507,6 +507,7 @@
                'long[]': 'jlongArray',
                'float[]': 'jfloatArray',
                'double[]': 'jdoubleArray' }
+  return_type = _StripGenerics(return_type)
   ret = type_map.get(return_type, None)
   if ret:
     return ret
diff --git a/base/android/jni_generator/jni_generator_tests.py b/base/android/jni_generator/jni_generator_tests.py
index c406f87..0e9d363 100755
--- a/base/android/jni_generator/jni_generator_tests.py
+++ b/base/android/jni_generator/jni_generator_tests.py
@@ -767,12 +767,14 @@
 public abstract class java.util.HashSet<T> extends java.util.AbstractSet<E>
       implements java.util.Set<E>, java.lang.Cloneable, java.io.Serializable {
     public void dummy();
-  Signature: ()V
+      Signature: ()V
+    public java.lang.Class<?> getClass();
+      Signature: ()Ljava/lang/Class<*>;
 }
 """
     jni_from_javap = jni_generator.JNIFromJavaP(contents.split('\n'),
                                                 TestOptions())
-    self.assertEquals(1, len(jni_from_javap.called_by_natives))
+    self.assertEquals(2, len(jni_from_javap.called_by_natives))
     self.assertGoldenTextEquals(jni_from_javap.GetContent())
 
   def testSnippnetJavap6_7_8(self):
diff --git a/base/android/jni_generator/testFromJavaPGenerics.golden b/base/android/jni_generator/testFromJavaPGenerics.golden
index 158d1de..386f83c 100644
--- a/base/android/jni_generator/testFromJavaPGenerics.golden
+++ b/base/android/jni_generator/testFromJavaPGenerics.golden
@@ -52,6 +52,28 @@
   jni_generator::CheckException(env);
 }
 
+static base::subtle::AtomicWord g_java_util_HashSet_getClass = 0;
+static base::android::ScopedJavaLocalRef<jclass> Java_HashSet_getClass(JNIEnv*
+    env, const base::android::JavaRef<jobject>& obj) __attribute__ ((unused));
+static base::android::ScopedJavaLocalRef<jclass> Java_HashSet_getClass(JNIEnv*
+    env, const base::android::JavaRef<jobject>& obj) {
+  CHECK_CLAZZ(env, obj.obj(),
+      java_util_HashSet_clazz(env), NULL);
+  jmethodID method_id =
+      base::android::MethodID::LazyGet<
+      base::android::MethodID::TYPE_INSTANCE>(
+      env, java_util_HashSet_clazz(env),
+      "getClass",
+      "()Ljava/lang/Class<*>;",
+      &g_java_util_HashSet_getClass);
+
+  jclass ret =
+      static_cast<jclass>(env->CallObjectMethod(obj.obj(),
+          method_id));
+  jni_generator::CheckException(env);
+  return base::android::ScopedJavaLocalRef<jclass>(env, ret);
+}
+
 }  // namespace JNI_HashSet
 
 #endif  // java_util_HashSet_JNI