Merge "frameworks/av: Documentation fixes for AImage and AImageReader." into pi-dev
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 5fd4886..2829b90 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -4807,6 +4807,8 @@
* of points can be less than max (that is, the request doesn't have to
* always provide a curve with number of points equivalent to
* ACAMERA_TONEMAP_MAX_CURVE_POINTS).</p>
+ * <p>For devices with MONOCHROME capability, only red channel is used. Green and blue channels
+ * are ignored.</p>
* <p>A few examples, and their corresponding graphical mappings; these
* only specify the red channel and the precision is limited to 4
* digits, for conciseness.</p>
@@ -7094,6 +7096,12 @@
*/
ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA = 11,
+ /**
+ * <p>The camera device is a monochrome camera that doesn't contain a color filter array,
+ * and the pixel values on U and Y planes are all 128.</p>
+ */
+ ACAMERA_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12,
+
} acamera_metadata_enum_android_request_available_capabilities_t;
diff --git a/media/mtp/Android.bp b/media/mtp/Android.bp
index acea373..2cf9b82 100644
--- a/media/mtp/Android.bp
+++ b/media/mtp/Android.bp
@@ -49,7 +49,6 @@
shared_libs: [
"libasyncio",
"libbase",
- "libutils",
"liblog",
"libusbhost",
],
diff --git a/media/mtp/IMtpDatabase.h b/media/mtp/IMtpDatabase.h
index d09a984..1245092 100644
--- a/media/mtp/IMtpDatabase.h
+++ b/media/mtp/IMtpDatabase.h
@@ -24,6 +24,7 @@
class MtpDataPacket;
class MtpProperty;
class MtpObjectInfo;
+class MtpStringBuffer;
class IMtpDatabase {
public:
@@ -86,7 +87,7 @@
virtual void* getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) = 0;
virtual MtpResponseCode getObjectFilePath(MtpObjectHandle handle,
- MtpString& outFilePath,
+ MtpStringBuffer& outFilePath,
int64_t& outFileLength,
MtpObjectFormat& outFormat) = 0;
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index d1c71d7..992dc9a 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -19,6 +19,7 @@
#include "MtpDataPacket.h"
#include <algorithm>
+#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
@@ -129,7 +130,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -145,7 +146,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -161,7 +162,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -177,7 +178,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -193,7 +194,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -209,7 +210,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -225,7 +226,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
@@ -241,7 +242,7 @@
delete result;
return NULL;
}
- result->push(value);
+ result->push_back(value);
}
return result;
}
diff --git a/media/mtp/MtpDebug.h b/media/mtp/MtpDebug.h
index 5b53e31..8d48273 100644
--- a/media/mtp/MtpDebug.h
+++ b/media/mtp/MtpDebug.h
@@ -18,10 +18,10 @@
#define _MTP_DEBUG_H
// #define LOG_NDEBUG 0
-#include <utils/Log.h>
-
#include "MtpTypes.h"
+#include <log/log.h>
+
namespace android {
class MtpDebug {
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index 0bf7854..993797a 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -262,7 +262,7 @@
MtpDeviceProperty propCode = (*mDeviceInfo->mDeviceProperties)[i];
MtpProperty* property = getDevicePropDesc(propCode);
if (property)
- mDeviceProperties.push(property);
+ mDeviceProperties.push_back(property);
}
}
}
@@ -327,7 +327,7 @@
}
bool MtpDevice::openSession() {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mSessionID = 0;
mTransactionID = 0;
@@ -353,7 +353,7 @@
}
MtpDeviceInfo* MtpDevice::getDeviceInfo() {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
if (!sendRequest(MTP_OPERATION_GET_DEVICE_INFO))
@@ -372,7 +372,7 @@
}
MtpStorageIDList* MtpDevice::getStorageIDs() {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
if (!sendRequest(MTP_OPERATION_GET_STORAGE_IDS))
@@ -387,7 +387,7 @@
}
MtpStorageInfo* MtpDevice::getStorageInfo(MtpStorageID storageID) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, storageID);
@@ -408,7 +408,7 @@
MtpObjectHandleList* MtpDevice::getObjectHandles(MtpStorageID storageID,
MtpObjectFormat format, MtpObjectHandle parent) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, storageID);
@@ -426,7 +426,7 @@
}
MtpObjectInfo* MtpDevice::getObjectInfo(MtpObjectHandle handle) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
// FIXME - we might want to add some caching here
@@ -448,7 +448,7 @@
}
void* MtpDevice::getThumbnail(MtpObjectHandle handle, int& outLength) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -463,7 +463,7 @@
}
MtpObjectHandle MtpDevice::sendObjectInfo(MtpObjectInfo* info) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
MtpObjectHandle parent = info->mParent;
@@ -517,7 +517,7 @@
}
bool MtpDevice::sendObject(MtpObjectHandle handle, int size, int srcFD) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
if (mLastSendObjectInfoTransactionID + 1 != mTransactionID ||
mLastSendObjectInfoObjectHandle != handle) {
@@ -537,7 +537,7 @@
}
bool MtpDevice::deleteObject(MtpObjectHandle handle) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -572,7 +572,7 @@
}
MtpObjectPropertyList* MtpDevice::getObjectPropsSupported(MtpObjectFormat format) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, format);
@@ -589,7 +589,7 @@
}
MtpProperty* MtpDevice::getDevicePropDesc(MtpDeviceProperty code) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, code);
@@ -609,7 +609,7 @@
}
MtpProperty* MtpDevice::getObjectPropDesc(MtpObjectProperty code, MtpObjectFormat format) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, code);
@@ -633,7 +633,7 @@
if (property == nullptr)
return false;
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -684,7 +684,7 @@
ReadObjectCallback callback,
const uint32_t* expectedLength,
void* clientData) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -806,7 +806,7 @@
uint32_t *writtenSize,
ReadObjectCallback callback,
void* clientData) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -828,7 +828,7 @@
uint32_t *writtenSize,
ReadObjectCallback callback,
void* clientData) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
mRequest.reset();
mRequest.setParameter(1, handle);
@@ -908,7 +908,7 @@
}
int MtpDevice::submitEventRequest() {
- if (mEventMutex.tryLock()) {
+ if (!mEventMutex.try_lock()) {
// An event is being reaped on another thread.
return -1;
}
@@ -916,7 +916,7 @@
// An event request was submitted, but no reapEventRequest called so far.
return -1;
}
- Mutex::Autolock autoLock(mEventMutexForInterrupt);
+ std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
mEventPacket.sendRequest(mRequestIntr);
const int currentHandle = ++mCurrentEventHandle;
mProcessingEvent = true;
@@ -925,7 +925,7 @@
}
int MtpDevice::reapEventRequest(int handle, uint32_t (*parameters)[3]) {
- Mutex::Autolock autoLock(mEventMutex);
+ std::lock_guard<std::mutex> lg(mEventMutex);
if (!mProcessingEvent || mCurrentEventHandle != handle || !parameters) {
return -1;
}
@@ -940,7 +940,7 @@
}
void MtpDevice::discardEventRequest(int handle) {
- Mutex::Autolock autoLock(mEventMutexForInterrupt);
+ std::lock_guard<std::mutex> lg(mEventMutexForInterrupt);
if (mCurrentEventHandle != handle) {
return;
}
diff --git a/media/mtp/MtpDevice.h b/media/mtp/MtpDevice.h
index a9a3e0e..8cf9e5e 100644
--- a/media/mtp/MtpDevice.h
+++ b/media/mtp/MtpDevice.h
@@ -23,7 +23,7 @@
#include "MtpResponsePacket.h"
#include "MtpTypes.h"
-#include <utils/threads.h>
+#include <mutex>
struct usb_device;
struct usb_request;
@@ -67,9 +67,9 @@
MtpObjectHandle mLastSendObjectInfoObjectHandle;
// to ensure only one MTP transaction at a time
- Mutex mMutex;
- Mutex mEventMutex;
- Mutex mEventMutexForInterrupt;
+ std::mutex mMutex;
+ std::mutex mEventMutex;
+ std::mutex mEventMutexForInterrupt;
// Remember the device's packet division mode.
UrbPacketDivisionMode mPacketDivisionMode;
diff --git a/media/mtp/MtpEventPacket.h b/media/mtp/MtpEventPacket.h
index 3f3b6a3..94d6ebf 100644
--- a/media/mtp/MtpEventPacket.h
+++ b/media/mtp/MtpEventPacket.h
@@ -20,6 +20,8 @@
#include "MtpPacket.h"
#include "mtp.h"
+#include <errno.h>
+
class IMtpHandle;
namespace android {
diff --git a/media/mtp/MtpPacket.h b/media/mtp/MtpPacket.h
index d47c91d..9842b28 100644
--- a/media/mtp/MtpPacket.h
+++ b/media/mtp/MtpPacket.h
@@ -19,6 +19,7 @@
#include <android-base/macros.h>
+#include "MtpDebug.h"
#include "MtpTypes.h"
struct usb_device;
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 039e4f5..5c02a0d 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -18,6 +18,10 @@
#include <inttypes.h>
#include <cutils/compiler.h>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
#include "MtpDataPacket.h"
#include "MtpDebug.h"
#include "MtpProperty.h"
@@ -336,7 +340,7 @@
}
void MtpProperty::print() {
- MtpString buffer;
+ std::string buffer;
bool deviceProp = isDeviceProperty();
if (deviceProp)
ALOGI(" %s (%04X)", MtpDebug::getDevicePropCodeName(mCode), mCode);
@@ -346,11 +350,11 @@
ALOGI(" writeable %s", (mWriteable ? "true" : "false"));
buffer = " default value: ";
print(mDefaultValue, buffer);
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
if (deviceProp) {
buffer = " current value: ";
print(mCurrentValue, buffer);
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
}
switch (mFormFlag) {
case kFormNone:
@@ -363,7 +367,7 @@
buffer += ", ";
print(mStepSize, buffer);
buffer += ")";
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
break;
case kFormEnum:
buffer = " Enum { ";
@@ -372,7 +376,7 @@
buffer += " ";
}
buffer += "}";
- ALOGI("%s", (const char *)buffer);
+ ALOGI("%s", buffer.c_str());
break;
case kFormDateTime:
ALOGI(" DateTime\n");
@@ -383,42 +387,47 @@
}
}
-void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
+void MtpProperty::print(MtpPropertyValue& value, std::string& buffer) {
+ std::ostringstream s;
switch (mType) {
case MTP_TYPE_INT8:
- buffer.appendFormat("%d", value.u.i8);
+ buffer += std::to_string(value.u.i8);
break;
case MTP_TYPE_UINT8:
- buffer.appendFormat("%d", value.u.u8);
+ buffer += std::to_string(value.u.u8);
break;
case MTP_TYPE_INT16:
- buffer.appendFormat("%d", value.u.i16);
+ buffer += std::to_string(value.u.i16);
break;
case MTP_TYPE_UINT16:
- buffer.appendFormat("%d", value.u.u16);
+ buffer += std::to_string(value.u.u16);
break;
case MTP_TYPE_INT32:
- buffer.appendFormat("%d", value.u.i32);
+ buffer += std::to_string(value.u.i32);
break;
case MTP_TYPE_UINT32:
- buffer.appendFormat("%d", value.u.u32);
+ buffer += std::to_string(value.u.u32);
break;
case MTP_TYPE_INT64:
- buffer.appendFormat("%" PRId64, value.u.i64);
+ buffer += std::to_string(value.u.i64);
break;
case MTP_TYPE_UINT64:
- buffer.appendFormat("%" PRIu64, value.u.u64);
+ buffer += std::to_string(value.u.u64);
break;
case MTP_TYPE_INT128:
- buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
- value.u.i128[2], value.u.i128[3]);
+ for (auto i : value.u.i128) {
+ s << std::hex << std::setfill('0') << std::uppercase << i;
+ }
+ buffer += s.str();
break;
case MTP_TYPE_UINT128:
- buffer.appendFormat("%08X%08X%08X%08X", value.u.u128[0], value.u.u128[1],
- value.u.u128[2], value.u.u128[3]);
+ for (auto i : value.u.u128) {
+ s << std::hex << std::setfill('0') << std::uppercase << i;
+ }
+ buffer += s.str();
break;
case MTP_TYPE_STR:
- buffer.appendFormat("%s", value.str);
+ buffer += value.str;
break;
default:
ALOGE("unsupported type for MtpProperty::print\n");
diff --git a/media/mtp/MtpProperty.h b/media/mtp/MtpProperty.h
index 03c08e1..bfd5f7f 100644
--- a/media/mtp/MtpProperty.h
+++ b/media/mtp/MtpProperty.h
@@ -19,6 +19,8 @@
#include "MtpTypes.h"
+#include <string>
+
namespace android {
class MtpDataPacket;
@@ -97,7 +99,6 @@
void setFormDateTime();
void print();
- void print(MtpPropertyValue& value, MtpString& buffer);
inline bool isDeviceProperty() const {
return ( ((mCode & 0xF000) == 0x5000)
@@ -110,6 +111,7 @@
MtpPropertyValue* readArrayValues(MtpDataPacket& packet, uint32_t& length);
void writeArrayValues(MtpDataPacket& packet,
MtpPropertyValue* values, uint32_t length);
+ void print(MtpPropertyValue& value, std::string& buffer);
};
}; // namespace android
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index e4ac8b0..86d59dd 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -102,10 +102,10 @@
};
MtpServer::MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
- const MtpString& deviceInfoManufacturer,
- const MtpString& deviceInfoModel,
- const MtpString& deviceInfoDeviceVersion,
- const MtpString& deviceInfoSerialNumber)
+ const char *deviceInfoManufacturer,
+ const char *deviceInfoModel,
+ const char *deviceInfoDeviceVersion,
+ const char *deviceInfoSerialNumber)
: mDatabase(database),
mPtp(ptp),
mDeviceInfoManufacturer(deviceInfoManufacturer),
@@ -132,14 +132,14 @@
}
void MtpServer::addStorage(MtpStorage* storage) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
- mStorages.push(storage);
+ mStorages.push_back(storage);
sendStoreAdded(storage->getStorageID());
}
void MtpServer::removeStorage(MtpStorage* storage) {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
auto iter = std::find(mStorages.begin(), mStorages.end(), storage);
if (iter != mStorages.end()) {
sendStoreRemoved(storage->getStorageID());
@@ -284,10 +284,10 @@
}
}
-void MtpServer::addEditObject(MtpObjectHandle handle, MtpString& path,
+void MtpServer::addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
uint64_t size, MtpObjectFormat format, int fd) {
ObjectEdit* edit = new ObjectEdit(handle, path, size, format, fd);
- mObjectEditList.add(edit);
+ mObjectEditList.push_back(edit);
}
MtpServer::ObjectEdit* MtpServer::getEditObject(MtpObjectHandle handle) {
@@ -305,7 +305,7 @@
ObjectEdit* edit = mObjectEditList[i];
if (edit->mHandle == handle) {
delete edit;
- mObjectEditList.removeAt(i);
+ mObjectEditList.erase(mObjectEditList.begin() + i);
return;
}
}
@@ -318,7 +318,7 @@
bool MtpServer::handleRequest() {
- Mutex::Autolock autoLock(mMutex);
+ std::lock_guard<std::mutex> lg(mMutex);
MtpOperationCode operation = mRequest.getOperationCode();
MtpResponseCode response;
@@ -769,7 +769,7 @@
if (mRequest.getParameterCount() < 1)
return MTP_RESPONSE_INVALID_PARAMETER;
MtpObjectHandle handle = mRequest.getParameter(1);
- MtpString pathBuf;
+ MtpStringBuffer pathBuf;
int64_t fileLength;
MtpObjectFormat format;
int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -855,7 +855,7 @@
// standard GetPartialObject
length = mRequest.getParameter(3);
}
- MtpString pathBuf;
+ MtpStringBuffer pathBuf;
int64_t fileLength;
MtpObjectFormat format;
int result = mDatabase->getObjectFilePath(handle, pathBuf, fileLength, format);
@@ -892,7 +892,7 @@
}
MtpResponseCode MtpServer::doSendObjectInfo() {
- MtpString path;
+ MtpStringBuffer path;
uint16_t temp16;
uint32_t temp32;
@@ -906,7 +906,7 @@
// special case the root
if (parent == MTP_PARENT_ROOT) {
- path = storage->getPath();
+ path.set(storage->getPath());
parent = 0;
} else {
int64_t length;
@@ -938,7 +938,7 @@
if (!mData.getUInt32(temp32)) return MTP_RESPONSE_INVALID_PARAMETER; // sequence number
MtpStringBuffer name, created, modified;
if (!mData.getString(name)) return MTP_RESPONSE_INVALID_PARAMETER; // file name
- if (name.getCharCount() == 0) {
+ if (name.isEmpty()) {
ALOGE("empty name");
return MTP_RESPONSE_INVALID_PARAMETER;
}
@@ -952,8 +952,8 @@
modifiedTime = 0;
if (path[path.size() - 1] != '/')
- path += "/";
- path += (const char *)name;
+ path.append("/");
+ path.append(name);
// check space first
if (mSendObjectFileSize > storage->getFreeSpace())
@@ -1006,10 +1006,10 @@
MtpObjectHandle parent = mRequest.getParameter(3);
if (!storage)
return MTP_RESPONSE_INVALID_STORAGE_ID;
- MtpString path;
+ MtpStringBuffer path;
MtpResponseCode result;
- MtpString fromPath;
+ MtpStringBuffer fromPath;
int64_t fileLength;
MtpObjectFormat format;
MtpObjectInfo info(objectHandle);
@@ -1022,7 +1022,7 @@
// special case the root
if (parent == 0) {
- path = storage->getPath();
+ path.set(storage->getPath());
} else {
int64_t parentLength;
MtpObjectFormat parentFormat;
@@ -1034,8 +1034,8 @@
}
if (path[path.size() - 1] != '/')
- path += "/";
- path += info.mName;
+ path.append("/");
+ path.append(info.mName);
result = mDatabase->beginMoveObject(objectHandle, parent, storageID);
if (result != MTP_RESPONSE_OK)
@@ -1085,9 +1085,9 @@
MtpObjectHandle parent = mRequest.getParameter(3);
if (!storage)
return MTP_RESPONSE_INVALID_STORAGE_ID;
- MtpString path;
+ MtpStringBuffer path;
- MtpString fromPath;
+ MtpStringBuffer fromPath;
int64_t fileLength;
MtpObjectFormat format;
MtpObjectInfo info(objectHandle);
@@ -1100,7 +1100,7 @@
// special case the root
if (parent == 0) {
- path = storage->getPath();
+ path.set(storage->getPath());
} else {
int64_t parentLength;
MtpObjectFormat parentFormat;
@@ -1116,8 +1116,8 @@
return MTP_RESPONSE_STORAGE_FULL;
if (path[path.size() - 1] != '/')
- path += "/";
- path += info.mName;
+ path.append("/");
+ path.append(info.mName);
MtpObjectHandle handle = mDatabase->beginCopyObject(objectHandle, parent, storageID);
if (handle == kInvalidObjectHandle) {
@@ -1264,7 +1264,7 @@
// FIXME - support deleting all objects if handle is 0xFFFFFFFF
// FIXME - implement deleting objects by format
- MtpString filePath;
+ MtpStringBuffer filePath;
int64_t fileLength;
int result = mDatabase->getObjectFilePath(handle, filePath, fileLength, format);
if (result != MTP_RESPONSE_OK)
@@ -1414,7 +1414,7 @@
return MTP_RESPONSE_GENERAL_ERROR;
}
- MtpString path;
+ MtpStringBuffer path;
int64_t fileLength;
MtpObjectFormat format;
int result = mDatabase->getObjectFilePath(handle, path, fileLength, format);
diff --git a/media/mtp/MtpServer.h b/media/mtp/MtpServer.h
index e633c52..f6939d7 100644
--- a/media/mtp/MtpServer.h
+++ b/media/mtp/MtpServer.h
@@ -21,14 +21,14 @@
#include "MtpDataPacket.h"
#include "MtpResponsePacket.h"
#include "MtpEventPacket.h"
+#include "MtpStringBuffer.h"
#include "mtp.h"
#include "MtpUtils.h"
#include "IMtpHandle.h"
-#include <utils/threads.h>
-#include <queue>
#include <memory>
#include <mutex>
+#include <queue>
namespace android {
@@ -44,13 +44,13 @@
bool mPtp;
// Manufacturer to report in DeviceInfo
- MtpString mDeviceInfoManufacturer;
+ MtpStringBuffer mDeviceInfoManufacturer;
// Model to report in DeviceInfo
- MtpString mDeviceInfoModel;
+ MtpStringBuffer mDeviceInfoModel;
// Device version to report in DeviceInfo
- MtpString mDeviceInfoDeviceVersion;
+ MtpStringBuffer mDeviceInfoDeviceVersion;
// Serial number to report in DeviceInfo
- MtpString mDeviceInfoSerialNumber;
+ MtpStringBuffer mDeviceInfoSerialNumber;
// current session ID
MtpSessionID mSessionID;
@@ -70,18 +70,18 @@
// handle for new object, set by SendObjectInfo and used by SendObject
MtpObjectHandle mSendObjectHandle;
MtpObjectFormat mSendObjectFormat;
- MtpString mSendObjectFilePath;
+ MtpStringBuffer mSendObjectFilePath;
size_t mSendObjectFileSize;
time_t mSendObjectModifiedTime;
- Mutex mMutex;
+ std::mutex mMutex;
// represents an MTP object that is being edited using the android extensions
// for direct editing (BeginEditObject, SendPartialObject, TruncateObject and EndEditObject)
class ObjectEdit {
public:
MtpObjectHandle mHandle;
- MtpString mPath;
+ MtpStringBuffer mPath;
uint64_t mSize;
MtpObjectFormat mFormat;
int mFD;
@@ -95,14 +95,14 @@
close(mFD);
}
};
- Vector<ObjectEdit*> mObjectEditList;
+ std::vector<ObjectEdit*> mObjectEditList;
public:
MtpServer(IMtpDatabase* database, int controlFd, bool ptp,
- const MtpString& deviceInfoManufacturer,
- const MtpString& deviceInfoModel,
- const MtpString& deviceInfoDeviceVersion,
- const MtpString& deviceInfoSerialNumber);
+ const char *deviceInfoManufacturer,
+ const char *deviceInfoModel,
+ const char *deviceInfoDeviceVersion,
+ const char *deviceInfoSerialNumber);
virtual ~MtpServer();
MtpStorage* getStorage(MtpStorageID id);
@@ -122,7 +122,7 @@
void sendStoreRemoved(MtpStorageID id);
void sendEvent(MtpEventCode code, uint32_t param1);
- void addEditObject(MtpObjectHandle handle, MtpString& path,
+ void addEditObject(MtpObjectHandle handle, MtpStringBuffer& path,
uint64_t size, MtpObjectFormat format, int fd);
ObjectEdit* getEditObject(MtpObjectHandle handle);
void removeEditObject(MtpObjectHandle handle);
diff --git a/media/mtp/MtpStorage.h b/media/mtp/MtpStorage.h
index cb7e333..e9518dd 100644
--- a/media/mtp/MtpStorage.h
+++ b/media/mtp/MtpStorage.h
@@ -17,6 +17,7 @@
#ifndef _MTP_STORAGE_H
#define _MTP_STORAGE_H
+#include "MtpStringBuffer.h"
#include "MtpTypes.h"
#include "mtp.h"
@@ -28,8 +29,8 @@
private:
MtpStorageID mStorageID;
- MtpString mFilePath;
- MtpString mDescription;
+ MtpStringBuffer mFilePath;
+ MtpStringBuffer mDescription;
uint64_t mMaxCapacity;
uint64_t mMaxFileSize;
bool mRemovable;
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index df04694..cd379bf 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -16,168 +16,97 @@
#define LOG_TAG "MtpStringBuffer"
-#include <string.h>
+#include <codecvt>
+#include <locale>
+#include <string>
+#include <vector>
#include "MtpDataPacket.h"
#include "MtpStringBuffer.h"
-namespace android {
+namespace {
-MtpStringBuffer::MtpStringBuffer()
- : mCharCount(0),
- mByteCount(1)
-{
- mBuffer[0] = 0;
+std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> gConvert;
+
+static std::string utf16ToUtf8(std::u16string input_str) {
+ return gConvert.to_bytes(input_str);
}
+static std::u16string utf8ToUtf16(std::string input_str) {
+ return gConvert.from_bytes(input_str);
+}
+
+} // namespace
+
+namespace android {
+
MtpStringBuffer::MtpStringBuffer(const char* src)
- : mCharCount(0),
- mByteCount(1)
{
set(src);
}
MtpStringBuffer::MtpStringBuffer(const uint16_t* src)
- : mCharCount(0),
- mByteCount(1)
{
set(src);
}
MtpStringBuffer::MtpStringBuffer(const MtpStringBuffer& src)
- : mCharCount(src.mCharCount),
- mByteCount(src.mByteCount)
{
- memcpy(mBuffer, src.mBuffer, mByteCount);
-}
-
-
-MtpStringBuffer::~MtpStringBuffer() {
+ mString = src.mString;
}
void MtpStringBuffer::set(const char* src) {
- // count the characters
- int count = 0;
- char ch;
- char* dest = (char*)mBuffer;
-
- while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
- if ((ch & 0x80) == 0) {
- // single byte character
- *dest++ = ch;
- } else if ((ch & 0xE0) == 0xC0) {
- // two byte character
- char ch1 = *src++;
- if (! ch1) {
- // last character was truncated, so ignore last byte
- break;
- }
-
- *dest++ = ch;
- *dest++ = ch1;
- } else if ((ch & 0xF0) == 0xE0) {
- // 3 byte char
- char ch1 = *src++;
- if (! ch1) {
- // last character was truncated, so ignore last byte
- break;
- }
- char ch2 = *src++;
- if (! ch2) {
- // last character was truncated, so ignore last byte
- break;
- }
-
- *dest++ = ch;
- *dest++ = ch1;
- *dest++ = ch2;
- }
- count++;
- }
-
- *dest++ = 0;
- mByteCount = dest - (char*)mBuffer;
- mCharCount = count;
+ mString = std::string(src);
}
void MtpStringBuffer::set(const uint16_t* src) {
- int count = 0;
- uint16_t ch;
- uint8_t* dest = mBuffer;
-
- while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
- if (ch >= 0x0800) {
- *dest++ = (uint8_t)(0xE0 | (ch >> 12));
- *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
- *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
- } else if (ch >= 0x80) {
- *dest++ = (uint8_t)(0xC0 | (ch >> 6));
- *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
- } else {
- *dest++ = ch;
- }
- count++;
- }
- *dest++ = 0;
- mCharCount = count;
- mByteCount = dest - mBuffer;
+ mString = utf16ToUtf8(std::u16string((const char16_t*)src));
}
bool MtpStringBuffer::readFromPacket(MtpDataPacket* packet) {
uint8_t count;
if (!packet->getUInt8(count))
return false;
+ if (count == 0)
+ return true;
- uint8_t* dest = mBuffer;
+ std::vector<char16_t> buffer(count);
for (int i = 0; i < count; i++) {
uint16_t ch;
-
if (!packet->getUInt16(ch))
return false;
- if (ch >= 0x0800) {
- *dest++ = (uint8_t)(0xE0 | (ch >> 12));
- *dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
- *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
- } else if (ch >= 0x80) {
- *dest++ = (uint8_t)(0xC0 | (ch >> 6));
- *dest++ = (uint8_t)(0x80 | (ch & 0x3F));
- } else {
- *dest++ = ch;
- }
+ buffer[i] = ch;
}
- *dest++ = 0;
- mCharCount = count;
- mByteCount = dest - mBuffer;
+ if (buffer[count-1] != '\0') {
+ ALOGE("Mtp string not null terminated\n");
+ return false;
+ }
+ mString = utf16ToUtf8(std::u16string(buffer.data()));
return true;
}
void MtpStringBuffer::writeToPacket(MtpDataPacket* packet) const {
- int count = mCharCount;
- const uint8_t* src = mBuffer;
- packet->putUInt8(count > 0 ? count + 1 : 0);
+ std::u16string src16 = utf8ToUtf16(mString);
+ int count = src16.length();
- // expand utf8 to 16 bit chars
- for (int i = 0; i < count; i++) {
- uint16_t ch;
- uint16_t ch1 = *src++;
- if ((ch1 & 0x80) == 0) {
- // single byte character
- ch = ch1;
- } else if ((ch1 & 0xE0) == 0xC0) {
- // two byte character
- uint16_t ch2 = *src++;
- ch = ((ch1 & 0x1F) << 6) | (ch2 & 0x3F);
- } else {
- // three byte character
- uint16_t ch2 = *src++;
- uint16_t ch3 = *src++;
- ch = ((ch1 & 0x0F) << 12) | ((ch2 & 0x3F) << 6) | (ch3 & 0x3F);
+ if (count == 0) {
+ packet->putUInt8(0);
+ return;
+ }
+ packet->putUInt8(std::min(count + 1, MTP_STRING_MAX_CHARACTER_NUMBER));
+
+ int i = 0;
+ for (char16_t &c : src16) {
+ if (i == MTP_STRING_MAX_CHARACTER_NUMBER - 1) {
+ // Leave a slot for null termination.
+ ALOGI("Mtp truncating long string\n");
+ break;
}
- packet->putUInt16(ch);
+ packet->putUInt16(c);
+ i++;
}
// only terminate with zero if string is not empty
- if (count > 0)
- packet->putUInt16(0);
+ packet->putUInt16(0);
}
} // namespace android
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index bcf2a48..4cec58a 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -17,7 +17,9 @@
#ifndef _MTP_STRING_BUFFER_H
#define _MTP_STRING_BUFFER_H
+#include <log/log.h>
#include <stdint.h>
+#include <string>
// Max Character number of a MTP String
#define MTP_STRING_MAX_CHARACTER_NUMBER 255
@@ -30,31 +32,39 @@
class MtpStringBuffer {
private:
- // mBuffer contains string in UTF8 format
- // maximum 3 bytes/character, with 1 extra for zero termination
- uint8_t mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1];
- int mCharCount;
- int mByteCount;
+ std::string mString;
public:
- MtpStringBuffer();
+ MtpStringBuffer() {};
+ ~MtpStringBuffer() {};
+
explicit MtpStringBuffer(const char* src);
explicit MtpStringBuffer(const uint16_t* src);
MtpStringBuffer(const MtpStringBuffer& src);
- virtual ~MtpStringBuffer();
void set(const char* src);
void set(const uint16_t* src);
+ inline void append(const char* other);
+ inline void append(MtpStringBuffer &other);
+
bool readFromPacket(MtpDataPacket* packet);
void writeToPacket(MtpDataPacket* packet) const;
- inline int getCharCount() const { return mCharCount; }
- inline int getByteCount() const { return mByteCount; }
+ inline bool isEmpty() const { return mString.empty(); }
+ inline int size() const { return mString.length(); }
- inline operator const char*() const { return (const char *)mBuffer; }
+ inline operator const char*() const { return mString.c_str(); }
};
+inline void MtpStringBuffer::append(const char* other) {
+ mString += other;
+}
+
+inline void MtpStringBuffer::append(MtpStringBuffer &other) {
+ mString += other.mString;
+}
+
}; // namespace android
#endif // _MTP_STRING_BUFFER_H
diff --git a/media/mtp/MtpTypes.h b/media/mtp/MtpTypes.h
index c749c66..e6ac23c 100644
--- a/media/mtp/MtpTypes.h
+++ b/media/mtp/MtpTypes.h
@@ -18,8 +18,7 @@
#define _MTP_TYPES_H
#include <stdint.h>
-#include "utils/String8.h"
-#include "utils/Vector.h"
+#include <vector>
namespace android {
@@ -51,18 +50,18 @@
class MtpDevice;
class MtpProperty;
-typedef Vector<MtpStorage *> MtpStorageList;
-typedef Vector<MtpDevice*> MtpDeviceList;
-typedef Vector<MtpProperty*> MtpPropertyList;
+typedef std::vector<MtpStorage *> MtpStorageList;
+typedef std::vector<MtpDevice*> MtpDeviceList;
+typedef std::vector<MtpProperty*> MtpPropertyList;
-typedef Vector<uint8_t> UInt8List;
-typedef Vector<uint16_t> UInt16List;
-typedef Vector<uint32_t> UInt32List;
-typedef Vector<uint64_t> UInt64List;
-typedef Vector<int8_t> Int8List;
-typedef Vector<int16_t> Int16List;
-typedef Vector<int32_t> Int32List;
-typedef Vector<int64_t> Int64List;
+typedef std::vector<uint8_t> UInt8List;
+typedef std::vector<uint16_t> UInt16List;
+typedef std::vector<uint32_t> UInt32List;
+typedef std::vector<uint64_t> UInt64List;
+typedef std::vector<int8_t> Int8List;
+typedef std::vector<int16_t> Int16List;
+typedef std::vector<int32_t> Int32List;
+typedef std::vector<int64_t> Int64List;
typedef UInt16List MtpObjectPropertyList;
typedef UInt16List MtpDevicePropertyList;
@@ -71,8 +70,6 @@
typedef UInt16List MtpObjectPropertyList;
typedef UInt32List MtpStorageIDList;
-typedef String8 MtpString;
-
enum UrbPacketDivisionMode {
// First packet only contains a header.
FIRST_PACKET_ONLY_HEADER,
diff --git a/media/mtp/tests/MtpFfsHandle_test.cpp b/media/mtp/tests/MtpFfsHandle_test.cpp
index 2174893..d11fe07 100644
--- a/media/mtp/tests/MtpFfsHandle_test.cpp
+++ b/media/mtp/tests/MtpFfsHandle_test.cpp
@@ -23,7 +23,7 @@
#include <random>
#include <string>
#include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
#include "MtpDescriptors.h"
#include "MtpFfsHandle.h"
diff --git a/media/mtp/tests/PosixAsyncIO_test.cpp b/media/mtp/tests/PosixAsyncIO_test.cpp
index 63b9a35..9e337aa 100644
--- a/media/mtp/tests/PosixAsyncIO_test.cpp
+++ b/media/mtp/tests/PosixAsyncIO_test.cpp
@@ -20,7 +20,7 @@
#include <gtest/gtest.h>
#include <string>
#include <unistd.h>
-#include <utils/Log.h>
+#include <log/log.h>
#include "PosixAsyncIO.h"
diff --git a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
index 2e247f2..1a35970 100644
--- a/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
+++ b/packages/MediaComponents/res/drawable/custom_progress_thumb.xml
@@ -17,6 +17,6 @@
android:shape="oval" >
<solid android:color="#ffffff" />
<size
- android:height="12dp"
- android:width="12dp" />
+ android:height="@dimen/mcv2_custom_progress_thumb_size"
+ android:width="@dimen/mcv2_custom_progress_thumb_size" />
</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/drawable/ic_default_album_image.xml b/packages/MediaComponents/res/drawable/ic_default_album_image.xml
new file mode 100644
index 0000000..1cee643
--- /dev/null
+++ b/packages/MediaComponents/res/drawable/ic_default_album_image.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="512dp"
+ android:height="512dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+
+ <path
+ android:fillColor="#616161"
+ android:pathData="M 0 0 H 512 V 512 H 0 V 0 Z" />
+ <path
+ android:fillColor="#525252"
+ android:pathData="M256,151v123.14c-6.88-4.02-14.82-6.48-23.33-6.48 c-25.78,0-46.67,20.88-46.67,46.67c0,25.78,20.88,46.67,46.67,46.67s46.67-20.88,46.67-46.67V197.67H326V151H256z" />
+</vector>
diff --git a/packages/MediaComponents/res/layout/embedded_music.xml b/packages/MediaComponents/res/layout/embedded_music.xml
new file mode 100644
index 0000000..3e4d365
--- /dev/null
+++ b/packages/MediaComponents/res/layout/embedded_music.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.25"/>
+
+ <ImageView
+ android:id="@+id/album"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.5"
+ android:scaleType="fitCenter"
+ android:src="@drawable/ic_default_album_image" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="0.25"/>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_landscape_music.xml b/packages/MediaComponents/res/layout/full_landscape_music.xml
new file mode 100644
index 0000000..8ce7058
--- /dev/null
+++ b/packages/MediaComponents/res/layout/full_landscape_music.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="#B300FF00"
+ android:orientation="horizontal">
+
+ <LinearLayout
+ android:id="@+id/music_image"
+ style="@style/FullMusicLandscape.Image">
+
+ <ImageView
+ android:id="@+id/album"
+ android:layout_width="@dimen/mcv2_full_album_image_landscape_size"
+ android:layout_height="@dimen/mcv2_full_album_image_landscape_size"
+ android:src="@drawable/ic_default_album_image"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/music_text"
+ style="@style/FullMusicLandscape.Text">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/mcv2_music_title_unknown_text"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ android:textColor="#FFFFFF" />
+ <TextView
+ android:id="@+id/artist"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/mcv2_music_artist_unknown_text"
+ android:textSize="16sp"
+ android:textColor="#BBBBBB" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/full_portrait_music.xml b/packages/MediaComponents/res/layout/full_portrait_music.xml
new file mode 100644
index 0000000..75f1bb3
--- /dev/null
+++ b/packages/MediaComponents/res/layout/full_portrait_music.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <LinearLayout
+ android:id="@+id/music_image"
+ style="@style/FullMusicPortrait.Image">
+
+ <ImageView
+ android:id="@+id/album"
+ android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+ android:layout_height="@dimen/mcv2_full_album_image_portrait_size"
+ android:src="@drawable/ic_default_album_image"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/music_text"
+ style="@style/FullMusicPortrait.Text">
+
+ <TextView
+ android:id="@+id/title"
+ android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+ android:layout_height="wrap_content"
+ android:text="@string/mcv2_music_title_unknown_text"
+ android:textSize="20sp"
+ android:textStyle="bold"
+ android:textColor="#FFFFFF" />
+ <TextView
+ android:id="@+id/artist"
+ android:layout_width="@dimen/mcv2_full_album_image_portrait_size"
+ android:layout_height="wrap_content"
+ android:text="@string/mcv2_music_artist_unknown_text"
+ android:textSize="16sp"
+ android:textColor="#BBBBBB" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/media_controller.xml b/packages/MediaComponents/res/layout/media_controller.xml
index dfda840..4658f04 100644
--- a/packages/MediaComponents/res/layout/media_controller.xml
+++ b/packages/MediaComponents/res/layout/media_controller.xml
@@ -17,14 +17,12 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="#55000000"
android:orientation="vertical"
android:layoutDirection="ltr">
<RelativeLayout
android:id="@+id/title_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:background="@layout/title_bar_gradient"
style="@style/TitleBar">
<LinearLayout
@@ -116,22 +114,51 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:gravity="center">
+ android:gravity="center"
+ android:orientation="vertical">
</LinearLayout>
- <SeekBar
- android:id="@+id/mediacontroller_progress"
- android:contentDescription="@string/mcv2_seek_bar_desc"
+ <LinearLayout
+ android:id="@+id/minimal_extra_view"
android:layout_width="match_parent"
- android:layout_height="12dp"
- android:maxHeight="2dp"
- android:minHeight="2dp"
- android:padding="0dp"/>
+ android:layout_height="wrap_content"
+ android:gravity="right">
+
+ <ImageButton
+ android:id="@+id/fullscreen"
+ android:gravity="right"
+ style="@style/BottomBarButton.FullScreen" />
+ </LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
+ android:layout_height="@dimen/mcv2_custom_progress_thumb_size">
+
+ <SeekBar
+ android:id="@+id/progress"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/mcv2_custom_progress_thumb_size"
+ android:contentDescription="@string/mcv2_seek_bar_desc"
+ android:padding="0dp"
+ android:maxHeight="@dimen/mcv2_custom_progress_max_size"
+ android:minHeight="@dimen/mcv2_custom_progress_max_size"
+ android:elevation="10dp"/>
+
+ <View
+ android:id="@+id/progress_buffer"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/mcv2_buffer_view_height"
+ android:layout_alignParentBottom="true"
+ android:background="@color/bottom_bar_background"
+ android:elevation="0dp"/>
+ </RelativeLayout>
+
+ <RelativeLayout
+ android:id="@+id/bottom_bar"
+ android:layout_width="match_parent"
android:layout_height="44dp"
- android:orientation="horizontal">
+ android:orientation="horizontal"
+ android:background="@color/bottom_bar_background">
<LinearLayout
android:id="@+id/bottom_bar_left"
diff --git a/packages/MediaComponents/res/layout/minimal_transport_controls.xml b/packages/MediaComponents/res/layout/minimal_transport_controls.xml
index 9ca3721..800c80b 100644
--- a/packages/MediaComponents/res/layout/minimal_transport_controls.xml
+++ b/packages/MediaComponents/res/layout/minimal_transport_controls.xml
@@ -18,8 +18,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
- android:orientation="horizontal"
- android:visibility="visible">
+ android:orientation="horizontal">
- <ImageButton android:id="@+id/pause" style="@style/MinimalTransportControlsButton.Pause" />
+ <ImageButton android:id="@+id/pause" style="@style/MinimalTransportControlsButton" />
</LinearLayout>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/layout/title_bar_gradient.xml b/packages/MediaComponents/res/layout/title_bar_gradient.xml
new file mode 100644
index 0000000..ab1fc6e
--- /dev/null
+++ b/packages/MediaComponents/res/layout/title_bar_gradient.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2018 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:startColor="@color/title_bar_gradient_start"
+ android:endColor="@color/title_bar_gradient_end"
+ android:angle="-270" />
+</shape>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/colors.xml b/packages/MediaComponents/res/values/colors.xml
index 6a65ef5..e7bc299 100644
--- a/packages/MediaComponents/res/values/colors.xml
+++ b/packages/MediaComponents/res/values/colors.xml
@@ -19,4 +19,7 @@
<color name="white">#ffffff</color>
<color name="white_opacity_70">#B3ffffff</color>
<color name="black_opacity_70">#B3000000</color>
+ <color name="title_bar_gradient_start">#50000000</color>
+ <color name="title_bar_gradient_end">#00000000</color>
+ <color name="bottom_bar_background">#40202020</color>
</resources>
\ No newline at end of file
diff --git a/packages/MediaComponents/res/values/dimens.xml b/packages/MediaComponents/res/values/dimens.xml
index 8d72d40..2d7b022 100644
--- a/packages/MediaComponents/res/values/dimens.xml
+++ b/packages/MediaComponents/res/values/dimens.xml
@@ -62,5 +62,11 @@
<dimen name="mcv2_minimal_icon_size">24dp</dimen>
<dimen name="mcv2_icon_margin">10dp</dimen>
+ <dimen name="mcv2_full_album_image_portrait_size">232dp</dimen>
+ <dimen name="mcv2_full_album_image_landscape_size">176dp</dimen>
+
+ <dimen name="mcv2_custom_progress_max_size">2dp</dimen>
+ <dimen name="mcv2_custom_progress_thumb_size">12dp</dimen>
+ <dimen name="mcv2_buffer_view_height">5dp</dimen>
<!-- TODO: adjust bottom bar view -->
</resources>
diff --git a/packages/MediaComponents/res/values/strings.xml b/packages/MediaComponents/res/values/strings.xml
index aaceac8..2597a3b 100644
--- a/packages/MediaComponents/res/values/strings.xml
+++ b/packages/MediaComponents/res/values/strings.xml
@@ -129,6 +129,10 @@
<string name="MediaControlView2_audio_track_number_text">
Track <xliff:g id="audio_number" example="1">%1$s</xliff:g>
</string>
+ <!-- Text for displaying unknown song title. -->
+ <string name="mcv2_music_title_unknown_text">Song title unknown</string>
+ <!-- Text for displaying unknown artist name. -->
+ <string name="mcv2_music_artist_unknown_text">Artist unknown</string>
<!--Content Descriptions -->
<string name="mcv2_back_button_desc">Back</string>
diff --git a/packages/MediaComponents/res/values/style.xml b/packages/MediaComponents/res/values/style.xml
index 0be04e6..5b9a8ee 100644
--- a/packages/MediaComponents/res/values/style.xml
+++ b/packages/MediaComponents/res/values/style.xml
@@ -84,18 +84,19 @@
<style name="MinimalTransportControlsButton">
<item name="android:background">@null</item>
+ <item name="android:layout_width">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_height">@dimen/mcv2_pause_icon_size</item>
+ <item name="android:layout_margin">@dimen/mcv2_icon_margin</item>
<item name="android:scaleType">fitXY</item>
- </style>
-
- <style name="MinimalTransportControlsButton.Pause">
<item name="android:src">@drawable/ic_pause_circle_filled</item>
- <item name="android:layout_width">@dimen/mcv2_minimal_icon_size</item>
- <item name="android:layout_height">@dimen/mcv2_minimal_icon_size</item>
<item name="android:contentDescription">@string/mcv2_pause_button_desc</item>
</style>
<style name="TitleBar">
+ <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">46dp</item>
+ <item name="android:paddingStart">5dp</item>
+ <item name="android:paddingEnd">5dp</item>
</style>
<style name="TitleBarButton">
@@ -182,4 +183,39 @@
<item name="android:src">@drawable/ic_high_quality</item>
<item name="android:contentDescription">@string/mcv2_video_quality_button_desc</item>
</style>
+
+ <style name="FullMusicPortrait">
+ <item name="android:layout_height">0dp</item>
+ </style>
+
+ <style name="FullMusicPortrait.Image">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_weight">0.6</item>
+ <item name="android:gravity">center</item>
+ </style>
+
+ <style name="FullMusicPortrait.Text">
+ <item name="android:layout_width">match_parent</item>
+ <item name="android:layout_weight">0.4</item>
+ <item name="android:gravity">top|center</item>
+ <item name="android:orientation">vertical</item>
+ </style>
+
+ <style name="FullMusicLandscape">
+ <item name="android:layout_width">0dp</item>
+ </style>
+
+ <style name="FullMusicLandscape.Image">
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_weight">0.35</item>
+ <item name="android:gravity">center|right</item>
+ </style>
+
+ <style name="FullMusicLandscape.Text">
+ <item name="android:layout_height">match_parent</item>
+ <item name="android:layout_weight">0.65</item>
+ <item name="android:layout_marginLeft">24dp</item>
+ <item name="android:gravity">center|left</item>
+ <item name="android:orientation">vertical</item>
+ </style>
</resources>
diff --git a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
index 4cdc41d..3aff150 100644
--- a/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/MediaControlView2Impl.java
@@ -16,7 +16,9 @@
package com.android.widget;
+import android.content.Context;
import android.content.res.Resources;
+import android.graphics.Point;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.PlaybackState;
@@ -31,6 +33,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
@@ -102,6 +105,10 @@
private static final int SETTINGS_MODE_MAIN = 5;
private static final int PLAYBACK_SPEED_1x_INDEX = 3;
+ private static final int MEDIA_TYPE_DEFAULT = 0;
+ private static final int MEDIA_TYPE_MUSIC = 1;
+ private static final int MEDIA_TYPE_ADVERTISEMENT = 2;
+
private static final int SIZE_TYPE_EMBEDDED = 0;
private static final int SIZE_TYPE_FULL = 1;
// TODO: add support for Minimal size type.
@@ -123,6 +130,7 @@
private int mDuration;
private int mPrevState;
private int mPrevWidth;
+ private int mPrevHeight;
private int mOriginalLeftBarWidth;
private int mVideoTrackCount;
private int mAudioTrackCount;
@@ -137,8 +145,8 @@
private int mEmbeddedSettingsItemHeight;
private int mFullSettingsItemHeight;
private int mSettingsWindowMargin;
+ private int mMediaType;
private int mSizeType;
- private int mOrientation;
private long mPlaybackActions;
private boolean mDragging;
private boolean mIsFullScreen;
@@ -148,9 +156,10 @@
private boolean mSeekAvailable;
private boolean mIsAdvertisement;
private boolean mIsMute;
+ private boolean mNeedUXUpdate;
// Relating to Title Bar View
- private View mRoot;
+ private ViewGroup mRoot;
private View mTitleBar;
private TextView mTitleView;
private View mAdExternalLink;
@@ -167,8 +176,15 @@
private ImageButton mNextButton;
private ImageButton mPrevButton;
+ // Relating to Minimal Extra View
+ private LinearLayout mMinimalExtraView;
+
// Relating to Progress Bar View
private ProgressBar mProgress;
+ private View mProgressBuffer;
+
+ // Relating to Bottom Bar View
+ private ViewGroup mBottomBar;
// Relating to Bottom Bar Left View
private ViewGroup mBottomBarLeftView;
@@ -334,28 +350,63 @@
public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
- if (mPrevWidth != mInstance.getMeasuredWidth()) {
- int currWidth = mInstance.getMeasuredWidth();
+ // Update layout when this view's width changes in order to avoid any UI overlap between
+ // transport controls.
+ if (mPrevWidth != mInstance.getMeasuredWidth()
+ || mPrevHeight != mInstance.getMeasuredHeight() || mNeedUXUpdate) {
+ // Dismiss SettingsWindow if it is showing.
+ mSettingsWindow.dismiss();
- int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
- int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
- int bottomBarRightWidthMax = iconSize * 4 + marginSize * 8;
-
- int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
- + bottomBarRightWidthMax;
// These views may not have been initialized yet.
if (mTransportControls.getWidth() == 0 || mTimeView.getWidth() == 0) {
return;
}
- if (mSizeType == SIZE_TYPE_EMBEDDED && fullWidth <= currWidth) {
- updateLayoutForSizeChange(SIZE_TYPE_FULL);
- } else if (mSizeType == SIZE_TYPE_FULL && fullWidth > currWidth) {
- updateLayoutForSizeChange(SIZE_TYPE_EMBEDDED);
+
+ int currWidth = mInstance.getMeasuredWidth();
+ int currHeight = mInstance.getMeasuredHeight();
+ WindowManager manager = (WindowManager) mInstance.getContext().getApplicationContext()
+ .getSystemService(Context.WINDOW_SERVICE);
+ Point screenSize = new Point();
+ manager.getDefaultDisplay().getSize(screenSize);
+ int screenWidth = screenSize.x;
+ int screenHeight = screenSize.y;
+ int fullIconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_full_icon_size);
+ int embeddedIconSize = mResources.getDimensionPixelSize(
+ R.dimen.mcv2_embedded_icon_size);
+ int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
+
+ // TODO: add support for Advertisement Mode.
+ if (mMediaType == MEDIA_TYPE_DEFAULT) {
+ // Max number of icons inside BottomBarRightView for Music mode is 4.
+ int maxIconCount = 4;
+ updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+ currHeight, screenWidth, screenHeight);
+ } else if (mMediaType == MEDIA_TYPE_MUSIC) {
+ if (mNeedUXUpdate) {
+ // One-time operation for Music media type
+ mBasicControls.removeView(mMuteButton);
+ mExtraControls.addView(mMuteButton, 0);
+ mVideoQualityButton.setVisibility(View.GONE);
+ if (mFfwdButton != null) {
+ mFfwdButton.setVisibility(View.GONE);
+ }
+ if (mRewButton != null) {
+ mRewButton.setVisibility(View.GONE);
+ }
+ }
+ mNeedUXUpdate = false;
+
+ // Max number of icons inside BottomBarRightView for Music mode is 3.
+ int maxIconCount = 3;
+ updateLayout(maxIconCount, fullIconSize, embeddedIconSize, marginSize, currWidth,
+ currHeight, screenWidth, screenHeight);
}
- // Dismiss SettingsWindow if it is showing.
- mSettingsWindow.dismiss();
mPrevWidth = currWidth;
+ mPrevHeight = currHeight;
}
+ // TODO: move this to a different location.
+ // Update title bar parameters in order to avoid overlap between title view and the right
+ // side of the title bar.
updateTitleBarLayout();
}
@@ -468,13 +519,14 @@
* @return The controller view.
* @hide This doesn't work as advertised
*/
- protected View makeControllerView() {
- View root = ApiHelper.inflateLibLayout(mInstance.getContext(), R.layout.media_controller);
+ protected ViewGroup makeControllerView() {
+ ViewGroup root = (ViewGroup) ApiHelper.inflateLibLayout(mInstance.getContext(),
+ R.layout.media_controller);
initControllerView(root);
return root;
}
- private void initControllerView(View v) {
+ private void initControllerView(ViewGroup v) {
// Relating to Title Bar View
mTitleBar = v.findViewById(R.id.title_bar);
mTitleView = v.findViewById(R.id.title_text);
@@ -482,6 +534,7 @@
mBackButton = v.findViewById(R.id.back);
if (mBackButton != null) {
mBackButton.setOnClickListener(mBackListener);
+ mBackButton.setVisibility(View.GONE);
}
mRouteButton = v.findViewById(R.id.cast);
@@ -490,8 +543,18 @@
mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
mCenterView.addView(mTransportControls);
+ // Relating to Minimal Extra View
+ mMinimalExtraView = (LinearLayout) v.findViewById(R.id.minimal_extra_view);
+ LinearLayout.LayoutParams params =
+ (LinearLayout.LayoutParams) mMinimalExtraView.getLayoutParams();
+ int iconSize = mResources.getDimensionPixelSize(R.dimen.mcv2_embedded_icon_size);
+ int marginSize = mResources.getDimensionPixelSize(R.dimen.mcv2_icon_margin);
+ params.setMargins(0, (iconSize + marginSize * 2) * (-1), 0, 0);
+ mMinimalExtraView.setLayoutParams(params);
+ mMinimalExtraView.setVisibility(View.GONE);
+
// Relating to Progress Bar View
- mProgress = v.findViewById(R.id.mediacontroller_progress);
+ mProgress = v.findViewById(R.id.progress);
if (mProgress != null) {
if (mProgress instanceof SeekBar) {
SeekBar seeker = (SeekBar) mProgress;
@@ -501,6 +564,10 @@
}
mProgress.setMax(MAX_PROGRESS);
}
+ mProgressBuffer = v.findViewById(R.id.progress_buffer);
+
+ // Relating to Bottom Bar View
+ mBottomBar = v.findViewById(R.id.bottom_bar);
// Relating to Bottom Bar Left View
mBottomBarLeftView = v.findViewById(R.id.bottom_bar_left);
@@ -757,11 +824,11 @@
return;
}
if (mDuration > 0) {
- int newPosition = (int) (((long) mDuration * progress) / MAX_PROGRESS);
- mControls.seekTo(newPosition);
+ int position = (int) (((long) mDuration * progress) / MAX_PROGRESS);
+ mControls.seekTo(position);
if (mCurrentTime != null) {
- mCurrentTime.setText(stringForTime(newPosition));
+ mCurrentTime.setText(stringForTime(position));
}
}
}
@@ -862,7 +929,7 @@
}
Bundle args = new Bundle();
args.putBoolean(ARGUMENT_KEY_FULLSCREEN, isEnteringFullScreen);
- mController.sendCommand(MediaControlView2Impl.COMMAND_SET_FULLSCREEN, args, null);
+ mController.sendCommand(COMMAND_SET_FULLSCREEN, args, null);
mIsFullScreen = isEnteringFullScreen;
}
@@ -1040,6 +1107,34 @@
}
}
+ private void updateAudioMetadata() {
+ if (mMediaType != MEDIA_TYPE_MUSIC) {
+ return;
+ }
+
+ if (mMetadata != null) {
+ String titleText = "";
+ String artistText = "";
+ if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+ titleText = mMetadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+ } else {
+ titleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
+ }
+
+ if (mMetadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+ artistText = mMetadata.getString(MediaMetadata.METADATA_KEY_ARTIST);
+ } else {
+ artistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
+ }
+
+ // Update title for Embedded size type
+ mTitleView.setText(titleText + " - " + artistText);
+
+ // Set to true to update layout inside onMeasure()
+ mNeedUXUpdate = true;
+ }
+ }
+
private void updateLayout() {
if (mIsAdvertisement) {
mRewButton.setVisibility(View.GONE);
@@ -1071,38 +1166,135 @@
}
}
+ private void updateLayout(int maxIconCount, int fullIconSize, int embeddedIconSize,
+ int marginSize, int currWidth, int currHeight, int screenWidth, int screenHeight) {
+ int fullBottomBarRightWidthMax = fullIconSize * maxIconCount
+ + marginSize * (maxIconCount * 2);
+ int embeddedBottomBarRightWidthMax = embeddedIconSize * maxIconCount
+ + marginSize * (maxIconCount * 2);
+ int fullWidth = mTransportControls.getWidth() + mTimeView.getWidth()
+ + fullBottomBarRightWidthMax;
+ int embeddedWidth = mTimeView.getWidth() + embeddedBottomBarRightWidthMax;
+ int screenMaxLength = Math.max(screenWidth, screenHeight);
+
+ if (fullWidth > screenMaxLength) {
+ // TODO: screen may be smaller than the length needed for Full size.
+ }
+
+ boolean isFullSize = (mMediaType == MEDIA_TYPE_DEFAULT) ? (currWidth == screenMaxLength) :
+ (currWidth == screenWidth && currHeight == screenHeight);
+
+ if (isFullSize) {
+ if (mSizeType != SIZE_TYPE_FULL) {
+ updateLayoutForSizeChange(SIZE_TYPE_FULL);
+ if (mMediaType == MEDIA_TYPE_MUSIC) {
+ mTitleView.setVisibility(View.GONE);
+ }
+ }
+ } else if (embeddedWidth <= currWidth) {
+ if (mSizeType != SIZE_TYPE_EMBEDDED) {
+ updateLayoutForSizeChange(SIZE_TYPE_EMBEDDED);
+ if (mMediaType == MEDIA_TYPE_MUSIC) {
+ mTitleView.setVisibility(View.VISIBLE);
+ }
+ }
+ } else {
+ if (mSizeType != SIZE_TYPE_MINIMAL) {
+ updateLayoutForSizeChange(SIZE_TYPE_MINIMAL);
+ if (mMediaType == MEDIA_TYPE_MUSIC) {
+ mTitleView.setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+
private void updateLayoutForSizeChange(int sizeType) {
mSizeType = sizeType;
- RelativeLayout.LayoutParams params =
+ RelativeLayout.LayoutParams timeViewParams =
(RelativeLayout.LayoutParams) mTimeView.getLayoutParams();
+ SeekBar seeker = (SeekBar) mProgress;
switch (mSizeType) {
case SIZE_TYPE_EMBEDDED:
+ // Relating to Title Bar
+ mTitleBar.setVisibility(View.VISIBLE);
+ mBackButton.setVisibility(View.GONE);
+
+ // Relating to Full Screen Button
+ mMinimalExtraView.setVisibility(View.GONE);
+ mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
+ mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+ // Relating to Center View
+ mCenterView.removeAllViews();
mBottomBarLeftView.removeView(mTransportControls);
mBottomBarLeftView.setVisibility(View.GONE);
mTransportControls = inflateTransportControls(R.layout.embedded_transport_controls);
- mCenterView.addView(mTransportControls, 0);
+ mCenterView.addView(mTransportControls);
- if (params.getRule(RelativeLayout.LEFT_OF) != 0) {
- params.removeRule(RelativeLayout.LEFT_OF);
- params.addRule(RelativeLayout.RIGHT_OF, R.id.bottom_bar_left);
+ // Relating to Progress Bar
+ seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
+ mProgressBuffer.setVisibility(View.VISIBLE);
+
+ // Relating to Bottom Bar
+ mBottomBar.setVisibility(View.VISIBLE);
+ if (timeViewParams.getRule(RelativeLayout.LEFT_OF) != 0) {
+ timeViewParams.removeRule(RelativeLayout.LEFT_OF);
+ timeViewParams.addRule(RelativeLayout.RIGHT_OF, R.id.bottom_bar_left);
}
break;
case SIZE_TYPE_FULL:
- mCenterView.removeView(mTransportControls);
+ // Relating to Title Bar
+ mTitleBar.setVisibility(View.VISIBLE);
+ mBackButton.setVisibility(View.VISIBLE);
+
+ // Relating to Full Screen Button
+ mMinimalExtraView.setVisibility(View.GONE);
+ mFullScreenButton = mBottomBarRightView.findViewById(R.id.fullscreen);
+ mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+ // Relating to Center View
+ mCenterView.removeAllViews();
+ mBottomBarLeftView.removeView(mTransportControls);
mTransportControls = inflateTransportControls(R.layout.full_transport_controls);
mBottomBarLeftView.addView(mTransportControls, 0);
mBottomBarLeftView.setVisibility(View.VISIBLE);
- if (params.getRule(RelativeLayout.RIGHT_OF) != 0) {
- params.removeRule(RelativeLayout.RIGHT_OF);
- params.addRule(RelativeLayout.LEFT_OF, R.id.bottom_bar_right);
+ // Relating to Progress Bar
+ seeker.setThumb(mResources.getDrawable(R.drawable.custom_progress_thumb));
+ mProgressBuffer.setVisibility(View.VISIBLE);
+
+ // Relating to Bottom Bar
+ mBottomBar.setVisibility(View.VISIBLE);
+ if (timeViewParams.getRule(RelativeLayout.RIGHT_OF) != 0) {
+ timeViewParams.removeRule(RelativeLayout.RIGHT_OF);
+ timeViewParams.addRule(RelativeLayout.LEFT_OF, R.id.bottom_bar_right);
}
break;
case SIZE_TYPE_MINIMAL:
- // TODO: implement
+ // Relating to Title Bar
+ mTitleBar.setVisibility(View.GONE);
+ mBackButton.setVisibility(View.GONE);
+
+ // Relating to Full Screen Button
+ mMinimalExtraView.setVisibility(View.VISIBLE);
+ mFullScreenButton = mMinimalExtraView.findViewById(R.id.fullscreen);
+ mFullScreenButton.setOnClickListener(mFullScreenListener);
+
+ // Relating to Center View
+ mCenterView.removeAllViews();
+ mBottomBarLeftView.removeView(mTransportControls);
+ mTransportControls = inflateTransportControls(R.layout.minimal_transport_controls);
+ mCenterView.addView(mTransportControls);
+
+ // Relating to Progress Bar
+ seeker.setThumb(null);
+ mProgressBuffer.setVisibility(View.GONE);
+
+ // Relating to Bottom Bar
+ mBottomBar.setVisibility(View.GONE);
break;
}
- mTimeView.setLayoutParams(params);
+ mTimeView.setLayoutParams(timeViewParams);
if (isPlaying()) {
mPlayPauseButton.setImageDrawable(
@@ -1115,6 +1307,14 @@
mPlayPauseButton.setContentDescription(
mResources.getString(R.string.mcv2_play_button_desc));
}
+
+ if (mIsFullScreen) {
+ mFullScreenButton.setImageDrawable(
+ mResources.getDrawable(R.drawable.ic_fullscreen_exit, null));
+ } else {
+ mFullScreenButton.setImageDrawable(
+ mResources.getDrawable(R.drawable.ic_fullscreen, null));
+ }
}
private View inflateTransportControls(int layoutId) {
@@ -1127,10 +1327,16 @@
mFfwdButton = v.findViewById(R.id.ffwd);
if (mFfwdButton != null) {
mFfwdButton.setOnClickListener(mFfwdListener);
+ if (mMediaType == MEDIA_TYPE_MUSIC) {
+ mFfwdButton.setVisibility(View.GONE);
+ }
}
mRewButton = v.findViewById(R.id.rew);
if (mRewButton != null) {
mRewButton.setOnClickListener(mRewListener);
+ if (mMediaType == MEDIA_TYPE_MUSIC) {
+ mRewButton.setVisibility(View.GONE);
+ }
}
// TODO: Add support for Next and Previous buttons
mNextButton = v.findViewById(R.id.next);
@@ -1250,11 +1456,17 @@
if ((newActions & PlaybackState.ACTION_PAUSE) != 0) {
mPlayPauseButton.setVisibility(View.VISIBLE);
}
- if ((newActions & PlaybackState.ACTION_REWIND) != 0) {
- mRewButton.setVisibility(View.VISIBLE);
+ if ((newActions & PlaybackState.ACTION_REWIND) != 0
+ && mMediaType != MEDIA_TYPE_MUSIC) {
+ if (mRewButton != null) {
+ mRewButton.setVisibility(View.VISIBLE);
+ }
}
- if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
- mFfwdButton.setVisibility(View.VISIBLE);
+ if ((newActions & PlaybackState.ACTION_FAST_FORWARD) != 0
+ && mMediaType != MEDIA_TYPE_MUSIC) {
+ if (mFfwdButton != null) {
+ mFfwdButton.setVisibility(View.VISIBLE);
+ }
}
if ((newActions & PlaybackState.ACTION_SEEK_TO) != 0) {
mSeekAvailable = true;
@@ -1295,6 +1507,7 @@
mMetadata = metadata;
updateDuration();
updateTitle();
+ updateAudioMetadata();
}
@Override
@@ -1321,6 +1534,9 @@
mAudioTrackList.add(mResources.getString(
R.string.MediaControlView2_audio_track_none_text));
}
+ if (mVideoTrackCount == 0 && mAudioTrackCount > 0) {
+ mMediaType = MEDIA_TYPE_MUSIC;
+ }
mSubtitleTrackCount = extras.getInt(KEY_SUBTITLE_TRACK_COUNT);
mSubtitleDescriptionsList = new ArrayList<String>();
diff --git a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
index 46ae359..b2acc26 100644
--- a/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
+++ b/packages/MediaComponents/src/com/android/widget/VideoView2Impl.java
@@ -17,6 +17,13 @@
package com.android.widget;
import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Point;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
import android.media.AudioManager;
@@ -29,6 +36,7 @@
import android.media.SubtitleData;
import android.media.MediaItem2;
import android.media.MediaMetadata2;
+import android.media.MediaMetadataRetriever;
import android.media.Metadata;
import android.media.PlaybackParams;
import android.media.TimedText;
@@ -45,19 +53,26 @@
import android.os.ResultReceiver;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
+import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
+import android.widget.ImageView;
import android.widget.MediaControlView2;
+import android.widget.TextView;
import android.widget.VideoView2;
+import com.android.internal.graphics.palette.Palette;
import com.android.media.RoutePlayer;
import com.android.media.subtitle.ClosedCaptionRenderer;
import com.android.media.subtitle.SubtitleController;
import com.android.media.subtitle.SubtitleTrack;
+import com.android.media.update.ApiHelper;
+import com.android.media.update.R;
import com.android.support.mediarouter.media.MediaItemStatus;
import com.android.support.mediarouter.media.MediaControlIntent;
import com.android.support.mediarouter.media.MediaRouter;
@@ -87,6 +102,11 @@
private static final int INVALID_TRACK_INDEX = -1;
private static final float INVALID_SPEED = 0f;
+ private static final int SIZE_TYPE_EMBEDDED = 0;
+ private static final int SIZE_TYPE_FULL = 1;
+ // TODO: add support for Minimal size type.
+ private static final int SIZE_TYPE_MINIMAL = 2;
+
private AccessibilityManager mAccessibilityManager;
private AudioManager mAudioManager;
private AudioAttributes mAudioAttributes;
@@ -107,10 +127,24 @@
private MediaController mMediaController;
private Metadata mMetadata;
private MediaMetadata2 mMediaMetadata;
+ private MediaMetadataRetriever mRetriever;
private boolean mNeedUpdateMediaType;
private Bundle mMediaTypeData;
private String mTitle;
+ // TODO: move music view inside SurfaceView/TextureView or implement VideoViewInterface.
+ private WindowManager mManager;
+ private Resources mResources;
+ private View mMusicView;
+ private Drawable mMusicAlbumDrawable;
+ private String mMusicTitleText;
+ private String mMusicArtistText;
+ private boolean mIsMusicMediaType;
+ private int mPrevWidth;
+ private int mPrevHeight;
+ private int mDominantColor;
+ private int mSizeType;
+
private PlaybackState.Builder mStateBuilder;
private List<PlaybackState.CustomAction> mCustomActionList;
private int mTargetState = STATE_IDLE;
@@ -259,10 +293,8 @@
mInstance.addView(mSurfaceView);
mCurrentView = mSurfaceView;
- LayoutParams subtitleParams = new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
mSubtitleView = new SubtitleView(mInstance.getContext());
- mSubtitleView.setLayoutParams(subtitleParams);
+ mSubtitleView.setLayoutParams(params);
mSubtitleView.setBackgroundColor(0);
mInstance.addView(mSubtitleView);
@@ -492,6 +524,14 @@
// TODO: remove this after moving MediaSession creating code inside initializing VideoView2
if (mCurrentState == STATE_PREPARED) {
extractTracks();
+ extractMetadata();
+ extractAudioMetadata();
+ if (mNeedUpdateMediaType) {
+ mMediaSession.sendSessionEvent(
+ MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
+ mMediaTypeData);
+ mNeedUpdateMediaType = false;
+ }
}
}
@@ -516,7 +556,9 @@
+ ", mTargetState=" + mTargetState);
}
if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- toggleMediaControlViewVisibility();
+ if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+ toggleMediaControlViewVisibility();
+ }
}
return super.onTouchEvent_impl(ev);
@@ -525,7 +567,9 @@
@Override
public boolean onTrackballEvent_impl(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) {
- toggleMediaControlViewVisibility();
+ if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) {
+ toggleMediaControlViewVisibility();
+ }
}
return super.onTrackballEvent_impl(ev);
@@ -537,6 +581,48 @@
return super.dispatchTouchEvent_impl(ev);
}
+ @Override
+ public void onMeasure_impl(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure_impl(widthMeasureSpec, heightMeasureSpec);
+
+ if (mIsMusicMediaType) {
+ if (mPrevWidth != mInstance.getMeasuredWidth()
+ || mPrevHeight != mInstance.getMeasuredHeight()) {
+ int currWidth = mInstance.getMeasuredWidth();
+ int currHeight = mInstance.getMeasuredHeight();
+ Point screenSize = new Point();
+ mManager.getDefaultDisplay().getSize(screenSize);
+ int screenWidth = screenSize.x;
+ int screenHeight = screenSize.y;
+
+ if (currWidth == screenWidth && currHeight == screenHeight) {
+ int orientation = retrieveOrientation();
+ if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+ inflateMusicView(R.layout.full_landscape_music);
+ } else {
+ inflateMusicView(R.layout.full_portrait_music);
+ }
+
+ if (mSizeType != SIZE_TYPE_FULL) {
+ mSizeType = SIZE_TYPE_FULL;
+ // Remove existing mFadeOut callback
+ mMediaControlView.removeCallbacks(mFadeOut);
+ mMediaControlView.setVisibility(View.VISIBLE);
+ }
+ } else {
+ if (mSizeType != SIZE_TYPE_EMBEDDED) {
+ mSizeType = SIZE_TYPE_EMBEDDED;
+ inflateMusicView(R.layout.embedded_music);
+ // Add new mFadeOut callback
+ mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs);
+ }
+ }
+ mPrevWidth = currWidth;
+ mPrevHeight = currHeight;
+ }
+ }
+ }
+
///////////////////////////////////////////////////
// Implements VideoViewInterface.SurfaceListener
///////////////////////////////////////////////////
@@ -663,6 +749,8 @@
if (scheme != null && scheme.equals("file")) {
mTitle = uri.getLastPathSegment();
}
+ mRetriever = new MediaMetadataRetriever();
+ mRetriever.setDataSource(mInstance.getContext(), uri);
if (DEBUG) {
Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState
@@ -798,7 +886,8 @@
private void showController() {
// TODO: Decide what to show when the state is not in playback state
- if (mMediaControlView == null || !isInPlaybackState()) {
+ if (mMediaControlView == null || !isInPlaybackState()
+ || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) {
return;
}
mMediaControlView.removeCallbacks(mFadeOut);
@@ -898,6 +987,9 @@
if (mAudioTrackIndices.size() > 0) {
mSelectedAudioTrackIndex = 0;
}
+ if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) {
+ mIsMusicMediaType = true;
+ }
Bundle data = new Bundle();
data.putInt(MediaControlView2Impl.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size());
@@ -909,6 +1001,110 @@
mMediaSession.sendSessionEvent(MediaControlView2Impl.EVENT_UPDATE_TRACK_STATUS, data);
}
+ private void extractMetadata() {
+ // Get and set duration and title values as MediaMetadata for MediaControlView2
+ MediaMetadata.Builder builder = new MediaMetadata.Builder();
+ if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
+ mTitle = mMetadata.getString(Metadata.TITLE);
+ }
+ builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
+ builder.putLong(
+ MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
+
+ if (mMediaSession != null) {
+ mMediaSession.setMetadata(builder.build());
+ }
+ }
+
+ private void extractAudioMetadata() {
+ if (!mIsMusicMediaType) {
+ return;
+ }
+
+ mResources = ApiHelper.getLibResources(mInstance.getContext());
+ mManager = (WindowManager) mInstance.getContext().getApplicationContext()
+ .getSystemService(Context.WINDOW_SERVICE);
+
+ byte[] album = mRetriever.getEmbeddedPicture();
+ if (album != null) {
+ Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length);
+ mMusicAlbumDrawable = new BitmapDrawable(bitmap);
+
+ // TODO: replace with visualizer
+ Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
+ public void onGenerated(Palette palette) {
+ // TODO: add dominant color for default album image.
+ mDominantColor = palette.getDominantColor(0);
+ if (mMusicView != null) {
+ mMusicView.setBackgroundColor(mDominantColor);
+ }
+ }
+ });
+ } else {
+ mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image);
+ }
+
+ String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+ if (title != null) {
+ mMusicTitleText = title;
+ } else {
+ mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text);
+ }
+
+ String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST);
+ if (artist != null) {
+ mMusicArtistText = artist;
+ } else {
+ mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text);
+ }
+
+ // Send title and artist string to MediaControlView2
+ MediaMetadata.Builder builder = new MediaMetadata.Builder();
+ builder.putString(MediaMetadata.METADATA_KEY_TITLE, mMusicTitleText);
+ builder.putString(MediaMetadata.METADATA_KEY_ARTIST, mMusicArtistText);
+ mMediaSession.setMetadata(builder.build());
+
+ // Display Embedded mode as default
+ mInstance.removeView(mSurfaceView);
+ mInstance.removeView(mTextureView);
+ inflateMusicView(R.layout.embedded_music);
+ }
+
+ private int retrieveOrientation() {
+ DisplayMetrics dm = Resources.getSystem().getDisplayMetrics();
+ int width = dm.widthPixels;
+ int height = dm.heightPixels;
+
+ return (height > width) ?
+ ActivityInfo.SCREEN_ORIENTATION_PORTRAIT :
+ ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+ }
+
+ private void inflateMusicView(int layoutId) {
+ mInstance.removeView(mMusicView);
+
+ View v = ApiHelper.inflateLibLayout(mInstance.getContext(), layoutId);
+ v.setBackgroundColor(mDominantColor);
+
+ ImageView albumView = v.findViewById(R.id.album);
+ if (albumView != null) {
+ albumView.setImageDrawable(mMusicAlbumDrawable);
+ }
+
+ TextView titleView = v.findViewById(R.id.title);
+ if (titleView != null) {
+ titleView.setText(mMusicTitleText);
+ }
+
+ TextView artistView = v.findViewById(R.id.artist);
+ if (artistView != null) {
+ artistView.setText(mMusicArtistText);
+ }
+
+ mMusicView = v;
+ mInstance.addView(mMusicView, 0);
+ }
+
OnSubtitleDataListener mSubtitleListener =
new OnSubtitleDataListener() {
@Override
@@ -994,6 +1190,14 @@
}
}
+ @Override
+ public void onCallCompleted(MediaPlayer2 mp, DataSourceDesc dsd, int what,
+ int status) {
+ if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO && status == 0) {
+ updatePlaybackState();
+ }
+ }
+
private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) {
if (DEBUG) {
Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState
@@ -1007,6 +1211,8 @@
// TODO: create MediaSession when initializing VideoView2
if (mMediaSession != null) {
extractTracks();
+ extractMetadata();
+ extractAudioMetadata();
}
if (mMediaControlView != null) {
@@ -1046,27 +1252,6 @@
mMediaController.getTransportControls().play();
}
}
- // Get and set duration and title values as MediaMetadata for MediaControlView2
- MediaMetadata.Builder builder = new MediaMetadata.Builder();
- if (mMetadata != null && mMetadata.has(Metadata.TITLE)) {
- mTitle = mMetadata.getString(Metadata.TITLE);
- }
- builder.putString(MediaMetadata.METADATA_KEY_TITLE, mTitle);
- builder.putLong(
- MediaMetadata.METADATA_KEY_DURATION, mMediaPlayer.getDuration());
-
- if (mMediaSession != null) {
- mMediaSession.setMetadata(builder.build());
-
- // TODO: merge this code with the above code when integrating with
- // MediaSession2.
- if (mNeedUpdateMediaType) {
- mMediaSession.sendSessionEvent(
- MediaControlView2Impl.EVENT_UPDATE_MEDIA_TYPE_STATUS,
- mMediaTypeData);
- mNeedUpdateMediaType = false;
- }
- }
}
private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) {
@@ -1153,7 +1338,7 @@
@Override
public void onPlay() {
- if (isInPlaybackState() && mCurrentView.hasAvailableSurface()) {
+ if (isInPlaybackState() && (mCurrentView.hasAvailableSurface() || mIsMusicMediaType)) {
if (isRemotePlayback()) {
mRoutePlayer.onPlay();
} else {
@@ -1200,7 +1385,6 @@
} else {
mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC);
mSeekWhenPrepared = 0;
- updatePlaybackState();
}
} else {
mSeekWhenPrepared = pos;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 9ed6d73..714d50f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -904,7 +904,7 @@
}
// Make sure the UID is in an active state to use the camera
- if (!mUidPolicy->isUidActive(callingUid)) {
+ if (!mUidPolicy->isUidActive(callingUid, String16(clientName8))) {
ALOGE("Access Denial: can't use the camera from an idle UID pid=%d, uid=%d",
clientPid, clientUid);
return STATUS_ERROR_FMT(ERROR_DISABLED,
@@ -2423,12 +2423,12 @@
}
}
-bool CameraService::UidPolicy::isUidActive(uid_t uid) {
+bool CameraService::UidPolicy::isUidActive(uid_t uid, String16 callingPackage) {
Mutex::Autolock _l(mUidLock);
- return isUidActiveLocked(uid);
+ return isUidActiveLocked(uid, callingPackage);
}
-bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid) {
+bool CameraService::UidPolicy::isUidActiveLocked(uid_t uid, String16 callingPackage) {
// Non-app UIDs are considered always active
// If activity manager is unreachable, assume everything is active
if (uid < FIRST_APPLICATION_UID || !mRegistered) {
@@ -2438,15 +2438,31 @@
if (it != mOverrideUids.end()) {
return it->second;
}
- return mActiveUids.find(uid) != mActiveUids.end();
+ bool active = mActiveUids.find(uid) != mActiveUids.end();
+ if (!active) {
+ // We want active UIDs to always access camera with their first attempt since
+ // there is no guarantee the app is robustly written and would retry getting
+ // the camera on failure. The inverse case is not a problem as we would take
+ // camera away soon once we get the callback that the uid is no longer active.
+ ActivityManager am;
+ // Okay to access with a lock held as UID changes are dispatched without
+ // a lock and we are a higher level component.
+ active = am.isUidActive(uid, callingPackage);
+ if (active) {
+ // Now that we found out the UID is actually active, cache that
+ mActiveUids.insert(uid);
+ }
+ }
+ return active;
}
-void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid, bool active) {
- updateOverrideUid(uid, active, true);
+void CameraService::UidPolicy::UidPolicy::addOverrideUid(uid_t uid,
+ String16 callingPackage, bool active) {
+ updateOverrideUid(uid, callingPackage, active, true);
}
-void CameraService::UidPolicy::removeOverrideUid(uid_t uid) {
- updateOverrideUid(uid, false, false);
+void CameraService::UidPolicy::removeOverrideUid(uid_t uid, String16 callingPackage) {
+ updateOverrideUid(uid, callingPackage, false, false);
}
void CameraService::UidPolicy::binderDied(const wp<IBinder>& /*who*/) {
@@ -2456,17 +2472,18 @@
mActiveUids.clear();
}
-void CameraService::UidPolicy::updateOverrideUid(uid_t uid, bool active, bool insert) {
+void CameraService::UidPolicy::updateOverrideUid(uid_t uid, String16 callingPackage,
+ bool active, bool insert) {
bool wasActive = false;
bool isActive = false;
{
Mutex::Autolock _l(mUidLock);
- wasActive = isUidActiveLocked(uid);
+ wasActive = isUidActiveLocked(uid, callingPackage);
mOverrideUids.erase(uid);
if (insert) {
mOverrideUids.insert(std::pair<uid_t, bool>(uid, active));
}
- isActive = isUidActiveLocked(uid);
+ isActive = isUidActiveLocked(uid, callingPackage);
}
if (wasActive != isActive && !isActive) {
sp<CameraService> service = mService.promote();
@@ -2999,7 +3016,7 @@
ALOGE("Expected active or idle but got: '%s'", String8(args[2]).string());
return BAD_VALUE;
}
- mUidPolicy->addOverrideUid(uid, active);
+ mUidPolicy->addOverrideUid(uid, args[1], active);
return NO_ERROR;
}
@@ -3011,7 +3028,7 @@
dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
return BAD_VALUE;
}
- mUidPolicy->removeOverrideUid(uid);
+ mUidPolicy->removeOverrideUid(uid, args[1]);
return NO_ERROR;
}
@@ -3023,7 +3040,7 @@
dprintf(err, "Unknown package: '%s'\n", String8(args[1]).string());
return BAD_VALUE;
}
- if (mUidPolicy->isUidActive(uid)) {
+ if (mUidPolicy->isUidActive(uid, args[1])) {
return dprintf(out, "active\n");
} else {
return dprintf(out, "idle\n");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a7a9264..8d4bcdb 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -526,20 +526,20 @@
void registerSelf();
void unregisterSelf();
- bool isUidActive(uid_t uid);
+ bool isUidActive(uid_t uid, String16 callingPackage);
void onUidGone(uid_t uid, bool disabled);
void onUidActive(uid_t uid);
void onUidIdle(uid_t uid, bool disabled);
- void addOverrideUid(uid_t uid, bool active);
- void removeOverrideUid(uid_t uid);
+ void addOverrideUid(uid_t uid, String16 callingPackage, bool active);
+ void removeOverrideUid(uid_t uid, String16 callingPackage);
// IBinder::DeathRecipient implementation
virtual void binderDied(const wp<IBinder> &who);
private:
- bool isUidActiveLocked(uid_t uid);
- void updateOverrideUid(uid_t uid, bool active, bool insert);
+ bool isUidActiveLocked(uid_t uid, String16 callingPackage);
+ void updateOverrideUid(uid_t uid, String16 callingPackage, bool active, bool insert);
Mutex mUidLock;
bool mRegistered;