MtpResponseCode MyMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle,
                                            MtpObjectProperty property,
                                            MtpDataPacket& packet) {
    int         type;

    if (!getObjectPropertyInfo(property, type))
        return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jlong longValue = 0;
    jstring stringValue = NULL;

    switch (type) {
        case MTP_TYPE_INT8:
            longValue = packet.getInt8();
            break;
        case MTP_TYPE_UINT8:
            longValue = packet.getUInt8();
            break;
        case MTP_TYPE_INT16:
            longValue = packet.getInt16();
            break;
        case MTP_TYPE_UINT16:
            longValue = packet.getUInt16();
            break;
        case MTP_TYPE_INT32:
            longValue = packet.getInt32();
            break;
        case MTP_TYPE_UINT32:
            longValue = packet.getUInt32();
            break;
        case MTP_TYPE_INT64:
            longValue = packet.getInt64();
            break;
        case MTP_TYPE_UINT64:
            longValue = packet.getUInt64();
            break;
        case MTP_TYPE_STR:
        {
            MtpStringBuffer buffer;
            packet.getString(buffer);
            stringValue = env->NewStringUTF((const char *)buffer);
            break;
         }
        default:
            ALOGE("unsupported type in setObjectPropertyValue\n");
            return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
    }

    jint result = env->CallIntMethod(mDatabase, method_setObjectProperty,
                (jint)handle, (jint)property, longValue, stringValue);
    if (stringValue)
        env->DeleteLocalRef(stringValue);

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}
Esempio n. 2
0
//virtual
MtpResponseCode
MozMtpDatabase::getObjectPropertyValue(MtpObjectHandle aHandle,
                                       MtpObjectProperty aProperty,
                                       MtpDataPacket& aPacket)
{
  RefPtr<DbEntry> entry = GetEntry(aHandle);
  if (!entry) {
    MTP_ERR("Invalid Handle: 0x%08x", aHandle);
    return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
  }

  MTP_LOG("Handle: 0x%08x '%s' Property: %s 0x%08x",
          aHandle, entry->mDisplayName.get(), ObjectPropertyAsStr(aProperty), aProperty);

  switch (aProperty)
  {
    case MTP_PROPERTY_STORAGE_ID:     aPacket.putUInt32(entry->mStorageID); break;
    case MTP_PROPERTY_PARENT_OBJECT:  aPacket.putUInt32(entry->mParent); break;
    case MTP_PROPERTY_OBJECT_FORMAT:  aPacket.putUInt16(entry->mObjectFormat); break;
    case MTP_PROPERTY_OBJECT_SIZE:    aPacket.putUInt64(entry->mObjectSize); break;
    case MTP_PROPERTY_DISPLAY_NAME:   aPacket.putString(entry->mDisplayName.get()); break;
    case MTP_PROPERTY_PERSISTENT_UID:
      // the same as aPacket.putUInt128
      aPacket.putUInt64(entry->mHandle);
      aPacket.putUInt64(entry->mStorageID);
      break;
    case MTP_PROPERTY_NAME:           aPacket.putString(entry->mDisplayName.get()); break;

    default:
      MTP_LOG("Invalid Property: 0x%08x", aProperty);
      return MTP_RESPONSE_INVALID_OBJECT_PROP_CODE;
  }

  return MTP_RESPONSE_OK;
}
void MtpProperty::write(MtpDataPacket& packet) {
    bool deviceProp = isDeviceProperty();

    packet.putUInt16(mCode);
    packet.putUInt16(mType);
    packet.putUInt8(mWriteable ? 1 : 0);

    switch (mType) {
        case MTP_TYPE_AINT8:
        case MTP_TYPE_AUINT8:
        case MTP_TYPE_AINT16:
        case MTP_TYPE_AUINT16:
        case MTP_TYPE_AINT32:
        case MTP_TYPE_AUINT32:
        case MTP_TYPE_AINT64:
        case MTP_TYPE_AUINT64:
        case MTP_TYPE_AINT128:
        case MTP_TYPE_AUINT128:
            writeArrayValues(packet, mDefaultArrayValues, mDefaultArrayLength);
            if (deviceProp)
                writeArrayValues(packet, mCurrentArrayValues, mCurrentArrayLength);
            break;
        default:
            writeValue(packet, mDefaultValue);
            if (deviceProp)
                writeValue(packet, mCurrentValue);
    }
    packet.putUInt32(mGroupCode);
    if (!deviceProp)
        packet.putUInt8(mFormFlag);
    if (mFormFlag == kFormRange) {
            writeValue(packet, mMinimumValue);
            writeValue(packet, mMaximumValue);
            writeValue(packet, mStepSize);
    } else if (mFormFlag == kFormEnum) {
        packet.putUInt16(mEnumLength);
        for (int i = 0; i < mEnumLength; i++)
            writeValue(packet, mEnumValues[i]);
    }
}
Esempio n. 4
0
//virtual
MtpResponseCode
MozMtpDatabase::setObjectPropertyValue(MtpObjectHandle aHandle,
                                       MtpObjectProperty aProperty,
                                       MtpDataPacket& aPacket)
{
  MTP_LOG("Handle: 0x%08x Property: 0x%08x", aHandle, aProperty);

  // Only support file name change
  if (aProperty != MTP_PROPERTY_OBJECT_FILE_NAME) {
    MTP_ERR("property 0x%x not supported", aProperty);
    return  MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED;
  }

  if (GetTypeOfObjectProp(aProperty) != MTP_TYPE_STR) {
    MTP_ERR("property type 0x%x not supported", GetTypeOfObjectProp(aProperty));
    return MTP_RESPONSE_GENERAL_ERROR;
  }

  RefPtr<DbEntry> entry = GetEntry(aHandle);
  if (!entry) {
    MTP_ERR("Invalid Handle: 0x%08x", aHandle);
    return MTP_RESPONSE_INVALID_OBJECT_HANDLE;
  }

  MtpStringBuffer buf;
  aPacket.getString(buf);

  nsDependentCString newFileName(buf);
  nsCString newFileFullPath(GetPathWithoutFileName(entry->mPath) + newFileName);

  if (PR_Rename(entry->mPath.get(), newFileFullPath.get()) != PR_SUCCESS) {
    MTP_ERR("Failed to rename '%s' to '%s'",
            entry->mPath.get(), newFileFullPath.get());
    return MTP_RESPONSE_GENERAL_ERROR;
  }

  MTP_LOG("renamed '%s' to '%s'", entry->mPath.get(), newFileFullPath.get());

  entry->mPath = newFileFullPath;
  entry->mObjectName = BaseName(entry->mPath);
  entry->mDisplayName = entry->mObjectName;

  return MTP_RESPONSE_OK;
}
bool MtpProperty::read(MtpDataPacket& packet) {
    uint8_t temp8;

    if (!packet.getUInt16(mCode)) return false;
    bool deviceProp = isDeviceProperty();
    if (!packet.getUInt16(mType)) return false;
    if (!packet.getUInt8(temp8)) return false;
    mWriteable = (temp8 == 1);
    switch (mType) {
        case MTP_TYPE_AINT8:
        case MTP_TYPE_AUINT8:
        case MTP_TYPE_AINT16:
        case MTP_TYPE_AUINT16:
        case MTP_TYPE_AINT32:
        case MTP_TYPE_AUINT32:
        case MTP_TYPE_AINT64:
        case MTP_TYPE_AUINT64:
        case MTP_TYPE_AINT128:
        case MTP_TYPE_AUINT128:
            mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
            if (!mDefaultArrayValues) return false;
            if (deviceProp) {
                mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
                if (!mCurrentArrayValues) return false;
            }
            break;
        default:
            if (!readValue(packet, mDefaultValue)) return false;
            if (deviceProp) {
                if (!readValue(packet, mCurrentValue)) return false;
            }
    }
    if (!deviceProp) {
        if (!packet.getUInt32(mGroupCode)) return false;
    }
    if (!packet.getUInt8(mFormFlag)) return false;

    if (mFormFlag == kFormRange) {
            if (!readValue(packet, mMinimumValue)) return false;
            if (!readValue(packet, mMaximumValue)) return false;
            if (!readValue(packet, mStepSize)) return false;
    } else if (mFormFlag == kFormEnum) {
        if (!packet.getUInt16(mEnumLength)) return false;
        mEnumValues = new MtpPropertyValue[mEnumLength];
        for (int i = 0; i < mEnumLength; i++) {
            if (!readValue(packet, mEnumValues[i])) return false;
        }
    }

    return true;
}
void MtpProperty::read(MtpDataPacket& packet) {
    mCode = packet.getUInt16();
    bool deviceProp = isDeviceProperty();
    mType = packet.getUInt16();
    mWriteable = (packet.getUInt8() == 1);
    switch (mType) {
        case MTP_TYPE_AINT8:
        case MTP_TYPE_AUINT8:
        case MTP_TYPE_AINT16:
        case MTP_TYPE_AUINT16:
        case MTP_TYPE_AINT32:
        case MTP_TYPE_AUINT32:
        case MTP_TYPE_AINT64:
        case MTP_TYPE_AUINT64:
        case MTP_TYPE_AINT128:
        case MTP_TYPE_AUINT128:
            mDefaultArrayValues = readArrayValues(packet, mDefaultArrayLength);
            if (deviceProp)
                mCurrentArrayValues = readArrayValues(packet, mCurrentArrayLength);
            break;
        default:
            readValue(packet, mDefaultValue);
            if (deviceProp)
                readValue(packet, mCurrentValue);
    }
    if (!deviceProp)
        mGroupCode = packet.getUInt32();
    mFormFlag = packet.getUInt8();

    if (mFormFlag == kFormRange) {
            readValue(packet, mMinimumValue);
            readValue(packet, mMaximumValue);
            readValue(packet, mStepSize);
    } else if (mFormFlag == kFormEnum) {
        mEnumLength = packet.getUInt16();
        mEnumValues = new MtpPropertyValue[mEnumLength];
        for (int i = 0; i < mEnumLength; i++)
            readValue(packet, mEnumValues[i]);
    }
}
Esempio n. 7
0
//virtual
MtpResponseCode
MozMtpDatabase::getObjectPropertyList(MtpObjectHandle aHandle,
                                      uint32_t aFormat,
                                      uint32_t aProperty,
                                      int aGroupCode,
                                      int aDepth,
                                      MtpDataPacket& aPacket)
{
  MTP_LOG("Handle: 0x%08x Format: 0x%08x aProperty: 0x%08x aGroupCode: %d aDepth %d",
          aHandle, aFormat, aProperty, aGroupCode, aDepth);

  if (aDepth > 1) {
    return MTP_RESPONSE_SPECIFICATION_BY_DEPTH_UNSUPPORTED;
  }
  if (aGroupCode != 0) {
    return MTP_RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED;
  }

  MatchType matchType = MatchAll;
  uint32_t matchField1 = 0;
  uint32_t matchField2 = 0;

  // aHandle == 0 implies all objects at the root level
  // further specificed by aFormat and/or aDepth

  if (aFormat == 0) {
    if (aHandle == 0xffffffff) {
      // select all objects
      matchType = MatchAll;
    } else {
      if (aDepth == 1) {
        // select objects whose Parent matches aHandle
        matchType = MatchParent;
        matchField1 = aHandle;
      } else {
        // select object whose handle matches aHandle
        matchType = MatchHandle;
        matchField1 = aHandle;
      }
    }
  } else {
    if (aHandle == 0xffffffff) {
      // select all objects whose format matches aFormat
      matchType = MatchFormat;
      matchField1 = aFormat;
    } else {
      if (aDepth == 1) {
        // select objects whose Parent is aHandle and format matches aFormat
        matchType = MatchParentFormat;
        matchField1 = aHandle;
        matchField2 = aFormat;
      } else {
        // select objects whose handle is aHandle and format matches aFormat
        matchType = MatchHandleFormat;
        matchField1 = aHandle;
        matchField2 = aFormat;
      }
    }
  }

  UnprotectedDbArray result;
  QueryEntries(matchType, matchField1, matchField2, result);

  const MtpObjectProperty *objectPropertyList;
  size_t numObjectProperties = 0;
  MtpObjectProperty objectProperty;

  if (aProperty == 0xffffffff) {
    // return all supported properties
    numObjectProperties = MOZ_ARRAY_LENGTH(sSupportedObjectProperties);
    objectPropertyList = sSupportedObjectProperties;
  } else {
    // return property indicated by aProperty
    numObjectProperties = 1;
    objectProperty = aProperty;
    objectPropertyList = &objectProperty;
  }

  UnprotectedDbArray::size_type numEntries = result.Length();
  UnprotectedDbArray::index_type entryIdx;

  char dateStr[20];

  aPacket.putUInt32(numObjectProperties * numEntries);
  for (entryIdx = 0; entryIdx < numEntries; entryIdx++) {
    RefPtr<DbEntry> entry = result[entryIdx];

    for (size_t propertyIdx = 0; propertyIdx < numObjectProperties; propertyIdx++) {
      aPacket.putUInt32(entry->mHandle);
      MtpObjectProperty prop = objectPropertyList[propertyIdx];
      aPacket.putUInt16(prop);
      switch (prop) {

        case MTP_PROPERTY_STORAGE_ID:
          aPacket.putUInt16(MTP_TYPE_UINT32);
          aPacket.putUInt32(entry->mStorageID);
          break;

        case MTP_PROPERTY_PARENT_OBJECT:
          aPacket.putUInt16(MTP_TYPE_UINT32);
          aPacket.putUInt32(entry->mParent);
          break;

        case MTP_PROPERTY_PERSISTENT_UID:
          aPacket.putUInt16(MTP_TYPE_UINT128);
          // the same as aPacket.putUInt128
          aPacket.putUInt64(entry->mHandle);
          aPacket.putUInt64(entry->mStorageID);
          break;

        case MTP_PROPERTY_OBJECT_FORMAT:
          aPacket.putUInt16(MTP_TYPE_UINT16);
          aPacket.putUInt16(entry->mObjectFormat);
          break;

        case MTP_PROPERTY_OBJECT_SIZE:
          aPacket.putUInt16(MTP_TYPE_UINT64);
          aPacket.putUInt64(entry->mObjectSize);
          break;

        case MTP_PROPERTY_OBJECT_FILE_NAME:
        case MTP_PROPERTY_NAME:
          aPacket.putUInt16(MTP_TYPE_STR);
          aPacket.putString(entry->mObjectName.get());
          break;

        case MTP_PROPERTY_PROTECTION_STATUS:
          aPacket.putUInt16(MTP_TYPE_UINT16);
          aPacket.putUInt16(0); // 0 = No Protection
          break;

        case MTP_PROPERTY_DATE_CREATED: {
          aPacket.putUInt16(MTP_TYPE_STR);
          aPacket.putString(FormatDate(entry->mDateCreated, dateStr, sizeof(dateStr)));
          MTP_LOG("mDateCreated: (%ld) %s", entry->mDateCreated, dateStr);
          break;
        }

        case MTP_PROPERTY_DATE_MODIFIED: {
          aPacket.putUInt16(MTP_TYPE_STR);
          aPacket.putString(FormatDate(entry->mDateModified, dateStr, sizeof(dateStr)));
          MTP_LOG("mDateModified: (%ld) %s", entry->mDateModified, dateStr);
          break;
        }

        case MTP_PROPERTY_DATE_ADDED: {
          aPacket.putUInt16(MTP_TYPE_STR);
          aPacket.putString(FormatDate(entry->mDateAdded, dateStr, sizeof(dateStr)));
          MTP_LOG("mDateAdded: (%ld) %s", entry->mDateAdded, dateStr);
          break;
        }

        default:
          MTP_ERR("Unrecognized property code: %u", prop);
          return MTP_RESPONSE_GENERAL_ERROR;
      }
    }
  }
  return MTP_RESPONSE_OK;
}
void MtpDeviceInfo::read(MtpDataPacket& packet) {
    MtpStringBuffer string;

    // read the device info
    mStandardVersion = packet.getUInt16();
    mVendorExtensionID = packet.getUInt32();
    mVendorExtensionVersion = packet.getUInt16();

    packet.getString(string);
    mVendorExtensionDesc = strdup((const char *)string);

    mFunctionalCode = packet.getUInt16();
    mOperations = packet.getAUInt16();
    mEvents = packet.getAUInt16();
    mDeviceProperties = packet.getAUInt16();
    mCaptureFormats = packet.getAUInt16();
    mPlaybackFormats = packet.getAUInt16();

    packet.getString(string);
    mManufacturer = strdup((const char *)string);
    packet.getString(string);
    mModel = strdup((const char *)string);
    packet.getString(string);
    mVersion = strdup((const char *)string);
    packet.getString(string);
    mSerial = strdup((const char *)string);
}
void MtpObjectInfo::read(MtpDataPacket& packet) {
    MtpStringBuffer string;
    time_t time;

    mStorageID = packet.getUInt32();
    mFormat = packet.getUInt16();
    mProtectionStatus = packet.getUInt16();
    mCompressedSize = packet.getUInt32();
    mThumbFormat = packet.getUInt16();
    mThumbCompressedSize = packet.getUInt32();
    mThumbPixWidth = packet.getUInt32();
    mThumbPixHeight = packet.getUInt32();
    mImagePixWidth = packet.getUInt32();
    mImagePixHeight = packet.getUInt32();
    mImagePixDepth = packet.getUInt32();
    mParent = packet.getUInt32();
    mAssociationType = packet.getUInt16();
    mAssociationDesc = packet.getUInt32();
    mSequenceNumber = packet.getUInt32();

    packet.getString(string);
    mName = strdup((const char *)string);

    packet.getString(string);
    if (parseDateTime((const char*)string, time))
        mDateCreated = time;

    packet.getString(string);
    if (parseDateTime((const char*)string, time))
        mDateModified = time;

    packet.getString(string);
    mKeywords = strdup((const char *)string);
}
void MtpProperty::writeArrayValues(MtpDataPacket& packet, MtpPropertyValue* values, int length) {
    packet.putUInt32(length);
    for (int i = 0; i < length; i++)
        writeValue(packet, values[i]);
}
void MtpProperty::writeValue(MtpDataPacket& packet, MtpPropertyValue& value) {
    MtpStringBuffer stringBuffer;

    switch (mType) {
        case MTP_TYPE_INT8:
        case MTP_TYPE_AINT8:
            packet.putInt8(value.u.i8);
            break;
        case MTP_TYPE_UINT8:
        case MTP_TYPE_AUINT8:
            packet.putUInt8(value.u.u8);
            break;
        case MTP_TYPE_INT16:
        case MTP_TYPE_AINT16:
            packet.putInt16(value.u.i16);
            break;
        case MTP_TYPE_UINT16:
        case MTP_TYPE_AUINT16:
            packet.putUInt16(value.u.u16);
            break;
        case MTP_TYPE_INT32:
        case MTP_TYPE_AINT32:
            packet.putInt32(value.u.i32);
            break;
        case MTP_TYPE_UINT32:
        case MTP_TYPE_AUINT32:
            packet.putUInt32(value.u.u32);
            break;
        case MTP_TYPE_INT64:
        case MTP_TYPE_AINT64:
            packet.putInt64(value.u.i64);
            break;
        case MTP_TYPE_UINT64:
        case MTP_TYPE_AUINT64:
            packet.putUInt64(value.u.u64);
            break;
        case MTP_TYPE_INT128:
        case MTP_TYPE_AINT128:
            packet.putInt128(value.u.i128);
            break;
        case MTP_TYPE_UINT128:
        case MTP_TYPE_AUINT128:
            packet.putUInt128(value.u.u128);
            break;
        case MTP_TYPE_STR:
            if (value.str)
                packet.putString(value.str);
            else
                packet.putEmptyString();
            break;
        default:
            ALOGE("unknown type %04X in MtpProperty::writeValue", mType);
    }
}
bool MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
    MtpStringBuffer stringBuffer;

    switch (mType) {
        case MTP_TYPE_INT8:
        case MTP_TYPE_AINT8:
            if (!packet.getInt8(value.u.i8)) return false;
            break;
        case MTP_TYPE_UINT8:
        case MTP_TYPE_AUINT8:
            if (!packet.getUInt8(value.u.u8)) return false;
            break;
        case MTP_TYPE_INT16:
        case MTP_TYPE_AINT16:
            if (!packet.getInt16(value.u.i16)) return false;
            break;
        case MTP_TYPE_UINT16:
        case MTP_TYPE_AUINT16:
            if (!packet.getUInt16(value.u.u16)) return false;
            break;
        case MTP_TYPE_INT32:
        case MTP_TYPE_AINT32:
            if (!packet.getInt32(value.u.i32)) return false;
            break;
        case MTP_TYPE_UINT32:
        case MTP_TYPE_AUINT32:
            if (!packet.getUInt32(value.u.u32)) return false;
            break;
        case MTP_TYPE_INT64:
        case MTP_TYPE_AINT64:
            if (!packet.getInt64(value.u.i64)) return false;
            break;
        case MTP_TYPE_UINT64:
        case MTP_TYPE_AUINT64:
            if (!packet.getUInt64(value.u.u64)) return false;
            break;
        case MTP_TYPE_INT128:
        case MTP_TYPE_AINT128:
            if (!packet.getInt128(value.u.i128)) return false;
            break;
        case MTP_TYPE_UINT128:
        case MTP_TYPE_AUINT128:
            if (!packet.getUInt128(value.u.u128)) return false;
            break;
        case MTP_TYPE_STR:
            if (!packet.getString(stringBuffer)) return false;
            value.str = strdup(stringBuffer);
            break;
        default:
            ALOGE("unknown type %04X in MtpProperty::readValue", mType);
            return false;
    }
    return true;
}
Esempio n. 13
0
int MtpStorage::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, uint32_t property, int groupCode, int depth, MtpDataPacket& packet) {
	MTPD("MtpStorage::getObjectPropertyList handle: %u, format: %x, property: %x\n", handle, format, property);
	if (groupCode != 0)
	{
		MTPE("getObjectPropertyList: groupCode unsupported\n");
		return -1; // TODO: RESPONSE_SPECIFICATION_BY_GROUP_UNSUPPORTED
	}
	// TODO: support all the special stuff, like:
	// handle == 0 -> all objects at the root level
	// handle == 0xffffffff -> all objects (on all storages? how could we support that?)
	// format == 0 -> all formats, otherwise filter by ObjectFormatCode
	// property == 0xffffffff -> all properties except those with group code 0xffffffff
	// if property == 0 then use groupCode
	//   groupCode == 0 -> return Specification_By_Group_Unsupported
	// depth == 0xffffffff -> all objects incl. and below handle

	std::vector<PropEntry> results;

	if (handle == 0xffffffff) {
		// TODO: all object on all storages (needs a different design, result packet needs to be built by server instead of storage)
	} else if (handle == 0)	{
		// all objects at the root level
		Tree* root = mtpmap[0];
		MtpObjectHandleList list;
		root->getmtpids(&list);
		for (MtpObjectHandleList::iterator it = list.begin(); it != list.end(); ++it) {
			Node* node = root->findNode(*it);
			if (!node) {
				MTPE("BUG: node not found for root entry with handle %u\n", *it);
				break;
			}
			queryNodeProperties(results, node, property, groupCode, mStorageID);
		}
	} else {
		// single object
		Node* node = findNode(handle);
		if (!node) {
			// Item is not on this storage device
			return -1;
		}
		queryNodeProperties(results, node, property, groupCode, mStorageID);
	}

	MTPD("count: %u\n", results.size());
	packet.putUInt32(results.size());

	for (size_t i = 0; i < results.size(); ++i) {
		PropEntry& p = results[i];
		MTPD("handle: %u, propertyCode: %x = %s, datatype: %x, value: %llu\n",
				p.handle, p.property, MtpDebug::getObjectPropCodeName(p.property),
				p.datatype, p.intvalue);
		packet.putUInt32(p.handle);
		packet.putUInt16(p.property);
		packet.putUInt16(p.datatype);
		switch (p.datatype) {
			case MTP_TYPE_INT8:
				MTPD("MTP_TYPE_INT8\n");
				packet.putInt8(p.intvalue);
				break;
			case MTP_TYPE_UINT8:
				MTPD("MTP_TYPE_UINT8\n");
				packet.putUInt8(p.intvalue);
				break;
			case MTP_TYPE_INT16:
				MTPD("MTP_TYPE_INT16\n");
				packet.putInt16(p.intvalue);
				break;
			case MTP_TYPE_UINT16:
				MTPD("MTP_TYPE_UINT16\n");
				packet.putUInt16(p.intvalue);
				break;
			case MTP_TYPE_INT32:
				MTPD("MTP_TYPE_INT32\n");
				packet.putInt32(p.intvalue);
				break;
			case MTP_TYPE_UINT32:
				MTPD("MTP_TYPE_UINT32\n");
				packet.putUInt32(p.intvalue);
				break;
			case MTP_TYPE_INT64:
				MTPD("MTP_TYPE_INT64\n");
				packet.putInt64(p.intvalue);
				break;
			case MTP_TYPE_UINT64:
				MTPD("MTP_TYPE_UINT64\n");
				packet.putUInt64(p.intvalue);
				break;
			case MTP_TYPE_INT128:
				MTPD("MTP_TYPE_INT128\n");
				packet.putInt128(p.intvalue);
				break;
			case MTP_TYPE_UINT128:
				MTPD("MTP_TYPE_UINT128\n");
				packet.putUInt128(p.intvalue);
				break;
			case MTP_TYPE_STR:
				MTPD("MTP_TYPE_STR: %s\n", p.strvalue.c_str());
				packet.putString(p.strvalue.c_str());
				break;
			default:
				MTPE("bad or unsupported data type: %x in MyMtpDatabase::getObjectPropertyList", p.datatype);
				break;
		}
	}
	return 0;
}
MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle,
                                            uint32_t format, uint32_t property,
                                            int groupCode, int depth,
                                            MtpDataPacket& packet) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
                (jlong)handle, (jint)format, (jlong)property, (jint)groupCode, (jint)depth);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    if (!list)
        return MTP_RESPONSE_GENERAL_ERROR;
    int count = env->GetIntField(list, field_mCount);
    MtpResponseCode result = env->GetIntField(list, field_mResult);

    packet.putUInt32(count);
    if (count > 0) {
        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);

        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);

        for (int i = 0; i < count; i++) {
            packet.putUInt32(objectHandles[i]);
            packet.putUInt16(propertyCodes[i]);
            int type = dataTypes[i];
            packet.putUInt16(type);

            switch (type) {
                case MTP_TYPE_INT8:
                    packet.putInt8(longValues[i]);
                    break;
                case MTP_TYPE_UINT8:
                    packet.putUInt8(longValues[i]);
                    break;
                case MTP_TYPE_INT16:
                    packet.putInt16(longValues[i]);
                    break;
                case MTP_TYPE_UINT16:
                    packet.putUInt16(longValues[i]);
                    break;
                case MTP_TYPE_INT32:
                    packet.putInt32(longValues[i]);
                    break;
                case MTP_TYPE_UINT32:
                    packet.putUInt32(longValues[i]);
                    break;
                case MTP_TYPE_INT64:
                    packet.putInt64(longValues[i]);
                    break;
                case MTP_TYPE_UINT64:
                    packet.putUInt64(longValues[i]);
                    break;
                case MTP_TYPE_INT128:
                    packet.putInt128(longValues[i]);
                    break;
                case MTP_TYPE_UINT128:
                    packet.putUInt128(longValues[i]);
                    break;
                case MTP_TYPE_STR: {
                    jstring value = (jstring)env->GetObjectArrayElement(stringValuesArray, i);
                    const char *valueStr = (value ? env->GetStringUTFChars(value, NULL) : NULL);
                    if (valueStr) {
                        packet.putString(valueStr);
                        env->ReleaseStringUTFChars(value, valueStr);
                    } else {
                        packet.putEmptyString();
                    }
                    env->DeleteLocalRef(value);
                    break;
                }
                default:
                    ALOGE("bad or unsupported data type in MyMtpDatabase::getObjectPropertyList");
                    break;
            }
        }

        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
        if (longValues)
            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);

        env->DeleteLocalRef(objectHandlesArray);
        env->DeleteLocalRef(propertyCodesArray);
        env->DeleteLocalRef(dataTypesArray);
        if (longValuesArray)
            env->DeleteLocalRef(longValuesArray);
        if (stringValuesArray)
            env->DeleteLocalRef(stringValuesArray);
    }

    env->DeleteLocalRef(list);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}
