Use Integer.valueOf rather than "new Integer" (et cetera) from JNI.

Also factor it out rather than keep duplicating it.

Change-Id: I6349668f4676f1e0a7dd6fdc101dd1784c5465fb
diff --git a/luni/src/main/native/ICU.cpp b/luni/src/main/native/ICU.cpp
index 6d60053..329b494 100644
--- a/luni/src/main/native/ICU.cpp
+++ b/luni/src/main/native/ICU.cpp
@@ -16,31 +16,32 @@
 
 #define LOG_TAG "ICU"
 
+#include "ErrorCode.h"
 #include "JNIHelp.h"
 #include "ScopedLocalRef.h"
 #include "ScopedUtfChars.h"
 #include "UniquePtr.h"
 #include "cutils/log.h"
-#include "unicode/numfmt.h"
-#include "unicode/locid.h"
-#include "unicode/ubrk.h"
-#include "unicode/ucal.h"
-#include "unicode/ucol.h"
-#include "unicode/udat.h"
-#include "unicode/gregocal.h"
-#include "unicode/ucurr.h"
 #include "unicode/calendar.h"
 #include "unicode/datefmt.h"
-#include "unicode/dtfmtsym.h"
-#include "unicode/decimfmt.h"
 #include "unicode/dcfmtsym.h"
-#include "unicode/uclean.h"
+#include "unicode/decimfmt.h"
+#include "unicode/dtfmtsym.h"
+#include "unicode/gregocal.h"
+#include "unicode/locid.h"
+#include "unicode/numfmt.h"
 #include "unicode/smpdtfmt.h"
 #include "unicode/strenum.h"
-#include "unicode/ustring.h"
 #include "unicode/timezone.h"
+#include "unicode/ubrk.h"
+#include "unicode/ucal.h"
+#include "unicode/uclean.h"
+#include "unicode/ucol.h"
+#include "unicode/ucurr.h"
+#include "unicode/udat.h"
+#include "unicode/ustring.h"
 #include "ureslocs.h"
-#include "ErrorCode.h"
+#include "valueOf.h"
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
@@ -465,15 +466,10 @@
 }
 
 static void setIntegerField(JNIEnv* env, jobject obj, const char* fieldName, int value) {
-    // Convert our int to a java.lang.Integer.
-    // TODO: switch to Integer.valueOf, add error checking.
-    jclass integerClass = env->FindClass("java/lang/Integer");
-    jmethodID constructor = env->GetMethodID(integerClass, "<init>", "(I)V");
-    jobject integerValue = env->NewObject(integerClass, constructor, value);
-    // Set the field.
+    ScopedLocalRef<jobject> integerValue(env, integerValueOf(env, value));
     jclass localeDataClass = env->FindClass("com/ibm/icu4jni/util/LocaleData");
     jfieldID fid = env->GetFieldID(localeDataClass, fieldName, "Ljava/lang/Integer;");
-    env->SetObjectField(obj, fid, integerValue);
+    env->SetObjectField(obj, fid, integerValue.get());
 }
 
 static void setStringField(JNIEnv* env, jobject obj, const char* fieldName, jstring value) {
diff --git a/luni/src/main/native/NativeDecimalFormat.cpp b/luni/src/main/native/NativeDecimalFormat.cpp
index 2f1d344..759a271 100644
--- a/luni/src/main/native/NativeDecimalFormat.cpp
+++ b/luni/src/main/native/NativeDecimalFormat.cpp
@@ -15,18 +15,20 @@
  */
 
 #define LOG_TAG "NativeDecimalFormat"
-#include "JNIHelp.h"
-#include "cutils/log.h"
-#include "unicode/unum.h"
-#include "unicode/numfmt.h"
-#include "unicode/decimfmt.h"
-#include "unicode/fmtable.h"
-#include "unicode/ustring.h"
-#include "digitlst.h"
+
 #include "ErrorCode.h"
+#include "JNIHelp.h"
 #include "ScopedJavaUnicodeString.h"
 #include "ScopedPrimitiveArray.h"
 #include "ScopedUtfChars.h"
+#include "cutils/log.h"
+#include "digitlst.h"
+#include "unicode/decimfmt.h"
+#include "unicode/fmtable.h"
+#include "unicode/numfmt.h"
+#include "unicode/unum.h"
+#include "unicode/ustring.h"
+#include "valueOf.h"
 #include <stdlib.h>
 #include <string.h>
 
@@ -276,18 +278,6 @@
     return format(env, addr, fpIter, sp);
 }
 
