Merge "libminijail_vendor is now just libminijail"
diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp
index 7e6297c..8620f36 100644
--- a/camera/ICameraClient.cpp
+++ b/camera/ICameraClient.cpp
@@ -192,12 +192,14 @@
             timestamps.reserve(n);
             handles.reserve(n);
             for (uint32_t i = 0; i < n; i++) {
-                res = data.readInt64(&timestamps[i]);
+                nsecs_t t;
+                res = data.readInt64(&t);
                 if (res != OK) {
                     ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
                             __FUNCTION__, i, strerror(-res), res);
                     return BAD_VALUE;
                 }
+                timestamps.push_back(t);
             }
             for (uint32_t i = 0; i < n; i++) {
                 native_handle_t* handle = data.readNativeHandle();
diff --git a/camera/ICameraRecordingProxyListener.cpp b/camera/ICameraRecordingProxyListener.cpp
index c954241..66faf8f 100644
--- a/camera/ICameraRecordingProxyListener.cpp
+++ b/camera/ICameraRecordingProxyListener.cpp
@@ -146,12 +146,14 @@
             timestamps.reserve(n);
             handles.reserve(n);
             for (uint32_t i = 0; i < n; i++) {
-                res = data.readInt64(&timestamps[i]);
+                nsecs_t t;
+                res = data.readInt64(&t);
                 if (res != OK) {
                     ALOGE("%s: Failed to read timestamp[%d]: %s (%d)",
                             __FUNCTION__, i, strerror(-res), res);
                     return BAD_VALUE;
                 }
+                timestamps.push_back(t);
             }
             for (uint32_t i = 0; i < n; i++) {
                 native_handle_t* handle = data.readNativeHandle();
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 9bc2594..fa1d253 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -740,6 +740,18 @@
                         { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                              // TONE_JAPAN_RADIO_ACK
+        { .segments = { { .duration = 375, .waveFreq = { 400, 0 }, 0, 0 },
+                        { .duration = 375, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_GB_BUSY
+        { .segments = { { .duration = 400, .waveFreq = { 400, 0 }, 0, 0 },
+                        { .duration = 350, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 225, .waveFreq = { 400, 0 }, 0, 0 },
+                        { .duration = 525, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_GB_CONGESTION
         { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
                         { .duration = 200, .waveFreq = { 0 }, 0, 0 },
                         { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
@@ -747,6 +759,10 @@
                         { .duration = 0, .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                              // TONE_GB_RINGTONE
+        { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 400, 425, 450, 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_AUSTRALIA_DIAL
         { .segments = { { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
                         { .duration = 200, .waveFreq = { 0 }, 0, 0 },
                         { .duration = 400, .waveFreq = { 400, 450, 0 }, 0, 0 },
@@ -771,6 +787,30 @@
                         { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
           .repeatCnt = ToneGenerator::TONEGEN_INF,
           .repeatSegment = 0 },                              // TONE_AUSTRALIA_CONGESTION
+        { .segments = { { .duration = 750, .waveFreq = { 425, 0 }, 0, 0 },
+                        { .duration = 750, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_SG_BUSY
+        { .segments = { { .duration = 400, .waveFreq = { 401, 425, 449, 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 400, .waveFreq = { 401, 425, 449, 0 }, 0, 0 },
+                        { .duration = 2000, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_SG_RINGTONE
+        { .segments = { { .duration = 500, .waveFreq = { 480, 620, 0 }, 0, 0 },
+                        { .duration = 500, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_HK_BUSY
+        { .segments = { { .duration = 400, .waveFreq = { 440, 480, 0 }, 0, 0 },
+                        { .duration = 200, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 400, .waveFreq = { 440, 480, 0 }, 0, 0 },
+                        { .duration = 3000, .waveFreq = { 0 }, 0, 0 },
+                        { .duration = 0 , .waveFreq = { 0 }, 0, 0}},
+          .repeatCnt = ToneGenerator::TONEGEN_INF,
+          .repeatSegment = 0 },                              // TONE_HK_RINGTONE
 };
 
 // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type
@@ -797,9 +837,9 @@
             TONE_SUP_RINGTONE            // TONE_SUP_RINGTONE
         },
         {   // GB
-            TONE_SUP_DIAL,               // TONE_SUP_DIAL
-            TONE_SUP_BUSY,               // TONE_SUP_BUSY
-            TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
+            TONE_ANSI_DIAL,              // TONE_SUP_DIAL
+            TONE_GB_BUSY,                // TONE_SUP_BUSY
+            TONE_GB_CONGESTION,          // TONE_SUP_CONGESTION
             TONE_SUP_RADIO_ACK,          // TONE_SUP_RADIO_ACK
             TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
             TONE_SUP_ERROR,              // TONE_SUP_ERROR
@@ -807,7 +847,7 @@
             TONE_GB_RINGTONE             // TONE_SUP_RINGTONE
         },
         {   // AUSTRALIA
-            TONE_ANSI_DIAL,             // TONE_SUP_DIAL
+            TONE_AUSTRALIA_DIAL,        // TONE_SUP_DIAL
             TONE_AUSTRALIA_BUSY,        // TONE_SUP_BUSY
             TONE_AUSTRALIA_CONGESTION,  // TONE_SUP_CONGESTION
             TONE_SUP_RADIO_ACK,         // TONE_SUP_RADIO_ACK
@@ -815,6 +855,26 @@
             TONE_SUP_ERROR,             // TONE_SUP_ERROR
             TONE_AUSTRALIA_CALL_WAITING,// TONE_SUP_CALL_WAITING
             TONE_AUSTRALIA_RINGTONE     // TONE_SUP_RINGTONE
+        },
+        {   // SINGAPORE
+            TONE_SUP_DIAL,               // TONE_SUP_DIAL
+            TONE_SG_BUSY,                // TONE_SUP_BUSY
+            TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
+            TONE_SUP_RADIO_ACK,          // TONE_SUP_RADIO_ACK
+            TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
+            TONE_SUP_ERROR,              // TONE_SUP_ERROR
+            TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
+            TONE_SG_RINGTONE             // TONE_SUP_RINGTONE
+        },
+        {   // HONGKONG
+            TONE_SUP_DIAL,               // TONE_SUP_DIAL
+            TONE_HK_BUSY,                // TONE_SUP_BUSY
+            TONE_SUP_CONGESTION,         // TONE_SUP_CONGESTION
+            TONE_SUP_RADIO_ACK,          // TONE_SUP_RADIO_ACK
+            TONE_SUP_RADIO_NOTAVAIL,     // TONE_SUP_RADIO_NOTAVAIL
+            TONE_SUP_ERROR,              // TONE_SUP_ERROR
+            TONE_SUP_CALL_WAITING,       // TONE_SUP_CALL_WAITING
+            TONE_HK_RINGTONE             // TONE_SUP_RINGTONE
         }
 };
 
@@ -864,6 +924,13 @@
     if (property_get("gsm.operator.iso-country", value, "") == 0) {
         property_get("gsm.sim.operator.iso-country", value, "");
     }
+    // If dual sim device has two SIM cards inserted and is not registerd to any network,
+    // "," is set to "gsm.operator.iso-country" prop.
+    // In this case, "gsm.sim.operator.iso-country" prop should be used.
+    if (strlen(value) == 1 && strstr(value, ",") != NULL) {
+        property_get("gsm.sim.operator.iso-country", value, "");
+    }
+
     if (strstr(value, "us") != NULL ||
         strstr(value, "ca") != NULL) {
         mRegion = ANSI;
@@ -873,6 +940,10 @@
         mRegion = GB;
     } else if (strstr(value, "au") != NULL) {
         mRegion = AUSTRALIA;
+    } else if (strstr(value, "sg") != NULL) {
+        mRegion = SINGAPORE;
+    } else if (strstr(value, "hk") != NULL) {
+        mRegion = HONGKONG;
     } else {
         mRegion = CEPT;
     }
diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h
index fc3d3ee..97bc825 100644
--- a/media/libaudioclient/include/media/ToneGenerator.h
+++ b/media/libaudioclient/include/media/ToneGenerator.h
@@ -177,7 +177,7 @@
 
 
     // Region specific tones.
-    // These supervisory tones are different depending on the region (USA/CANADA, JAPAN, rest of the world).
+    // These supervisory tones are different depending on the region (USA/CANADA, JAPAN, Singapore, Hong Kong, rest of the world).
     // When a tone in the range [FIRST_SUP_TONE, LAST_SUP_TONE] is requested, the region is determined
     // from system property gsm.operator.iso-country and the proper tone descriptor is selected with the
     // help of sToneMappingTable[]
@@ -194,12 +194,21 @@
         TONE_JAPAN_BUSY,            // Busy tone: 400Hz, 500ms ON, 500ms OFF...
         TONE_JAPAN_RADIO_ACK,       // Radio path acknowlegment: 400Hz, 1s ON, 2s OFF...
         // GB Supervisory tones
+        TONE_GB_BUSY,               // Busy tone: 400 Hz, 375ms ON, 375ms OFF...
+        TONE_GB_CONGESTION,         // Congestion Tone: 400 Hz, 400ms ON, 350ms OFF, 225ms ON, 525ms OFF...
         TONE_GB_RINGTONE,           // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
         // AUSTRALIA Supervisory tones
+        TONE_AUSTRALIA_DIAL,        // Dial tone: 425 Hz tone modulated with 25 Hz, continuous
         TONE_AUSTRALIA_RINGTONE,    // Ring tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern.
         TONE_AUSTRALIA_BUSY,        // Busy tone: 425 Hz repeated in a 0.375s on, 0.375s off pattern.
         TONE_AUSTRALIA_CALL_WAITING,// Call waiting tone: 425Hz tone repeated in a 0.2s on, 0.2s off, 0.2s on, 4.4s off pattern.
         TONE_AUSTRALIA_CONGESTION,  // Congestion tone: 425Hz tone repeated in a 0.375s on, 0.375s off pattern
+        // SINGAPORE Supervisory tones
+        TONE_SG_BUSY,               // Busy tone: 425 Hz, 750ms ON, 750ms OFF...
+        TONE_SG_RINGTONE,           // Ring Tone: 425 Hz tone modulated with 24 Hz, 400ms ON, 200ms OFF, 400ms ON, 2s OFF...
+        // HONG KONG Supervisory tones
+        TONE_HK_BUSY,               // Busy tone: 480 Hz + 620 Hz, 500ms ON, 500ms OFF...
+        TONE_HK_RINGTONE,           // Ring Tone: 440 Hz + 480 Hz repeated with pattern 0,4s on, 0,2s off, 0,4s on and 3s off.
         NUM_ALTERNATE_TONES
     };
 
@@ -208,6 +217,8 @@
         JAPAN,
         GB,
         AUSTRALIA,
+        SINGAPORE,
+        HONGKONG,
         CEPT,
         NUM_REGIONS
     };
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index ab75c65..1460301 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -93,7 +93,6 @@
         "libutils",
         "libvorbisidec",
         "libmediadrm",
-        "libnativewindow",
 
         "libmedia_helper",
         "libstagefright_foundation",
@@ -102,9 +101,7 @@
         "libhidlbase",
         "libhidlmemory",
         "android.hidl.allocator@1.0",
-        "android.hidl.memory@1.0",
         "android.hardware.media.omx@1.0",
-        "libstagefright_xmlparser@1.0",
     ],
 
     static_libs: [
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 65e172a..3f61dd4 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -3511,6 +3511,18 @@
         return ERROR_UNSUPPORTED;
     }
 
+    if (mLastTrack != NULL) {
+        uint32_t maxBitrate = 0;
+        uint32_t avgBitrate = 0;
+        esds.getBitRate(&maxBitrate, &avgBitrate);
+        if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
+            mLastTrack->meta->setInt32(kKeyMaxBitRate, (int32_t)maxBitrate);
+        }
+        if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
+            mLastTrack->meta->setInt32(kKeyBitRate, (int32_t)avgBitrate);
+        }
+    }
+
     const uint8_t *csd;
     size_t csd_size;
     if (esds.getCodecSpecificInfo(
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index e31c37c..442d0a4 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -1119,6 +1119,7 @@
             mMeta->setData(kKeyVorbisInfo, 0, data, size);
             mMeta->setInt32(kKeySampleRate, mVi.rate);
             mMeta->setInt32(kKeyChannelCount, mVi.channels);
+            mMeta->setInt32(kKeyBitRate, mVi.bitrate_nominal);
 
             ALOGV("lower-bitrate = %ld", mVi.bitrate_lower);
             ALOGV("upper-bitrate = %ld", mVi.bitrate_upper);
diff --git a/media/libstagefright/codecs/aacenc/Android.bp b/media/libstagefright/codecs/aacenc/Android.bp
index 1a7ffca..0a8e40c 100644
--- a/media/libstagefright/codecs/aacenc/Android.bp
+++ b/media/libstagefright/codecs/aacenc/Android.bp
@@ -55,7 +55,7 @@
 
             instruction_set: "arm",
 
-            armv7_a_neon: {
+            neon: {
                 exclude_srcs: [
                     "src/asm/ARMV5E/PrePostMDCT_v5.s",
                     "src/asm/ARMV5E/R4R8First_v5.s",
diff --git a/media/libstagefright/codecs/amrwbenc/Android.bp b/media/libstagefright/codecs/amrwbenc/Android.bp
index 5c5a122..eb27388 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.bp
+++ b/media/libstagefright/codecs/amrwbenc/Android.bp
@@ -75,7 +75,7 @@
 
             instruction_set: "arm",
 
-            armv7_a_neon: {
+            neon: {
                 exclude_srcs: [
                     "src/asm/ARMV5E/convolve_opt.s",
                     "src/asm/ARMV5E/cor_h_vec_opt.s",
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.bp b/media/libstagefright/codecs/on2/h264dec/Android.bp
index 95c2075..6d558b6 100644
--- a/media/libstagefright/codecs/on2/h264dec/Android.bp
+++ b/media/libstagefright/codecs/on2/h264dec/Android.bp
@@ -35,7 +35,7 @@
         arm: {
             instruction_set: "arm",
 
-            armv7_a_neon: {
+            neon: {
                 cflags: [
                     "-DH264DEC_NEON",
                     "-DH264DEC_OMXDL",
diff --git a/media/libstagefright/foundation/Android.bp b/media/libstagefright/foundation/Android.bp
index 91462c8..657f02c 100644
--- a/media/libstagefright/foundation/Android.bp
+++ b/media/libstagefright/foundation/Android.bp
@@ -1,7 +1,9 @@
 cc_library_shared {
     name: "libstagefright_foundation",
     vendor_available: true,
-
+    vndk: {
+        enabled: true,
+    },
     include_dirs: [
         "frameworks/av/include",
         "frameworks/native/include",
diff --git a/media/mtp/MtpDatabase.h b/media/mtp/MtpDatabase.h
index 4e6ac7a..c7021df 100644
--- a/media/mtp/MtpDatabase.h
+++ b/media/mtp/MtpDatabase.h
@@ -103,6 +103,9 @@
 
     virtual MtpProperty*            getDevicePropertyDesc(MtpDeviceProperty property) = 0;
 
+    virtual MtpResponseCode         moveObject(MtpObjectHandle handle, MtpObjectHandle newParent,
+                                            MtpString& newPath) = 0;
+
     virtual void                    sessionStarted() = 0;
 
     virtual void                    sessionEnded() = 0;
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index e148b0c..236f3a9 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -67,8 +67,8 @@
     MTP_OPERATION_SET_DEVICE_PROP_VALUE,
     MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
 //    MTP_OPERATION_TERMINATE_OPEN_CAPTURE,
-//    MTP_OPERATION_MOVE_OBJECT,
-//    MTP_OPERATION_COPY_OBJECT,
+    MTP_OPERATION_MOVE_OBJECT,
+    MTP_OPERATION_COPY_OBJECT,
     MTP_OPERATION_GET_PARTIAL_OBJECT,
 //    MTP_OPERATION_INITIATE_OPEN_CAPTURE,
     MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED,
@@ -437,6 +437,12 @@
         case MTP_OPERATION_DELETE_OBJECT:
             response = doDeleteObject();
             break;
+        case MTP_OPERATION_COPY_OBJECT:
+            response = doCopyObject();
+            break;
+        case MTP_OPERATION_MOVE_OBJECT:
+            response = doMoveObject();
+            break;
         case MTP_OPERATION_GET_OBJECT_PROP_DESC:
             response = doGetObjectPropDesc();
             break;
@@ -1020,6 +1026,137 @@
     return MTP_RESPONSE_OK;
 }
 
+MtpResponseCode MtpServer::doMoveObject() {
+    if (!hasStorage())
+        return MTP_RESPONSE_GENERAL_ERROR;
+    if (mRequest.getParameterCount() < 3)
+        return MTP_RESPONSE_INVALID_PARAMETER;
+    MtpObjectHandle objectHandle = mRequest.getParameter(1);
+    MtpStorageID storageID = mRequest.getParameter(2);
+    MtpStorage* storage = getStorage(storageID);
+    MtpObjectHandle parent = mRequest.getParameter(3);
+    if (!storage)
+        return MTP_RESPONSE_INVALID_STORAGE_ID;
+    MtpString path;
+    MtpResponseCode result;
+
+    MtpString fromPath;
+    int64_t fileLength;
+    MtpObjectFormat format;
+    MtpObjectInfo info(objectHandle);
+    result = mDatabase->getObjectInfo(objectHandle, info);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+    result = mDatabase->getObjectFilePath(objectHandle, fromPath, fileLength, format);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+
+    // special case the root
+    if (parent == 0) {
+        path = storage->getPath();
+    } else {
+        int64_t parentLength;
+        MtpObjectFormat parentFormat;
+        result = mDatabase->getObjectFilePath(parent, path, parentLength, parentFormat);
+        if (result != MTP_RESPONSE_OK)
+            return result;
+        if (parentFormat != MTP_FORMAT_ASSOCIATION)
+            return MTP_RESPONSE_INVALID_PARENT_OBJECT;
+    }
+
+    if (path[path.size() - 1] != '/')
+        path += "/";
+    path += info.mName;
+
+    result = mDatabase->moveObject(objectHandle, parent, path);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+
+    if (info.mStorageID == storageID) {
+        ALOGV("Moving file from %s to %s", (const char*)fromPath, (const char*)path);
+        if (rename(fromPath, path)) {
+            ALOGE("rename() failed from %s to %s", (const char*)fromPath, (const char*)path);
+            result = MTP_RESPONSE_GENERAL_ERROR;
+        }
+    } else {
+        ALOGV("Moving across storages from %s to %s", (const char*)fromPath, (const char*)path);
+        if (copyFile(fromPath, path)) {
+            result = MTP_RESPONSE_GENERAL_ERROR;
+        } else {
+            deletePath(fromPath);
+        }
+    }
+
+    // If the move failed, undo the database change
+    if (result != MTP_RESPONSE_OK)
+        if (mDatabase->moveObject(objectHandle, info.mParent, fromPath) != MTP_RESPONSE_OK)
+            ALOGE("Couldn't undo failed move");
+
+    return result;
+}
+
+MtpResponseCode MtpServer::doCopyObject() {
+    if (!hasStorage())
+        return MTP_RESPONSE_GENERAL_ERROR;
+    MtpResponseCode result = MTP_RESPONSE_OK;
+    if (mRequest.getParameterCount() < 3)
+        return MTP_RESPONSE_INVALID_PARAMETER;
+    MtpObjectHandle objectHandle = mRequest.getParameter(1);
+    MtpStorageID storageID = mRequest.getParameter(2);
+    MtpStorage* storage = getStorage(storageID);
+    MtpObjectHandle parent = mRequest.getParameter(3);
+    if (!storage)
+        return MTP_RESPONSE_INVALID_STORAGE_ID;
+    MtpString path;
+
+    MtpString fromPath;
+    int64_t fileLength;
+    MtpObjectFormat format;
+    MtpObjectInfo info(objectHandle);
+    result = mDatabase->getObjectInfo(objectHandle, info);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+    result = mDatabase->getObjectFilePath(objectHandle, fromPath, fileLength, format);
+    if (result != MTP_RESPONSE_OK)
+        return result;
+
+    // special case the root
+    if (parent == 0) {
+        path = storage->getPath();
+    } else {
+        int64_t parentLength;
+        MtpObjectFormat parentFormat;
+        result = mDatabase->getObjectFilePath(parent, path, parentLength, parentFormat);
+        if (result != MTP_RESPONSE_OK)
+            return result;
+        if (parentFormat != MTP_FORMAT_ASSOCIATION)
+            return MTP_RESPONSE_INVALID_PARENT_OBJECT;
+    }
+
+    // check space first
+    if ((uint64_t) fileLength > storage->getFreeSpace())
+        return MTP_RESPONSE_STORAGE_FULL;
+
+    if (path[path.size() - 1] != '/')
+        path += "/";
+    path += info.mName;
+
+    MtpObjectHandle handle = mDatabase->beginSendObject((const char*)path,
+            format, parent, storageID, fileLength, info.mDateModified);
+    if (handle == kInvalidObjectHandle) {
+        return MTP_RESPONSE_GENERAL_ERROR;
+    }
+
+    ALOGV("Copying file from %s to %s", (const char*)fromPath, (const char*)path);
+    if (copyFile(fromPath, path)) {
+        result = MTP_RESPONSE_GENERAL_ERROR;
+    }
+
+    mDatabase->endSendObject(path, handle, format, result);
+    mResponse.setParameter(1, handle);
+    return result;
+}
+
 MtpResponseCode MtpServer::doSendObject() {
     if (!hasStorage())
         return MTP_RESPONSE_GENERAL_ERROR;
@@ -1124,65 +1261,6 @@
     return result;
 }
 
-static void deleteRecursive(const char* path) {
-    char pathbuf[PATH_MAX];
-    size_t pathLength = strlen(path);
-    if (pathLength >= sizeof(pathbuf) - 1) {
-        ALOGE("path too long: %s\n", path);
-    }
-    strcpy(pathbuf, path);
-    if (pathbuf[pathLength - 1] != '/') {
-        pathbuf[pathLength++] = '/';
-    }
-    char* fileSpot = pathbuf + pathLength;
-    int pathRemaining = sizeof(pathbuf) - pathLength - 1;
-
-    DIR* dir = opendir(path);
-    if (!dir) {
-        ALOGE("opendir %s failed: %s", path, strerror(errno));
-        return;
-    }
-
-    struct dirent* entry;
-    while ((entry = readdir(dir))) {
-        const char* name = entry->d_name;
-
-        // ignore "." and ".."
-        if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
-            continue;
-        }
-
-        int nameLength = strlen(name);
-        if (nameLength > pathRemaining) {
-            ALOGE("path %s/%s too long\n", path, name);
-            continue;
-        }
-        strcpy(fileSpot, name);
-
-        if (entry->d_type == DT_DIR) {
-            deleteRecursive(pathbuf);
-            rmdir(pathbuf);
-        } else {
-            unlink(pathbuf);
-        }
-    }
-    closedir(dir);
-}
-
-static void deletePath(const char* path) {
-    struct stat statbuf;
-    if (stat(path, &statbuf) == 0) {
-        if (S_ISDIR(statbuf.st_mode)) {
-            deleteRecursive(path);
-            rmdir(path);
-        } else {
-            unlink(path);
-        }
-    } else {
-        ALOGE("deletePath stat failed for %s: %s", path, strerror(errno));
-    }
-}
-
 MtpResponseCode MtpServer::doDeleteObject() {
     if (!hasStorage())
         return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index 08a9e4a..aafc753 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -161,6 +161,8 @@
     MtpResponseCode     doSendObjectInfo();
     MtpResponseCode     doSendObject();
     MtpResponseCode     doDeleteObject();
+    MtpResponseCode     doMoveObject();
+    MtpResponseCode     doCopyObject();
     MtpResponseCode     doGetObjectPropDesc();
     MtpResponseCode     doGetDevicePropDesc();
     MtpResponseCode     doSendPartialObject();
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index ebf3601..036ffe7 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -16,13 +16,23 @@
 
 #define LOG_TAG "MtpUtils"
 
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 #include <stdio.h>
 #include <time.h>
+#include <unistd.h>
 
 #include "MtpUtils.h"
 
 namespace android {
 
+constexpr unsigned long FILE_COPY_SIZE = 262144;
+
 /*
 DateTime strings follow a compatible subset of the definition found in ISO 8601, and
 take the form of a Unicode string formatted as: "YYYYMMDDThhmmss.s". In this
@@ -78,4 +88,101 @@
         tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
 
+int copyFile(const char *fromPath, const char *toPath) {
+    auto start = std::chrono::steady_clock::now();
+
+    android::base::unique_fd fromFd(open(fromPath, O_RDONLY));
+    if (fromFd == -1) {
+        PLOG(ERROR) << "Failed to open copy from " << fromPath;
+        return -1;
+    }
+    android::base::unique_fd toFd(open(toPath, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR));
+    if (toFd == -1) {
+        PLOG(ERROR) << "Failed to open copy to " << toPath;
+        return -1;
+    }
+    off_t offset = 0;
+
+    struct stat sstat = {};
+    if (stat(fromPath, &sstat) == -1)
+        return -1;
+
+    off_t length = sstat.st_size;
+    int ret = 0;
+
+    while (offset < length) {
+        ssize_t transfer_length = std::min(length - offset, (off_t) FILE_COPY_SIZE);
+        ret = sendfile(toFd, fromFd, &offset, transfer_length);
+        if (ret != transfer_length) {
+            ret = -1;
+            PLOG(ERROR) << "Copying failed!";
+            break;
+        }
+    }
+    auto end = std::chrono::steady_clock::now();
+    std::chrono::duration<double> diff = end - start;
+    LOG(INFO) << "Copied a file with MTP. Time: " << diff.count() << " s, Size: " << length <<
+        ", Rate: " << ((double) length) / diff.count() << " bytes/s";
+    return ret == -1 ? -1 : 0;
+}
+
+void deleteRecursive(const char* path) {
+    char pathbuf[PATH_MAX];
+    size_t pathLength = strlen(path);
+    if (pathLength >= sizeof(pathbuf) - 1) {
+        LOG(ERROR) << "path too long: " << path;
+    }
+    strcpy(pathbuf, path);
+    if (pathbuf[pathLength - 1] != '/') {
+        pathbuf[pathLength++] = '/';
+    }
+    char* fileSpot = pathbuf + pathLength;
+    int pathRemaining = sizeof(pathbuf) - pathLength - 1;
+
+    DIR* dir = opendir(path);
+    if (!dir) {
+        PLOG(ERROR) << "opendir " << path << " failed";
+        return;
+    }
+
+    struct dirent* entry;
+    while ((entry = readdir(dir))) {
+        const char* name = entry->d_name;
+
+        // ignore "." and ".."
+        if (name[0] == '.' && (name[1] == 0 || (name[1] == '.' && name[2] == 0))) {
+            continue;
+        }
+
+        int nameLength = strlen(name);
+        if (nameLength > pathRemaining) {
+            LOG(ERROR) << "path " << path << "/" << name << " too long";
+            continue;
+        }
+        strcpy(fileSpot, name);
+
+        if (entry->d_type == DT_DIR) {
+            deleteRecursive(pathbuf);
+            rmdir(pathbuf);
+        } else {
+            unlink(pathbuf);
+        }
+    }
+    closedir(dir);
+}
+
+void deletePath(const char* path) {
+    struct stat statbuf;
+    if (stat(path, &statbuf) == 0) {
+        if (S_ISDIR(statbuf.st_mode)) {
+            deleteRecursive(path);
+            rmdir(path);
+        } else {
+            unlink(path);
+        }
+    } else {
+        PLOG(ERROR) << "deletePath stat failed for " << path;;
+    }
+}
+
 }  // namespace android
diff --git a/media/mtp/MtpUtils.h b/media/mtp/MtpUtils.h
index 61f9055..a2bb7e1 100644
--- a/media/mtp/MtpUtils.h
+++ b/media/mtp/MtpUtils.h
@@ -24,6 +24,10 @@
 bool parseDateTime(const char* dateTime, time_t& outSeconds);
 void formatDateTime(time_t seconds, char* buffer, int bufferLength);
 
+int copyFile(const char *fromPath, const char *toPath);
+void deleteRecursive(const char* path);
+void deletePath(const char* path);
+
 }; // namespace android
 
 #endif // _MTP_UTILS_H
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index 12e8f0f..faf2d14 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -39,6 +39,7 @@
 #endif
 
 struct ANativeWindow;
+typedef struct ANativeWindow ANativeWindow;
 
 #if __ANDROID_API__ >= 21
 
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
index b7f7af0..0fae598 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.cpp
@@ -114,57 +114,72 @@
 }
 
 hardware::Return<void> CameraHardwareInterface::unregisterMemory(uint32_t memId) {
-    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
-    if (mHidlMemPoolMap.count(memId) == 0) {
-        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
-        return hardware::Void();
+    camera_memory_t* mem = nullptr;
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        if (mHidlMemPoolMap.count(memId) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, memId);
+            return hardware::Void();
+        }
+        mem = mHidlMemPoolMap.at(memId);
+        mHidlMemPoolMap.erase(memId);
     }
-    camera_memory_t* mem = mHidlMemPoolMap.at(memId);
     sPutMemory(mem);
-    mHidlMemPoolMap.erase(memId);
     return hardware::Void();
 }
 
 hardware::Return<void> CameraHardwareInterface::dataCallback(
         DataCallbackMsg msgType, uint32_t data, uint32_t bufferIndex,
         const hardware::camera::device::V1_0::CameraFrameMetadata& metadata) {
-    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
-    if (mHidlMemPoolMap.count(data) == 0) {
-        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
-        return hardware::Void();
+    camera_memory_t* mem = nullptr;
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        if (mHidlMemPoolMap.count(data) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+            return hardware::Void();
+        }
+        mem = mHidlMemPoolMap.at(data);
     }
     camera_frame_metadata_t md;
     md.number_of_faces = metadata.faces.size();
     md.faces = (camera_face_t*) metadata.faces.data();
-    sDataCb((int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, &md, this);
+    sDataCb((int32_t) msgType, mem, bufferIndex, &md, this);
     return hardware::Void();
 }
 
 hardware::Return<void> CameraHardwareInterface::dataCallbackTimestamp(
         DataCallbackMsg msgType, uint32_t data,
         uint32_t bufferIndex, int64_t timestamp) {
-    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
-    if (mHidlMemPoolMap.count(data) == 0) {
-        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
-        return hardware::Void();
+    camera_memory_t* mem = nullptr;
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        if (mHidlMemPoolMap.count(data) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+            return hardware::Void();
+        }
+        mem = mHidlMemPoolMap.at(data);
     }
-    sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
+    sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
     return hardware::Void();
 }
 
 hardware::Return<void> CameraHardwareInterface::handleCallbackTimestamp(
         DataCallbackMsg msgType, const hidl_handle& frameData, uint32_t data,
         uint32_t bufferIndex, int64_t timestamp) {
-    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
-    if (mHidlMemPoolMap.count(data) == 0) {
-        ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
-        return hardware::Void();
+    camera_memory_t* mem = nullptr;
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        if (mHidlMemPoolMap.count(data) == 0) {
+            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, data);
+            return hardware::Void();
+        }
+        mem = mHidlMemPoolMap.at(data);
     }
-    sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(data)->handle));
+    sp<CameraHeapMemory> heapMem(static_cast<CameraHeapMemory *>(mem->handle));
     VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
-            mem->mBuffers[bufferIndex]->pointer();
+            heapMem->mBuffers[bufferIndex]->pointer();
     md->pHandle = const_cast<native_handle_t*>(frameData.getNativeHandle());
-    sDataCbTimestamp(timestamp, (int32_t) msgType, mHidlMemPoolMap.at(data), bufferIndex, this);
+    sDataCbTimestamp(timestamp, (int32_t) msgType, mem, bufferIndex, this);
     return hardware::Void();
 }
 
@@ -173,28 +188,28 @@
         const hardware::hidl_vec<hardware::camera::device::V1_0::HandleTimestampMessage>& messages) {
     std::vector<android::HandleTimestampMessage> msgs;
     msgs.reserve(messages.size());
+    {
+        std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
+        for (const auto& hidl_msg : messages) {
+            if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
+                ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
+                return hardware::Void();
+            }
+            sp<CameraHeapMemory> mem(
+                    static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
 
-    std::lock_guard<std::mutex> lock(mHidlMemPoolMapLock);
-    for (const auto& hidl_msg : messages) {
-        if (mHidlMemPoolMap.count(hidl_msg.data) == 0) {
-            ALOGE("%s: memory pool ID %d not found", __FUNCTION__, hidl_msg.data);
-            return hardware::Void();
+            if (hidl_msg.bufferIndex >= mem->mNumBufs) {
+                ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
+                     hidl_msg.bufferIndex, mem->mNumBufs);
+                return hardware::Void();
+            }
+            VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
+                    mem->mBuffers[hidl_msg.bufferIndex]->pointer();
+            md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
+
+            msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
         }
-        sp<CameraHeapMemory> mem(
-                static_cast<CameraHeapMemory *>(mHidlMemPoolMap.at(hidl_msg.data)->handle));
-
-        if (hidl_msg.bufferIndex >= mem->mNumBufs) {
-            ALOGE("%s: invalid buffer index %d, max allowed is %d", __FUNCTION__,
-                 hidl_msg.bufferIndex, mem->mNumBufs);
-            return hardware::Void();
-        }
-        VideoNativeHandleMetadata* md = (VideoNativeHandleMetadata*)
-                mem->mBuffers[hidl_msg.bufferIndex]->pointer();
-        md->pHandle = const_cast<native_handle_t*>(hidl_msg.frameData.getNativeHandle());
-
-        msgs.push_back({hidl_msg.timestamp, mem->mBuffers[hidl_msg.bufferIndex]});
     }
-
     mDataCbTimestampBatch((int32_t) msgType, msgs, mCbUser);
     return hardware::Void();
 }
diff --git a/services/mediacodec/seccomp_policy/mediacodec-arm.policy b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
index 73857f8..8e1fc77 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-arm.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-arm.policy
@@ -52,6 +52,7 @@
 fstatat64: 1
 ugetrlimit: 1
 getdents64: 1
+getrandom: 1
 
 # for attaching to debuggerd on process crash
 sigaction: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
index e06ac8c..4fa69d7 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm.policy
@@ -39,6 +39,7 @@
 getegid32: 1
 getgroups32: 1
 nanosleep: 1
+getrandom: 1
 
 # for FileSource
 readlinkat: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
index 4b51457..d1278a9 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-arm64.policy
@@ -28,10 +28,10 @@
 rt_sigreturn: 1
 getrlimit: 1
 nanosleep: 1
+getrandom: 1
 
 # for FileSource
 readlinkat: 1
-_llseek: 1
 
 # for attaching to debuggerd on process crash
 tgkill: 1
diff --git a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
index cdff4db..3b37f92 100644
--- a/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
+++ b/services/mediaextractor/seccomp_policy/mediaextractor-x86.policy
@@ -37,6 +37,7 @@
 getegid32: 1
 getgroups32: 1
 nanosleep: 1
+getrandom: 1
 
 # for FileSource
 readlinkat: 1