Merge "Remove unused IMediaSource Implementation, AACEncoder"
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/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h
deleted file mode 120000
index c35401e..0000000
--- a/include/media/nbaio/NBLog.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/NBLog.h
\ No newline at end of file
diff --git a/include/media/nbaio/PerformanceAnalysis.h b/include/media/nbaio/PerformanceAnalysis.h
deleted file mode 120000
index 7acfc90..0000000
--- a/include/media/nbaio/PerformanceAnalysis.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
\ No newline at end of file
diff --git a/include/media/nbaio/ReportPerformance.h b/include/media/nbaio/ReportPerformance.h
deleted file mode 120000
index bd596e3..0000000
--- a/include/media/nbaio/ReportPerformance.h
+++ /dev/null
@@ -1 +0,0 @@
-../../../media/libnbaio/include/media/nbaio/ReportPerformance.h
\ No newline at end of file
diff --git a/include/media/nblog/NBLog.h b/include/media/nblog/NBLog.h
new file mode 120000
index 0000000..3cc366c
--- /dev/null
+++ b/include/media/nblog/NBLog.h
@@ -0,0 +1 @@
+../../../media/libnblog/include/media/nblog/NBLog.h
\ No newline at end of file
diff --git a/include/media/nblog/PerformanceAnalysis.h b/include/media/nblog/PerformanceAnalysis.h
new file mode 120000
index 0000000..6ead3bc
--- /dev/null
+++ b/include/media/nblog/PerformanceAnalysis.h
@@ -0,0 +1 @@
+../../../media/libnblog/include/media/nblog/PerformanceAnalysis.h
\ No newline at end of file
diff --git a/include/media/nblog/ReportPerformance.h b/include/media/nblog/ReportPerformance.h
new file mode 120000
index 0000000..e9b8e80
--- /dev/null
+++ b/include/media/nblog/ReportPerformance.h
@@ -0,0 +1 @@
+../../../media/libnblog/include/media/nblog/ReportPerformance.h
\ No newline at end of file
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 34c629b..474ef97 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -32,9 +32,11 @@
 #include <hwbinder/ProcessState.h>
 
 // from LOCAL_C_INCLUDES
+#include "aaudio/AAudioTesting.h"
 #include "AudioFlinger.h"
 #include "AudioPolicyService.h"
 #include "AAudioService.h"
+#include "utility/AAudioUtilities.h"
 #include "MediaLogService.h"
 #include "SoundTriggerHwService.h"
 
@@ -131,7 +133,16 @@
         ALOGI("ServiceManager: %p", sm.get());
         AudioFlinger::instantiate();
         AudioPolicyService::instantiate();
-        AAudioService::instantiate();
+
+        // AAudioService should only be used in OC-MR1 and later.
+        // And only enable the AAudioService if the system MMAP policy explicitly allows it.
+        // This prevents a client from misusing AAudioService when it is not supported.
+        aaudio_policy_t mmapPolicy = property_get_int32(AAUDIO_PROP_MMAP_POLICY,
+                                                        AAUDIO_POLICY_NEVER);
+        if (mmapPolicy == AAUDIO_POLICY_AUTO || mmapPolicy == AAUDIO_POLICY_ALWAYS) {
+            AAudioService::instantiate();
+        }
+
         SoundTriggerHwService::instantiate();
         ProcessState::self()->startThreadPool();
 
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 78e392e..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
         }
 };
 
@@ -880,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/AudioMixer.h b/media/libaudioclient/include/media/AudioMixer.h
index 2bd2d01..dcd4a5d 100644
--- a/media/libaudioclient/include/media/AudioMixer.h
+++ b/media/libaudioclient/include/media/AudioMixer.h
@@ -25,7 +25,7 @@
 #include <media/AudioResampler.h>
 #include <media/AudioResamplerPublic.h>
 #include <media/BufferProviders.h>
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 #include <system/audio.h>
 #include <utils/Compat.h>
 #include <utils/threads.h>
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/libaudioprocessing/Android.mk b/media/libaudioprocessing/Android.mk
index c850984..da1ecc2 100644
--- a/media/libaudioprocessing/Android.mk
+++ b/media/libaudioprocessing/Android.mk
@@ -24,6 +24,7 @@
     libcutils \
     liblog \
     libnbaio \
+    libnblog \
     libsonic \
     libutils \
 
diff --git a/media/libmediametrics/MediaAnalyticsItem.cpp b/media/libmediametrics/MediaAnalyticsItem.cpp
index 30a31e6..31ac4e5 100644
--- a/media/libmediametrics/MediaAnalyticsItem.cpp
+++ b/media/libmediametrics/MediaAnalyticsItem.cpp
@@ -100,7 +100,7 @@
 
     // clean attributes
     // contents of the attributes