-static jobject newLong(JNIEnv* env, jlong value) {
-    static jclass gLongClass = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Long"));
-    static jmethodID gLong_init = env->GetMethodID(gLongClass, "<init>", "(J)V");
-    return env->NewObject(gLongClass, gLong_init, value);
-}
-
-static jobject newDouble(JNIEnv* env, jdouble value) {
-    static jclass gDoubleClass = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Double"));
-    static jmethodID gDouble_init = env->GetMethodID(gDoubleClass, "<init>", "(D)V");
-    return env->NewObject(gDoubleClass, gDouble_init, value);
-}
-
 static jobject newBigDecimal(JNIEnv* env, const char* value, jsize len) {
     static jclass gBigDecimalClass = (jclass) env->NewGlobalRef(env->FindClass("java/math/BigDecimal"));
     static jmethodID gBigDecimal_init = env->GetMethodID(gBigDecimalClass, "<init>", "(Ljava/lang/String;)V");
@@ -347,7 +337,7 @@
                 strncmp(data, "Inf", 3) == 0 ||
                 strncmp(data, "-Inf", 4) == 0) {
                 double resultDouble = res.getDouble(status);
-                return newDouble(env, (jdouble) resultDouble);
+                return doubleValueOf(env, (jdouble) resultDouble);
             }
             return newBigDecimal(env, data, len);
         }
@@ -358,15 +348,15 @@
         switch(numType) {
         case Formattable::kDouble: {
             double resultDouble = res.getDouble();
-            return newDouble(env, (jdouble) resultDouble);
+            return doubleValueOf(env, (jdouble) resultDouble);
         }
         case Formattable::kLong: {
             long resultLong = res.getLong();
-            return newLong(env, (jlong) resultLong);
+            return longValueOf(env, (jlong) resultLong);
         }
         case Formattable::kInt64: {
             int64_t resultInt64 = res.getInt64();
-            return newLong(env, (jlong) resultInt64);
+            return longValueOf(env, (jlong) resultInt64);
         }
         default: {
             return NULL;
diff --git a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
index c9fa21a..b03f374 100644
--- a/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
+++ b/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.cpp
@@ -28,6 +28,7 @@
 #include "NetworkUtilities.h"
 #include "ScopedPrimitiveArray.h"
 #include "jni.h"
+#include "valueOf.h"
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -97,14 +98,11 @@
     jfieldID fd_descriptor;
     jclass iaddr_class;
     jclass i4addr_class;
-    jmethodID i4addr_class_init;
     jfieldID iaddr_ipaddress;
     jclass genericipmreq_class;
     jclass integer_class;
-    jmethodID integer_class_init;
     jfieldID integer_class_value;
     jclass boolean_class;
-    jmethodID boolean_class_init;
     jfieldID boolean_class_value;
     jclass byte_class;
     jfieldID byte_class_value;
@@ -279,35 +277,6 @@
     return byteArrayToSocketAddress(env, NULL, addressBytes, port, sockaddress);
 }
 
-/**
- * Answer a new java.lang.Boolean object.
- *
- * @param env   pointer to the JNI library
- * @param anInt the Boolean constructor argument
- *
- * @return  the new Boolean
- */
-static jobject newJavaLangBoolean(JNIEnv * env, jint anInt) {
-    jclass tempClass;
-    jmethodID tempMethod;
-
-    tempClass = gCachedFields.boolean_class;
-    tempMethod = gCachedFields.boolean_class_init;
-    return env->NewObject(tempClass, tempMethod, (jboolean) (anInt != 0));
-}
-
-/**
- * Answer a new java.lang.Integer object.
- *
- * @param env   pointer to the JNI library
- * @param anInt the Integer constructor argument
- *
- * @return  the new Integer
- */
-static jobject newJavaLangInteger(JNIEnv* env, jint anInt) {
-    return env->NewObject(gCachedFields.integer_class, gCachedFields.integer_class_init, anInt);
-}
-
 // Converts a number of milliseconds to a timeval.
 static timeval toTimeval(long ms) {
     timeval tv;
@@ -763,27 +732,6 @@
         *c.clazz = (jclass) env->NewGlobalRef(tempClass);
     }
 
-    struct methodInfo {
-        jmethodID *method;
-        jclass clazz;
-        const char *name;
-        const char *signature;
-        bool isStatic;
-    } methods[] = {
-        {&c->i4addr_class_init, c->i4addr_class, "<init>", "([B)V", false},
-        {&c->integer_class_init, c->integer_class, "<init>", "(I)V", false},
-        {&c->boolean_class_init, c->boolean_class, "<init>", "(Z)V", false},
-    };
-    for (unsigned i = 0; i < sizeof(methods) / sizeof(methods[0]); i++) {
-        methodInfo m = methods[i];
-        if (m.isStatic) {
-            *m.method = env->GetStaticMethodID(m.clazz, m.name, m.signature);
-        } else {
-            *m.method = env->GetMethodID(m.clazz, m.name, m.signature);
-        }
-        if (*m.method == NULL) return false;
-    }
-
     struct fieldInfo {
         jfieldID *field;
         jclass clazz;
@@ -1672,12 +1620,12 @@
 
 static jobject getSocketOption_Boolean(JNIEnv* env, int fd, int level, int option) {
     int value;
-    return getSocketOption(env, fd, level, option, &value) ? newJavaLangBoolean(env, value) : NULL;
+    return getSocketOption(env, fd, level, option, &value) ? booleanValueOf(env, value) : NULL;
 }
 
 static jobject getSocketOption_Integer(JNIEnv* env, int fd, int level, int option) {
     int value;
-    return getSocketOption(env, fd, level, option, &value) ? newJavaLangInteger(env, value) : NULL;
+    return getSocketOption(env, fd, level, option, &value) ? integerValueOf(env, value) : NULL;
 }
 
 static jobject osNetworkSystem_getSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option) {
@@ -1717,13 +1665,13 @@
         {
             linger lingr;
             bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &lingr);
-            return ok ? newJavaLangInteger(env, !lingr.l_onoff ? -1 : lingr.l_linger) : NULL;
+            return ok ? integerValueOf(env, !lingr.l_onoff ? -1 : lingr.l_linger) : NULL;
         }
     case JAVASOCKOPT_SO_RCVTIMEOUT:
         {
             timeval timeout;
             bool ok = getSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout);
-            return ok ? newJavaLangInteger(env, toMs(timeout)) : NULL;
+            return ok ? integerValueOf(env, toMs(timeout)) : NULL;
         }
 #ifdef ENABLE_MULTICAST
     case JAVASOCKOPT_IP_MULTICAST_IF:
