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(×tamps[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(×tamps[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