MTP: work in progress on expanded property support

GetObjectPropValue and SetObjectPropValue are disabled until I figure out
why Windows doesn't like what I have done.

Change-Id: I74e945ef3ea031f6d46f4ebaa8df815da0a5c3ed
Signed-off-by: Mike Lockwood <lockwood@android.com>
This commit is contained in:
Mike Lockwood
2010-08-10 15:20:35 -04:00
parent 9650f128b2
commit 828d19dd96
8 changed files with 226 additions and 73 deletions

View File

@@ -311,9 +311,12 @@ public final class Mtp
// Object properties we support
public static final int PROPERTY_STORAGE_ID = 0xDC01;
public static final int PROPERTY_OBJECT_FORMAT = 0xDC02;
public static final int PROPERTY_PROTECTION_STATUS = 0xDC03;
public static final int PROPERTY_OBJECT_SIZE = 0xDC04;
public static final int PROPERTY_OBJECT_FILE_NAME = 0xDC07;
public static final int PROPERTY_DATE_MODIFIED = 0xDC09;
public static final int PROPERTY_PARENT_OBJECT = 0xDC0B;
public static final int PROPERTY_PERSISTENT_UID = 0xDC41;
/**
* Object is not protected. It may be modified and deleted, and its properties

View File

@@ -66,14 +66,6 @@ public class MtpDatabase {
private final MediaScanner mMediaScanner;
// MTP property codes
private static final int MTP_PROPERTY_STORAGE_ID = 0xDC01;
private static final int MTP_PROPERTY_OBJECT_FORMAT = 0xDC02;
private static final int MTP_PROPERTY_OBJECT_SIZE = 0xDC04;
private static final int MTP_PROPERTY_OBJECT_FILE_NAME = 0xDC07;
private static final int MTP_PROPERTY_DATE_MODIFIED = 0xDC09;
private static final int MTP_PROPERTY_PARENT_OBJECT = 0xDC0B;
// MTP response codes
private static final int MTP_RESPONSE_OK = 0x2001;
private static final int MTP_RESPONSE_GENERAL_ERROR = 0x2002;
@@ -271,25 +263,36 @@ public class MtpDatabase {
boolean isString = false;
switch (property) {
case MTP_PROPERTY_STORAGE_ID:
case Mtp.Object.PROPERTY_STORAGE_ID:
outIntValue[0] = mStorageID;
return MTP_RESPONSE_OK;
case MTP_PROPERTY_OBJECT_FORMAT:
case Mtp.Object.PROPERTY_OBJECT_FORMAT:
column = MtpObjects.ObjectColumns.FORMAT;
break;
case MTP_PROPERTY_OBJECT_SIZE:
case Mtp.Object.PROPERTY_PROTECTION_STATUS:
// protection status is always 0
outIntValue[0] = 0;
return MTP_RESPONSE_OK;
case Mtp.Object.PROPERTY_OBJECT_SIZE:
column = MtpObjects.ObjectColumns.SIZE;
break;
case MTP_PROPERTY_OBJECT_FILE_NAME:
case Mtp.Object.PROPERTY_OBJECT_FILE_NAME:
column = MtpObjects.ObjectColumns.DATA;
isString = true;
break;
case MTP_PROPERTY_DATE_MODIFIED:
case Mtp.Object.PROPERTY_DATE_MODIFIED:
column = MtpObjects.ObjectColumns.DATE_MODIFIED;
break;
case MTP_PROPERTY_PARENT_OBJECT:
case Mtp.Object.PROPERTY_PARENT_OBJECT:
column = MtpObjects.ObjectColumns.PARENT;
break;
case Mtp.Object.PROPERTY_PERSISTENT_UID:
// PUID is concatenation of storageID and object handle
long puid = mStorageID;
puid <<= 32;
puid += handle;
outIntValue[0] = puid;
return MTP_RESPONSE_OK;
default:
return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
}
@@ -305,7 +308,7 @@ public class MtpDatabase {
String value = c.getString(1);
int start = 0;
if (property == MTP_PROPERTY_OBJECT_FILE_NAME) {
if (property == Mtp.Object.PROPERTY_OBJECT_FILE_NAME) {
// extract name from full path
int lastSlash = value.lastIndexOf('/');
if (lastSlash >= 0) {

View File

@@ -29,6 +29,7 @@
#include "MtpDatabase.h"
#include "MtpDataPacket.h"
#include "MtpProperty.h"
#include "MtpUtils.h"
#include "mtp.h"
@@ -45,6 +46,7 @@ static jmethodID method_getSupportedCaptureFormats;
static jmethodID method_getSupportedObjectProperties;
static jmethodID method_getSupportedDeviceProperties;
static jmethodID method_getObjectProperty;
static jmethodID method_setObjectProperty;
static jmethodID method_getObjectInfo;
static jmethodID method_getObjectFilePath;
static jmethodID method_deleteFile;
@@ -98,10 +100,22 @@ public:
virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format);
virtual MtpDevicePropertyList* getSupportedDeviceProperties();
virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet);
virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet);
virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet);
virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet);
virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property);
virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet);
@@ -116,6 +130,11 @@ public:
virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
MtpObjectHandleList* references);
virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
MtpObjectFormat format);
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property);
};
// ----------------------------------------------------------------------------
@@ -292,7 +311,7 @@ MtpDevicePropertyList* MyMtpDatabase::getSupportedDeviceProperties() {
return list;
}
MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) {
int type;
@@ -310,6 +329,15 @@ MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
jlong longValue = longValues[0];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
// special case MTP_PROPERTY_DATE_MODIFIED, which is a string to MTP
// but stored internally as a uint64
if (property == MTP_PROPERTY_DATE_MODIFIED) {
char date[20];
formatDateTime(longValue, date, sizeof(date));
packet.putString(date);
return MTP_RESPONSE_OK;
}
switch (type) {
case MTP_TYPE_INT8:
packet.putInt8(longValue);
@@ -335,6 +363,12 @@ MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
case MTP_TYPE_UINT64:
packet.putUInt64(longValue);
break;
case MTP_TYPE_INT128:
packet.putInt128(longValue);
break;
case MTP_TYPE_UINT128:
packet.putInt128(longValue);
break;
case MTP_TYPE_STR:
{
jchar* str = env->GetCharArrayElements(mStringBuffer, 0);
@@ -351,6 +385,26 @@ MtpResponseCode MyMtpDatabase::getObjectProperty(MtpObjectHandle handle,
return MTP_RESPONSE_OK;
}
MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) {
return -1;
}
MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet) {
return -1;
}
MtpResponseCode MyMtpDatabase::setDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet) {
return -1;
}
MtpResponseCode MyMtpDatabase::resetDeviceProperty(MtpDeviceProperty property) {
return -1;
}
MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet) {
char date[20];
@@ -372,9 +426,10 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle,
uint64_t modified = longValues[1];
env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);
int associationType = (format == MTP_FORMAT_ASSOCIATION ?
MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
MTP_ASSOCIATION_TYPE_UNDEFINED);
// int associationType = (format == MTP_FORMAT_ASSOCIATION ?
// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER :
// MTP_ASSOCIATION_TYPE_UNDEFINED);
int associationType = MTP_ASSOCIATION_TYPE_UNDEFINED;
packet.putUInt32(storageID);
packet.putUInt16(format);
@@ -497,6 +552,37 @@ MtpResponseCode MyMtpDatabase::setObjectReferences(MtpObjectHandle handle,
return result;
}
MtpProperty* MyMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property,
MtpObjectFormat format) {
MtpProperty* result = NULL;
switch (property) {
case MTP_PROPERTY_OBJECT_FORMAT:
case MTP_PROPERTY_PROTECTION_STATUS:
result = new MtpProperty(property, MTP_TYPE_UINT16);
break;
case MTP_PROPERTY_STORAGE_ID:
case MTP_PROPERTY_PARENT_OBJECT:
result = new MtpProperty(property, MTP_TYPE_UINT32);
break;
case MTP_PROPERTY_OBJECT_SIZE:
result = new MtpProperty(property, MTP_TYPE_UINT64);
break;
case MTP_PROPERTY_PERSISTENT_UID:
result = new MtpProperty(property, MTP_TYPE_UINT128);
break;
case MTP_PROPERTY_OBJECT_FILE_NAME:
case MTP_PROPERTY_DATE_MODIFIED:
result = new MtpProperty(property, MTP_TYPE_STR);
break;
}
return result;
}
MtpProperty* MyMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
return NULL;
}
#endif // HAVE_ANDROID_OS
// ----------------------------------------------------------------------------

View File

@@ -242,6 +242,16 @@ void MtpDataPacket::putUInt128(const uint128_t& value) {
putUInt32(value[3]);
}
void MtpDataPacket::putInt128(int64_t value) {
putInt64(value);
putUInt64(value < 0 ? 0xFFFFFFFFFFFFFFFF : 0);
}
void MtpDataPacket::putUInt128(uint64_t value) {
putUInt64(value);
putUInt64(0);
}
void MtpDataPacket::putAInt8(const int8_t* values, int count) {
putUInt32(count);
for (int i = 0; i < count; i++)
@@ -363,7 +373,7 @@ int MtpDataPacket::readDataHeader(int fd) {
int MtpDataPacket::write(int fd) {
MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, mPacketSize);
MtpPacket::putUInt16(MTP_CONTAINER_TYPE_OFFSET, MTP_CONTAINER_TYPE_DATA);
dump();
// send header separately from data
int ret = ::write(fd, mBuffer, MTP_CONTAINER_HEADER_SIZE);
if (ret == MTP_CONTAINER_HEADER_SIZE)

View File

@@ -69,6 +69,8 @@ public:
void putUInt64(uint64_t value);
void putInt128(const int128_t& value);
void putUInt128(const uint128_t& value);
void putInt128(int64_t value);
void putUInt128(uint64_t value);
void putAInt8(const int8_t* values, int count);
void putAUInt8(const uint8_t* values, int count);

View File

@@ -22,6 +22,7 @@
namespace android {
class MtpDataPacket;
class MtpProperty;
class MtpDatabase {
public:
@@ -58,10 +59,22 @@ public:
virtual MtpObjectPropertyList* getSupportedObjectProperties(MtpObjectFormat format) = 0;
virtual MtpDevicePropertyList* getSupportedDeviceProperties() = 0;
virtual MtpResponseCode getObjectProperty(MtpObjectHandle handle,
virtual MtpResponseCode getObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) = 0;
virtual MtpResponseCode setObjectPropertyValue(MtpObjectHandle handle,
MtpObjectProperty property,
MtpDataPacket& packet) = 0;
virtual MtpResponseCode getDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet) = 0;
virtual MtpResponseCode setDevicePropertyValue(MtpDeviceProperty property,
MtpDataPacket& packet) = 0;
virtual MtpResponseCode resetDeviceProperty(MtpDeviceProperty property) = 0;
virtual MtpResponseCode getObjectInfo(MtpObjectHandle handle,
MtpDataPacket& packet) = 0;
@@ -76,6 +89,10 @@ public:
virtual MtpResponseCode setObjectReferences(MtpObjectHandle handle,
MtpObjectHandleList* references) = 0;
virtual MtpProperty* getObjectPropertyDesc(MtpObjectProperty property,
MtpObjectFormat format) = 0;
virtual MtpProperty* getDevicePropertyDesc(MtpDeviceProperty property) = 0;
};
}; // namespace android

View File

@@ -56,17 +56,17 @@ static const MtpOperationCode kSupportedOperationCodes[] = {
// MTP_OPERATION_SET_OBJECT_PROTECTION,
// MTP_OPERATION_POWER_DOWN,
// MTP_OPERATION_GET_DEVICE_PROP_DESC,
// MTP_OPERATION_GET_DEVICE_PROP_VALUE,
// MTP_OPERATION_SET_DEVICE_PROP_VALUE,
// MTP_OPERATION_RESET_DEVICE_PROP_VALUE,
MTP_OPERATION_GET_DEVICE_PROP_VALUE,
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_GET_PARTIAL_OBJECT,
// MTP_OPERATION_INITIATE_OPEN_CAPTURE,
MTP_OPERATION_GET_OBJECT_PROPS_SUPPORTED,
// MTP_OPERATION_GET_OBJECT_PROP_DESC,
MTP_OPERATION_GET_OBJECT_PROP_VALUE,
MTP_OPERATION_GET_OBJECT_PROP_DESC,
// MTP_OPERATION_GET_OBJECT_PROP_VALUE,
// MTP_OPERATION_SET_OBJECT_PROP_VALUE,
MTP_OPERATION_GET_OBJECT_REFERENCES,
MTP_OPERATION_SET_OBJECT_REFERENCES,
@@ -91,7 +91,6 @@ MtpServer::MtpServer(int fd, MtpDatabase* database,
mSendObjectFormat(0),
mSendObjectFileSize(0)
{
initObjectProperties();
}
MtpServer::~MtpServer() {
@@ -136,7 +135,9 @@ void MtpServer::run() {
// FIXME need to generalize this
bool dataIn = (operation == MTP_OPERATION_SEND_OBJECT_INFO
|| operation == MTP_OPERATION_SET_OBJECT_REFERENCES);
|| operation == MTP_OPERATION_SET_OBJECT_REFERENCES
|| operation == MTP_OPERATION_SET_OBJECT_PROP_VALUE
|| operation == MTP_OPERATION_SET_DEVICE_PROP_VALUE);
if (dataIn) {
int ret = mData.read(fd);
if (ret < 0) {
@@ -158,7 +159,6 @@ void MtpServer::run() {
mData.setOperationCode(operation);
mData.setTransactionID(transaction);
LOGV("sending data:");
mData.dump();
ret = mData.write(fd);
if (ret < 0) {
LOGE("request write returned %d, errno: %d", ret, errno);
@@ -187,24 +187,6 @@ void MtpServer::run() {
}
}
MtpProperty* MtpServer::getObjectProperty(MtpPropertyCode propCode) {
for (int i = 0; i < mObjectProperties.size(); i++) {
MtpProperty* property = mObjectProperties[i];
if (property->getPropertyCode() == propCode)
return property;
}
return NULL;
}
MtpProperty* MtpServer::getDeviceProperty(MtpPropertyCode propCode) {
for (int i = 0; i < mDeviceProperties.size(); i++) {
MtpProperty* property = mDeviceProperties[i];
if (property->getPropertyCode() == propCode)
return property;
}
return NULL;
}
void MtpServer::sendObjectAdded(MtpObjectHandle handle) {
if (mSessionOpen) {
LOGD("sendObjectAdded %d\n", handle);
@@ -227,14 +209,6 @@ void MtpServer::sendObjectRemoved(MtpObjectHandle handle) {
}
}
void MtpServer::initObjectProperties() {
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32));
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16));
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64));
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR));
mObjectProperties.push(new MtpProperty(MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32));
}
bool MtpServer::handleRequest() {
MtpOperationCode operation = mRequest.getOperationCode();
MtpResponseCode response;
@@ -281,6 +255,18 @@ bool MtpServer::handleRequest() {
case MTP_OPERATION_GET_OBJECT_PROP_VALUE:
response = doGetObjectPropValue();
break;
case MTP_OPERATION_SET_OBJECT_PROP_VALUE:
response = doSetObjectPropValue();
break;
case MTP_OPERATION_GET_DEVICE_PROP_VALUE:
response = doGetDevicePropValue();
break;
case MTP_OPERATION_SET_DEVICE_PROP_VALUE:
response = doSetDevicePropValue();
break;
case MTP_OPERATION_RESET_DEVICE_PROP_VALUE:
response = doResetDevicePropValue();
break;
case MTP_OPERATION_GET_OBJECT_INFO:
response = doGetObjectInfo();
break;
@@ -456,13 +442,15 @@ MtpResponseCode MtpServer::doGetObjectReferences() {
if (!mSessionOpen)
return MTP_RESPONSE_SESSION_NOT_OPEN;
MtpStorageID handle = mRequest.getParameter(1);
// FIXME - check for invalid object handle
MtpObjectHandleList* handles = mDatabase->getObjectReferences(handle);
if (!handles) {
if (handles) {
mData.putAUInt32(handles);
delete handles;
} else {
mData.putEmptyArray();
return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
}
mData.putAUInt32(handles);
delete handles;
return MTP_RESPONSE_OK;
}
@@ -479,8 +467,43 @@ MtpResponseCode MtpServer::doSetObjectReferences() {
MtpResponseCode MtpServer::doGetObjectPropValue() {
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectProperty property = mRequest.getParameter(2);
LOGD("GetObjectPropValue %d %s\n", handle,
MtpDebug::getObjectPropCodeName(property));
return mDatabase->getObjectProperty(handle, property, mData);
return mDatabase->getObjectPropertyValue(handle, property, mData);
}
MtpResponseCode MtpServer::doSetObjectPropValue() {
MtpObjectHandle handle = mRequest.getParameter(1);
MtpObjectProperty property = mRequest.getParameter(2);
LOGD("SetObjectPropValue %d %s\n", handle,
MtpDebug::getObjectPropCodeName(property));
return mDatabase->setObjectPropertyValue(handle, property, mData);
}
MtpResponseCode MtpServer::doGetDevicePropValue() {
MtpDeviceProperty property = mRequest.getParameter(1);
LOGD("GetDevicePropValue %s\n",
MtpDebug::getDevicePropCodeName(property));
return mDatabase->getDevicePropertyValue(property, mData);
}
MtpResponseCode MtpServer::doSetDevicePropValue() {
MtpDeviceProperty property = mRequest.getParameter(1);
LOGD("SetDevicePropValue %s\n",
MtpDebug::getDevicePropCodeName(property));
return mDatabase->setDevicePropertyValue(property, mData);
}
MtpResponseCode MtpServer::doResetDevicePropValue() {
MtpDeviceProperty property = mRequest.getParameter(1);
LOGD("ResetDevicePropValue %s\n",
MtpDebug::getDevicePropCodeName(property));
return mDatabase->resetDeviceProperty(property);
}
MtpResponseCode MtpServer::doGetObjectInfo() {
@@ -592,7 +615,7 @@ MtpResponseCode MtpServer::doSendObjectInfo() {
}
mResponse.setParameter(1, storageID);
mResponse.setParameter(2, (parent == 0 ? 0xFFFFFFFF: parent));
mResponse.setParameter(2, parent);
mResponse.setParameter(3, handle);
return MTP_RESPONSE_OK;
@@ -677,11 +700,24 @@ MtpResponseCode MtpServer::doDeleteObject() {
MtpResponseCode MtpServer::doGetObjectPropDesc() {
MtpObjectProperty propCode = mRequest.getParameter(1);
MtpObjectFormat format = mRequest.getParameter(2);
MtpProperty* property = getObjectProperty(propCode);
LOGD("GetObjectPropDesc %s %s\n", MtpDebug::getObjectPropCodeName(propCode),
MtpDebug::getFormatCodeName(format));
MtpProperty* property = mDatabase->getObjectPropertyDesc(propCode, format);
if (!property)
return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
property->write(mData);
delete property;
return MTP_RESPONSE_OK;
}
MtpResponseCode MtpServer::doGetDevicePropDesc() {
MtpDeviceProperty propCode = mRequest.getParameter(1);
LOGD("GetDevicePropDesc %s\n", MtpDebug::getDevicePropCodeName(propCode));
MtpProperty* property = mDatabase->getDevicePropertyDesc(propCode);
if (!property)
return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
property->write(mData);
delete property;
return MTP_RESPONSE_OK;
}

View File

@@ -28,7 +28,6 @@
namespace android {
class MtpDatabase;
class MtpProperty;
class MtpStorage;
class MtpServer {
@@ -57,9 +56,6 @@ private:
MtpStorageList mStorages;
MtpPropertyList mObjectProperties;
MtpPropertyList mDeviceProperties;
// handle for new object, set by SendObjectInfo and used by SendObject
MtpObjectHandle mSendObjectHandle;
MtpObjectFormat mSendObjectFormat;
@@ -76,15 +72,10 @@ public:
MtpStorage* getStorage(MtpStorageID id);
void run();
MtpProperty* getObjectProperty(MtpPropertyCode propCode);
MtpProperty* getDeviceProperty(MtpPropertyCode propCode);
void sendObjectAdded(MtpObjectHandle handle);
void sendObjectRemoved(MtpObjectHandle handle);
private:
void initObjectProperties();
bool handleRequest();
MtpResponseCode doGetDeviceInfo();
@@ -98,12 +89,17 @@ private:
MtpResponseCode doGetObjectReferences();
MtpResponseCode doSetObjectReferences();
MtpResponseCode doGetObjectPropValue();
MtpResponseCode doSetObjectPropValue();
MtpResponseCode doGetDevicePropValue();
MtpResponseCode doSetDevicePropValue();
MtpResponseCode doResetDevicePropValue();
MtpResponseCode doGetObjectInfo();
MtpResponseCode doGetObject();
MtpResponseCode doSendObjectInfo();
MtpResponseCode doSendObject();
MtpResponseCode doDeleteObject();
MtpResponseCode doGetObjectPropDesc();
MtpResponseCode doGetDevicePropDesc();
};
}; // namespace android