Merge "Add support for retrieving location information in mp4/3gpp files" into ics-mr1
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 9aa6700..534afce 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -54,6 +54,7 @@
     METADATA_KEY_BITRATE         = 20,
     METADATA_KEY_TIMED_TEXT_LANGUAGES      = 21,
     METADATA_KEY_IS_DRM          = 22,
+    METADATA_KEY_LOCATION        = 23,
 
     // Add more here...
 };
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 57f678c..4cdee17 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -85,6 +85,7 @@
     kKeyDate              = 'date',  // cstring
     kKeyWriter            = 'writ',  // cstring
     kKeyCompilation       = 'cpil',  // cstring
+    kKeyLocation          = 'loc ',  // cstring
     kKeyTimeScale         = 'tmsl',  // int32_t
 
     // video profile and level
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 10694c3..b17f297 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -458,5 +458,13 @@
      * @hide
      */
     public static final int METADATA_KEY_IS_DRM          = 22;
+    /**
+     * This key retrieves the location information, if available.
+     * The location should be specified according to ISO-6709 standard, under
+     * a mp4/3gp box "@xyz". Location with longitude of -90 degrees and latitude
+     * of 180 degrees will be retrieved as "-90.0000+180.0000", for instance.
+     * @hide
+     */
+    public static final int METADATA_KEY_LOCATION        = 23;
     // Add more here...
 }
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 1e24599..1ebf0a8 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1136,6 +1136,41 @@
             break;
         }
 
+        // @xyz
+        case FOURCC('\xA9', 'x', 'y', 'z'):
+        {
+            // Best case the total data length inside "@xyz" box
+            // would be 8, for instance "@xyz" + "\x00\x04\x15\xc7" + "0+0/",
+            // where "\x00\x04" is the text string length with value = 4,
+            // "\0x15\xc7" is the language code = en, and "0+0" is a
+            // location (string) value with longitude = 0 and latitude = 0.
+            if (chunk_data_size < 8) {
+                return ERROR_MALFORMED;
+            }
+
+            // Worst case the location string length would be 18,
+            // for instance +90.0000-180.0000, without the trailing "/" and
+            // the string length + language code.
+            char buffer[18];
+
+            // Substracting 5 from the data size is because the text string length +
+            // language code takes 4 bytes, and the trailing slash "/" takes 1 byte.
+            off64_t location_length = chunk_data_size - 5;
+            if (location_length >= (off64_t) sizeof(buffer)) {
+                return ERROR_MALFORMED;
+            }
+
+            if (mDataSource->readAt(
+                        data_offset + 4, buffer, location_length) < location_length) {
+                return ERROR_IO;
+            }
+
+            buffer[location_length] = '\0';
+            mFileMetaData->setCString(kKeyLocation, buffer);
+            *offset += chunk_size;
+            break;
+        }
+
         case FOURCC('e', 's', 'd', 's'):
         {
             if (chunk_data_size < 4) {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index c74cb5a..4491c97 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -418,6 +418,7 @@
         { kKeyYear, METADATA_KEY_YEAR },
         { kKeyWriter, METADATA_KEY_WRITER },
         { kKeyCompilation, METADATA_KEY_COMPILATION },
+        { kKeyLocation, METADATA_KEY_LOCATION },
     };
     static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);