MediaFormat owns its strings

Have MediaFormat own the strings it returns from toString and getString,
reducing the chance of memory leaks.

Change-Id: I0ddd593874c8b3af0b7714f2d8a106edf8121108
diff --git a/include/ndk/NdkMediaFormat.h b/include/ndk/NdkMediaFormat.h
index 16f4348..4489b78 100644
--- a/include/ndk/NdkMediaFormat.h
+++ b/include/ndk/NdkMediaFormat.h
@@ -40,7 +40,8 @@
 int AMediaFormat_delete(AMediaFormat*);
 
 /**
- * Debug string. Caller must free.
+ * Human readable representation of the format. The returned string is owned by the format,
+ * and remains valid until the next call to toString, or until the format is deleted.
  */
 const char* AMediaFormat_toString(AMediaFormat*);
 
@@ -50,7 +51,8 @@
 bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out);
 bool AMediaFormat_getSize(AMediaFormat*, const char *name, size_t *out);
 /**
- * Caller must free the returned string
+ * The returned string is owned by the format, and remains valid until the next call to getString,
+ * or until the format is deleted.
  */
 bool AMediaFormat_getString(AMediaFormat*, const char *name, const char **out);
 
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index 359f37e..6f69f8d 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -34,6 +34,8 @@
 
 struct AMediaFormat {
     sp<AMessage> mFormat;
+    String8 mDebug;
+    KeyedVector<String8, String8> mStringCache;
 };
 
 extern "C" {
@@ -135,7 +137,8 @@
         }
     }
     ret.append("}");
-    return strdup(ret.string());
+    mData->mDebug = ret;
+    return mData->mDebug.string();
 }
 
 bool AMediaFormat_getInt32(AMediaFormat* mData, const char *name, int32_t *out) {
@@ -159,9 +162,19 @@
 }
 
 bool AMediaFormat_getString(AMediaFormat* mData, const char *name, const char **out) {
+
+    for (size_t i = 0; i < mData->mStringCache.size(); i++) {
+        if (strcmp(mData->mStringCache.keyAt(i).string(), name) == 0) {
+            mData->mStringCache.removeItemsAt(i, 1);
+            break;
+        }
+    }
+
     AString tmp;
     if (mData->mFormat->findString(name, &tmp)) {
-        *out = strdup(tmp.c_str());
+        String8 ret(tmp.c_str());
+        mData->mStringCache.add(String8(name), ret);
+        *out = ret.string();
         return true;
     }
     return false;