Fix for memory leak in AdapterSertvice.cpp : The native jobjectArray and jintArray instances are being declared and de-referenced in adapter_properties_callback() and remote_device_properties_callback() methods but is being initialized in get_properties() method. Becasuse of this, when the get_properties() method returns, VM looses reference to the native instances and hence leading to memory leak.

Change-Id: I48944887903a492a40cb95f5f79a56b9d58f85fa
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index 89d4823..2af399b 100755
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -77,19 +77,7 @@
 
 static int get_properties(int num_properties, bt_property_t *properties, jintArray *types,
                         jobjectArray *props) {
-    jbyteArray propVal, val;
-    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
-    if (val == NULL) goto Fail;
-
-    //TODO(BT) Is this the best way to do it ?
-    *props = callbackEnv->NewObjectArray(num_properties, callbackEnv->GetObjectClass(val),
-                                             NULL);
-    if (*props == NULL) goto Fail;
-
-    *types = callbackEnv->NewIntArray(num_properties);
-    if (*types == NULL) goto Fail;
-    // Delete the reference to val
-    callbackEnv->DeleteLocalRef(val);
+    jbyteArray propVal;
     for (int i = 0; i < num_properties; i++) {
 
        /* The higher layers expect rssi as a short int value, while the value is sent as a byte
@@ -114,7 +102,6 @@
     }
     return 0;
 Fail:
-    if (val) callbackEnv->DeleteLocalRef(val);
     if (propVal) callbackEnv->DeleteLocalRef(propVal);
     LOGE("Error while allocation of array in %s", __FUNCTION__);
     return -1;
@@ -124,6 +111,9 @@
                                         bt_property_t *properties) {
     jobjectArray props;
     jintArray types;
+    jbyteArray val;
+    jclass mclass;
+
     if (!checkCallbackThread()) {
        LOGE("Callback: '%s' is not called on the correct thread", __FUNCTION__);
        return;
@@ -136,6 +126,34 @@
         return;
     }
 
+    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
+    if (val == NULL) {
+        LOGE("%s: Error allocating byteArray", __FUNCTION__);
+        return;
+    }
+
+    mclass = callbackEnv->GetObjectClass(val);
+
+    /* (BT) Initialize the jobjectArray and jintArray here itself and send the
+     initialized array pointers alone to get_properties */
+
+    props = callbackEnv->NewObjectArray(num_properties, mclass,
+                                             NULL);
+    if (props == NULL) {
+        LOGE("%s: Error allocating object Array for properties", __FUNCTION__);
+        return;
+    }
+
+    types = (jintArray)callbackEnv->NewIntArray(num_properties);
+
+    if (types == NULL) {
+        LOGE("%s: Error allocating int Array for values", __FUNCTION__);
+        return;
+    }
+    // Delete the reference to val and mclass
+    callbackEnv->DeleteLocalRef(mclass);
+    callbackEnv->DeleteLocalRef(val);
+
     if (get_properties(num_properties, properties, &types, &props) < 0) {
         if (props) callbackEnv->DeleteLocalRef(props);
         if (types) callbackEnv->DeleteLocalRef(types);
@@ -170,6 +188,36 @@
     jobjectArray props;
     jbyteArray addr;
     jintArray types;
+    jbyteArray val;
+    jclass mclass;
+
+    val = (jbyteArray) callbackEnv->NewByteArray(num_properties);
+    if (val == NULL) {
+        LOGE("%s: Error allocating byteArray", __FUNCTION__);
+        return;
+    }
+
+    mclass = callbackEnv->GetObjectClass(val);
+
+    /* Initialize the jobjectArray and jintArray here itself and send the
+     initialized array pointers alone to get_properties */
+
+    props = callbackEnv->NewObjectArray(num_properties, mclass,
+                                             NULL);
+    if (props == NULL) {
+        LOGE("%s: Error allocating object Array for properties", __FUNCTION__);
+        return;
+    }
+
+    types = (jintArray)callbackEnv->NewIntArray(num_properties);
+
+    if (types == NULL) {
+        LOGE("%s: Error allocating int Array for values", __FUNCTION__);
+        return;
+    }
+    // Delete the reference to val and mclass
+    callbackEnv->DeleteLocalRef(mclass);
+    callbackEnv->DeleteLocalRef(val);
 
     addr = callbackEnv->NewByteArray(sizeof(bt_bdaddr_t));
     if (addr == NULL) goto Fail;
@@ -187,6 +235,7 @@
     checkAndClearExceptionFromCallback(callbackEnv, __FUNCTION__);
     callbackEnv->DeleteLocalRef(props);
     callbackEnv->DeleteLocalRef(types);
+    callbackEnv->DeleteLocalRef(addr);
     callbackEnv->PopLocalFrame(NULL);
     return;