@@ -1744,7 +1692,7 @@
         if (family == AF_INET) {
             struct ip_mreqn multicastRequest;
             bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &multicastRequest);
-            return ok ? newJavaLangInteger(env, multicastRequest.imr_ifindex) : NULL;
+            return ok ? integerValueOf(env, multicastRequest.imr_ifindex) : NULL;
         } else {
             return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF);
         }
@@ -1753,7 +1701,7 @@
             // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
             u_char loopback;
             bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback);
-            return ok ? newJavaLangBoolean(env, loopback) : NULL;
+            return ok ? booleanValueOf(env, loopback) : NULL;
         } else {
             return getSocketOption_Boolean(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP);
         }
@@ -1763,7 +1711,7 @@
             // IPv4 multicast TTL uses a byte.
             u_char ttl;
             bool ok = getSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl);
-            return ok ? newJavaLangInteger(env, ttl) : NULL;
+            return ok ? integerValueOf(env, ttl) : NULL;
         } else {
             return getSocketOption_Integer(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS);
         }
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 4df8515..1c73e74 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -42,7 +42,8 @@
 	org_apache_harmony_luni_util_NumberConvert.cpp \
 	org_apache_harmony_luni_util_fltparse.cpp \
 	org_apache_harmony_xml_ExpatParser.cpp \
-	org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp
+	org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp \
+	valueOf.cpp
 
 
 LOCAL_C_INCLUDES += \
diff --git a/luni/src/main/native/valueOf.cpp b/luni/src/main/native/valueOf.cpp
new file mode 100644
index 0000000..64cfb1f
--- /dev/null
+++ b/luni/src/main/native/valueOf.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "valueOf"
+
+#include "valueOf.h"
+#include "JNIHelp.h"
+
+jobject booleanValueOf(JNIEnv * env, jboolean value) {
+    static jclass c = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Boolean"));
+    static jmethodID valueOfMethod = env->GetStaticMethodID(c, "valueOf", "(Z)Ljava/lang/Boolean;");
+    return env->CallStaticObjectMethod(c, valueOfMethod, value);
+}
+
+jobject doubleValueOf(JNIEnv* env, jdouble value) {
+    static jclass c = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Double"));
+    static jmethodID valueOfMethod = env->GetStaticMethodID(c, "valueOf", "(D)Ljava/lang/Double;");
+    return env->CallStaticObjectMethod(c, valueOfMethod, value);
+}
+
+jobject integerValueOf(JNIEnv* env, jint value) {
+    static jclass c = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Integer"));
+    static jmethodID valueOfMethod = env->GetStaticMethodID(c, "valueOf", "(I)Ljava/lang/Integer;");
+    return env->CallStaticObjectMethod(c, valueOfMethod, value);
+}
+
+jobject longValueOf(JNIEnv* env, jlong value) {
+    static jclass c = (jclass) env->NewGlobalRef(env->FindClass("java/lang/Long"));
+    static jmethodID valueOfMethod = env->GetStaticMethodID(c, "valueOf", "(J)Ljava/lang/Long;");
+    return env->CallStaticObjectMethod(c, valueOfMethod, value);
+}
diff --git a/luni/src/main/native/valueOf.h b/luni/src/main/native/valueOf.h
new file mode 100644
index 0000000..5c8588f
--- /dev/null
+++ b/luni/src/main/native/valueOf.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VALUE_OF_H_included
+#define VALUE_OF_H_included
+
+#include "JNIHelp.h"
+
+jobject booleanValueOf(JNIEnv* env, jboolean b);
+jobject doubleValueOf(JNIEnv* env, jdouble d);
+jobject integerValueOf(JNIEnv* env, jint i);
+jobject longValueOf(JNIEnv* env, jlong l);
+
+#endif  // VALUE_OF_H_included