MtpResponseCode MyMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property,
                                            MtpDataPacket& packet) {
    int         type;

    if (!getDevicePropertyInfo(property, type))
        return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED;

    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jint result = env->CallIntMethod(mDatabase, method_getDeviceProperty,
                (jint)property, mLongBuffer, mStringBuffer);
    if (result != MTP_RESPONSE_OK) {
        checkAndClearExceptionFromCallback(env, __FUNCTION__);
        return result;
    }

    jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0);
    jlong longValue = longValues[0];
    env->ReleaseLongArrayElements(mLongBuffer, longValues, 0);

    switch (type) {
        case MTP_TYPE_INT8:
            packet.putInt8(longValue);
            break;
        case MTP_TYPE_UINT8:
            packet.putUInt8(longValue);
            break;
        case MTP_TYPE_INT16:
            packet.putInt16(longValue);
            break;
        case MTP_TYPE_UINT16:
            packet.putUInt16(longValue);
            break;
        case MTP_TYPE_INT32:
            packet.putInt32(longValue);
            break;
        case MTP_TYPE_UINT32:
            packet.putUInt32(longValue);
            break;
        case MTP_TYPE_INT64:
            packet.putInt64(longValue);
            break;
        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);
            packet.putString(str);
            env->ReleaseCharArrayElements(mStringBuffer, str, 0);
            break;
         }
        default:
            ALOGE("unsupported type in getDevicePropertyValue\n");
            return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT;
    }

    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return MTP_RESPONSE_OK;
}
void MtpProperty::readValue(MtpDataPacket& packet, MtpPropertyValue& value) {
    MtpStringBuffer stringBuffer;

    switch (mType) {
        case MTP_TYPE_INT8:
        case MTP_TYPE_AINT8:
            value.u.i8 = packet.getInt8();
            break;
        case MTP_TYPE_UINT8:
        case MTP_TYPE_AUINT8:
            value.u.u8 = packet.getUInt8();
            break;
        case MTP_TYPE_INT16:
        case MTP_TYPE_AINT16:
            value.u.i16 = packet.getInt16();
            break;
        case MTP_TYPE_UINT16:
        case MTP_TYPE_AUINT16:
            value.u.u16 = packet.getUInt16();
            break;
        case MTP_TYPE_INT32:
        case MTP_TYPE_AINT32:
            value.u.i32 = packet.getInt32();
            break;
        case MTP_TYPE_UINT32:
        case MTP_TYPE_AUINT32:
            value.u.u32 = packet.getUInt32();
            break;
        case MTP_TYPE_INT64:
        case MTP_TYPE_AINT64:
            value.u.i64 = packet.getInt64();
            break;
        case MTP_TYPE_UINT64:
        case MTP_TYPE_AUINT64:
            value.u.u64 = packet.getUInt64();
            break;
        case MTP_TYPE_INT128:
        case MTP_TYPE_AINT128:
            packet.getInt128(value.u.i128);
            break;
        case MTP_TYPE_UINT128:
        case MTP_TYPE_AUINT128:
            packet.getUInt128(value.u.u128);
            break;
        case MTP_TYPE_STR:
            packet.getString(stringBuffer);
            value.str = strdup(stringBuffer);
            break;
        default:
            ALOGE("unknown type %04X in MtpProperty::readValue", mType);
    }
}
Esempio n. 17
0
bool MtpDeviceInfo::read(MtpDataPacket& packet) {
    MtpStringBuffer string;

    // read the device info
    if (!packet.getUInt16(mStandardVersion)) return false;
    if (!packet.getUInt32(mVendorExtensionID)) return false;
    if (!packet.getUInt16(mVendorExtensionVersion)) return false;

    if (!packet.getString(string)) return false;
    mVendorExtensionDesc = strdup((const char *)string);

    if (!packet.getUInt16(mFunctionalMode)) return false;
    mOperations = packet.getAUInt16();
    if (!mOperations) return false;
    mEvents = packet.getAUInt16();
    if (!mEvents) return false;
    mDeviceProperties = packet.getAUInt16();
    if (!mDeviceProperties) return false;
    mCaptureFormats = packet.getAUInt16();
    if (!mCaptureFormats) return false;
    mPlaybackFormats = packet.getAUInt16();
    if (!mCaptureFormats) return false;

    if (!packet.getString(string)) return false;
    mManufacturer = strdup((const char *)string);
    if (!packet.getString(string)) return false;
    mModel = strdup((const char *)string);
    if (!packet.getString(string)) return false;
    mVersion = strdup((const char *)string);
    if (!packet.getString(string)) return false;
    mSerial = strdup((const char *)string);

    return true;
}
MtpResponseCode MyMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle,
                                            MtpObjectProperty property,
                                            MtpDataPacket& packet) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    jobject list = env->CallObjectMethod(mDatabase, method_getObjectPropertyList,
                (jlong)handle, 0, (jlong)property, 0, 0);
    MtpResponseCode result = env->GetIntField(list, field_mResult);
    int count = env->GetIntField(list, field_mCount);
    if (result == MTP_RESPONSE_OK && count != 1)
        result = MTP_RESPONSE_GENERAL_ERROR;

    if (result == MTP_RESPONSE_OK) {
        jintArray objectHandlesArray = (jintArray)env->GetObjectField(list, field_mObjectHandles);
        jintArray propertyCodesArray = (jintArray)env->GetObjectField(list, field_mPropertyCodes);
        jintArray dataTypesArray = (jintArray)env->GetObjectField(list, field_mDataTypes);
        jlongArray longValuesArray = (jlongArray)env->GetObjectField(list, field_mLongValues);
        jobjectArray stringValuesArray = (jobjectArray)env->GetObjectField(list, field_mStringValues);

        jint* objectHandles = env->GetIntArrayElements(objectHandlesArray, 0);
        jint* propertyCodes = env->GetIntArrayElements(propertyCodesArray, 0);
        jint* dataTypes = env->GetIntArrayElements(dataTypesArray, 0);
        jlong* longValues = (longValuesArray ? env->GetLongArrayElements(longValuesArray, 0) : NULL);

        int type = dataTypes[0];
        jlong longValue = (longValues ? longValues[0] : 0);

        // special case date properties, which are strings to MTP
        // but stored internally as a uint64
        if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) {
            char    date[20];
            formatDateTime(longValue, date, sizeof(date));
            packet.putString(date);
            goto out;
        }
        // release date is stored internally as just the year
        if (property == MTP_PROPERTY_ORIGINAL_RELEASE_DATE) {
            char    date[20];
            snprintf(date, sizeof(date), "%04" PRId64 "0101T000000", longValue);
            packet.putString(date);
            goto out;
        }

        switch (type) {
            case MTP_TYPE_INT8:
                packet.putInt8(longValue);
                break;
            case MTP_TYPE_UINT8:
                packet.putUInt8(longValue);
                break;
            case MTP_TYPE_INT16:
                packet.putInt16(longValue);
                break;
            case MTP_TYPE_UINT16:
                packet.putUInt16(longValue);
                break;
            case MTP_TYPE_INT32:
                packet.putInt32(longValue);
                break;
            case MTP_TYPE_UINT32:
                packet.putUInt32(longValue);
                break;
            case MTP_TYPE_INT64:
                packet.putInt64(longValue);
                break;
            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:
            {
                jstring stringValue = (jstring)env->GetObjectArrayElement(stringValuesArray, 0);
                const char* str = (stringValue ? env->GetStringUTFChars(stringValue, NULL) : NULL);
                if (stringValue) {
                    packet.putString(str);
                    env->ReleaseStringUTFChars(stringValue, str);
                } else {
                    packet.putEmptyString();
                }
                env->DeleteLocalRef(stringValue);
                break;
             }
            default:
                ALOGE("unsupported type in getObjectPropertyValue\n");
                result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT;
        }
out:
        env->ReleaseIntArrayElements(objectHandlesArray, objectHandles, 0);
        env->ReleaseIntArrayElements(propertyCodesArray, propertyCodes, 0);
        env->ReleaseIntArrayElements(dataTypesArray, dataTypes, 0);
        if (longValues)
            env->ReleaseLongArrayElements(longValuesArray, longValues, 0);

        env->DeleteLocalRef(objectHandlesArray);
        env->DeleteLocalRef(propertyCodesArray);
        env->DeleteLocalRef(dataTypesArray);
        if (longValuesArray)
            env->DeleteLocalRef(longValuesArray);
        if (stringValuesArray)
            env->DeleteLocalRef(stringValuesArray);
    }

    env->DeleteLocalRef(list);
    checkAndClearExceptionFromCallback(env, __FUNCTION__);
    return result;
}