-    for (size_t i = 0 ; i < mPropSize; i++ ) {
+    for (size_t i = 0 ; i < mPropCount; i++ ) {
         clearProp(&mProps[i]);
     }
     // the attribute records themselves
@@ -300,7 +300,8 @@
         clearProp(prop);
         if (i != mPropCount-1) {
             // in the middle, bring last one down to fill gap
-            mProps[i] = mProps[mPropCount-1];
+            copyProp(prop, &mProps[mPropCount-1]);
+            clearProp(&mProps[mPropCount-1]);
         }
         mPropCount--;
         return true;
diff --git a/media/libnbaio/Android.bp b/media/libnbaio/Android.bp
index 4220b77..a4df38d 100644
--- a/media/libnbaio/Android.bp
+++ b/media/libnbaio/Android.bp
@@ -41,11 +41,8 @@
         "AudioBufferProviderSource.cpp",
         "AudioStreamInSource.cpp",
         "AudioStreamOutSink.cpp",
-        "NBLog.cpp",
-        "PerformanceAnalysis.cpp",
         "Pipe.cpp",
         "PipeReader.cpp",
-        "ReportPerformance.cpp",
         "SourceAudioBufferProvider.cpp",
     ],
 
diff --git a/media/libnblog/Android.bp b/media/libnblog/Android.bp
new file mode 100644
index 0000000..74aaf77
--- /dev/null
+++ b/media/libnblog/Android.bp
@@ -0,0 +1,28 @@
+cc_library_shared {
+
+    name: "libnblog",
+
+    srcs: [
+        "NBLog.cpp",
+        "PerformanceAnalysis.cpp",
+        "ReportPerformance.cpp",
+    ],
+
+    shared_libs: [
+        "libaudioutils",
+        "libbinder",
+        "libcutils",
+        "liblog",
+        "libutils",
+    ],
+
+    cflags: [
+        "-Werror",
+        "-Wall",
+    ],
+
+    include_dirs: ["system/media/audio_utils/include"],
+
+    export_include_dirs: ["include"],
+
+}
diff --git a/media/libnbaio/NBLog.cpp b/media/libnblog/NBLog.cpp
similarity index 99%
rename from media/libnbaio/NBLog.cpp
rename to media/libnblog/NBLog.cpp
index ad38390..c8c7195 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnblog/NBLog.cpp
@@ -34,9 +34,9 @@
 #include <time.h>
 #include <new>
 #include <audio_utils/roundup.h>
-#include <media/nbaio/NBLog.h>
-#include <media/nbaio/PerformanceAnalysis.h>
-#include <media/nbaio/ReportPerformance.h>
+#include <media/nblog/NBLog.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/ReportPerformance.h>
 #include <utils/CallStack.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
diff --git a/media/libnbaio/PerformanceAnalysis.cpp b/media/libnblog/PerformanceAnalysis.cpp
similarity index 98%
rename from media/libnbaio/PerformanceAnalysis.cpp
rename to media/libnblog/PerformanceAnalysis.cpp
index 9e0f84d..478c460 100644
--- a/media/libnbaio/PerformanceAnalysis.cpp
+++ b/media/libnblog/PerformanceAnalysis.cpp
@@ -33,9 +33,9 @@
 #include <time.h>
 #include <new>
 #include <audio_utils/roundup.h>
-#include <media/nbaio/NBLog.h>
-#include <media/nbaio/PerformanceAnalysis.h>
-#include <media/nbaio/ReportPerformance.h>
+#include <media/nblog/NBLog.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/ReportPerformance.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 
diff --git a/media/libnbaio/ReportPerformance.cpp b/media/libnblog/ReportPerformance.cpp
similarity index 97%
rename from media/libnbaio/ReportPerformance.cpp
rename to media/libnblog/ReportPerformance.cpp
index efc1b84..827e731 100644
--- a/media/libnbaio/ReportPerformance.cpp
+++ b/media/libnblog/ReportPerformance.cpp
@@ -27,9 +27,9 @@
 #include <sys/prctl.h>
 #include <sys/time.h>
 #include <utility>
-#include <media/nbaio/NBLog.h>
-#include <media/nbaio/PerformanceAnalysis.h>
-#include <media/nbaio/ReportPerformance.h>
+#include <media/nblog/NBLog.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/ReportPerformance.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
 
diff --git a/media/libnbaio/include/media/nbaio/NBLog.h b/media/libnblog/include/media/nblog/NBLog.h
similarity index 99%
rename from media/libnbaio/include/media/nbaio/NBLog.h
rename to media/libnblog/include/media/nblog/NBLog.h
index 2c00386..ebb88f0 100644
--- a/media/libnbaio/include/media/nbaio/NBLog.h
+++ b/media/libnblog/include/media/nblog/NBLog.h
@@ -26,8 +26,8 @@
 
 #include <audio_utils/fifo.h>
 #include <binder/IMemory.h>
-#include <media/nbaio/PerformanceAnalysis.h>
-#include <media/nbaio/ReportPerformance.h>
+#include <media/nblog/PerformanceAnalysis.h>
+#include <media/nblog/ReportPerformance.h>
 #include <utils/Mutex.h>
 #include <utils/threads.h>
 
diff --git a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
similarity index 98%
rename from media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
rename to media/libnblog/include/media/nblog/PerformanceAnalysis.h
index 50367be..ddfe9d6 100644
--- a/media/libnbaio/include/media/nbaio/PerformanceAnalysis.h
+++ b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
@@ -21,7 +21,7 @@
 #include <map>
 #include <vector>
 
-#include <media/nbaio/ReportPerformance.h>
+#include <media/nblog/ReportPerformance.h>
 
 namespace android {
 
diff --git a/media/libnbaio/include/media/nbaio/ReportPerformance.h b/media/libnblog/include/media/nblog/ReportPerformance.h
similarity index 100%
rename from media/libnbaio/include/media/nbaio/ReportPerformance.h
rename to media/libnblog/include/media/nblog/ReportPerformance.h
diff --git a/media/libstagefright/codec2/include/C2Work.h b/media/libstagefright/codec2/include/C2Work.h
index a42d11a..a378623 100644
--- a/media/libstagefright/codec2/include/C2Work.h
+++ b/media/libstagefright/codec2/include/C2Work.h
@@ -60,9 +60,9 @@
 typedef uint32_t node_id;
 
 enum flags_t : uint32_t {
-    BUFFERFLAG_CODEC_CONFIG,
-    BUFFERFLAG_DROP_FRAME,
-    BUFFERFLAG_END_OF_STREAM,
+    BUFFERFLAG_CODEC_CONFIG  = (1 << 0),
+    BUFFERFLAG_DROP_FRAME    = (1 << 1),
+    BUFFERFLAG_END_OF_STREAM = (1 << 2),
 };
 
 enum {
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/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index d0454d4..7419e64 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -51,6 +51,7 @@
     libmedialogservice \
     libmediautils \
     libnbaio \
+    libnblog \
     libpowermanager \
     libserviceutility \
     libmediautils \
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index de617b9..dff94d2 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -71,7 +71,7 @@
 
 #include <powermanager/IPowerManager.h>
 
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 #include <private/media/AudioEffectShared.h>
 #include <private/media/AudioTrackShared.h>
 
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 5a55c7a..2be1e91 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -21,7 +21,7 @@
 #include <system/audio.h>
 #include <media/ExtendedAudioBufferProvider.h>
 #include <media/nbaio/NBAIO.h>
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 #include "FastThreadState.h"
 
 namespace android {
diff --git a/services/audioflinger/FastThreadState.h b/services/audioflinger/FastThreadState.h
index f18f846..54c0dc6 100644
--- a/services/audioflinger/FastThreadState.h
+++ b/services/audioflinger/FastThreadState.h
@@ -19,7 +19,7 @@
 
 #include "Configuration.h"
 #include <stdint.h>
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 
 namespace android {
 
diff --git a/services/audioflinger/TypedLogger.h b/services/audioflinger/TypedLogger.h
index 909af09..cae74b1 100644
--- a/services/audioflinger/TypedLogger.h
+++ b/services/audioflinger/TypedLogger.h
@@ -18,7 +18,9 @@
 #ifndef ANDROID_TYPED_LOGGER_H
 #define ANDROID_TYPED_LOGGER_H
 
-#include <media/nbaio/NBLog.h>
+// This is the client API for the typed logger.
+
+#include <media/nblog/NBLog.h>
 #include <algorithm>
 
 /*
diff --git a/services/medialog/Android.mk b/services/medialog/Android.mk
index 423b186..4f2630e 100644
--- a/services/medialog/Android.mk
+++ b/services/medialog/Android.mk
@@ -4,7 +4,7 @@
 
 LOCAL_SRC_FILES := MediaLogService.cpp IMediaLogService.cpp
 
-LOCAL_SHARED_LIBRARIES := libbinder libutils liblog libnbaio libaudioutils
+LOCAL_SHARED_LIBRARIES := libbinder libutils liblog libnbaio libnblog libaudioutils
 
 LOCAL_MULTILIB := $(AUDIOSERVER_MULTILIB)
 
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index fe19b6b..1be5544 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -20,7 +20,7 @@
 #include <sys/mman.h>
 #include <utils/Log.h>
 #include <binder/PermissionCache.h>
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 #include <private/android_filesystem_config.h>
 #include "MediaLogService.h"
 
diff --git a/services/medialog/MediaLogService.h b/services/medialog/MediaLogService.h
index 39d9cc0..c945d1f 100644
--- a/services/medialog/MediaLogService.h
+++ b/services/medialog/MediaLogService.h
@@ -19,7 +19,7 @@
 
 #include <binder/BinderService.h>
 #include <media/IMediaLogService.h>
-#include <media/nbaio/NBLog.h>
+#include <media/nblog/NBLog.h>
 
 namespace android {