| /* | |
| * Copyright (C) 2010 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. | |
| */ | |
| package android.mtp; | |
| import android.annotation.NonNull; | |
| import android.os.Build; | |
| import com.android.internal.util.Preconditions; | |
| import dalvik.system.VMRuntime; | |
| /** | |
| * This class encapsulates information about an object on an MTP device. | |
| * This corresponds to the ObjectInfo Dataset described in | |
| * section 5.3.1 of the MTP specification. | |
| */ | |
| public final class MtpObjectInfo { | |
| private int mHandle; | |
| private int mStorageId; | |
| private int mFormat; | |
| private int mProtectionStatus; | |
| private int mCompressedSize; | |
| private int mThumbFormat; | |
| private int mThumbCompressedSize; | |
| private int mThumbPixWidth; | |
| private int mThumbPixHeight; | |
| private int mImagePixWidth; | |
| private int mImagePixHeight; | |
| private int mImagePixDepth; | |
| private int mParent; | |
| private int mAssociationType; | |
| private int mAssociationDesc; | |
| private int mSequenceNumber; | |
| private String mName = ""; | |
| private long mDateCreated; | |
| private long mDateModified; | |
| private String mKeywords = ""; | |
| // only instantiated via JNI or via a builder | |
| private MtpObjectInfo() { | |
| } | |
| /** | |
| * Returns the object handle for the MTP object | |
| * | |
| * @return the object handle | |
| */ | |
| public final int getObjectHandle() { | |
| return mHandle; | |
| } | |
| /** | |
| * Returns the storage ID for the MTP object's storage unit | |
| * | |
| * @return the storage ID | |
| */ | |
| public final int getStorageId() { | |
| return mStorageId; | |
| } | |
| /** | |
| * Returns the format code for the MTP object | |
| * | |
| * @return the format code | |
| */ | |
| public final int getFormat() { | |
| return mFormat; | |
| } | |
| /** | |
| * Returns the protection status for the MTP object | |
| * Possible values are: | |
| * | |
| * <ul> | |
| * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NONE} | |
| * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_READ_ONLY} | |
| * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NON_TRANSFERABLE_DATA} | |
| * </ul> | |
| * | |
| * @return the protection status | |
| */ | |
| public final int getProtectionStatus() { | |
| return mProtectionStatus; | |
| } | |
| /** | |
| * Returns the size of the MTP object | |
| * | |
| * @return the object size | |
| */ | |
| public final int getCompressedSize() { | |
| Preconditions.checkState(mCompressedSize >= 0); | |
| return mCompressedSize; | |
| } | |
| /** | |
| * Returns the size of the MTP object | |
| * | |
| * @return the object size | |
| */ | |
| public final long getCompressedSizeLong() { | |
| return uint32ToLong(mCompressedSize); | |
| } | |
| /** | |
| * Returns the format code for the MTP object's thumbnail | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail format code | |
| */ | |
| public final int getThumbFormat() { | |
| return mThumbFormat; | |
| } | |
| /** | |
| * Returns the size of the MTP object's thumbnail | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail size | |
| */ | |
| public final int getThumbCompressedSize() { | |
| Preconditions.checkState(mThumbCompressedSize >= 0); | |
| return mThumbCompressedSize; | |
| } | |
| /** | |
| * Returns the size of the MTP object's thumbnail | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail size | |
| */ | |
| public final long getThumbCompressedSizeLong() { | |
| return uint32ToLong(mThumbCompressedSize); | |
| } | |
| /** | |
| * Returns the width of the MTP object's thumbnail in pixels | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail width | |
| */ | |
| public final int getThumbPixWidth() { | |
| Preconditions.checkState(mThumbPixWidth >= 0); | |
| return mThumbPixWidth; | |
| } | |
| /** | |
| * Returns the width of the MTP object's thumbnail in pixels | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail width | |
| */ | |
| public final long getThumbPixWidthLong() { | |
| return uint32ToLong(mThumbPixWidth); | |
| } | |
| /** | |
| * Returns the height of the MTP object's thumbnail in pixels | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail height | |
| */ | |
| public final int getThumbPixHeight() { | |
| Preconditions.checkState(mThumbPixHeight >= 0); | |
| return mThumbPixHeight; | |
| } | |
| /** | |
| * Returns the height of the MTP object's thumbnail in pixels | |
| * Will be zero for objects with no thumbnail | |
| * | |
| * @return the thumbnail height | |
| */ | |
| public final long getThumbPixHeightLong() { | |
| return uint32ToLong(mThumbPixHeight); | |
| } | |
| /** | |
| * Returns the width of the MTP object in pixels | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image width | |
| */ | |
| public final int getImagePixWidth() { | |
| Preconditions.checkState(mImagePixWidth >= 0); | |
| return mImagePixWidth; | |
| } | |
| /** | |
| * Returns the width of the MTP object in pixels | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image width | |
| */ | |
| public final long getImagePixWidthLong() { | |
| return uint32ToLong(mImagePixWidth); | |
| } | |
| /** | |
| * Returns the height of the MTP object in pixels | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image height | |
| */ | |
| public final int getImagePixHeight() { | |
| Preconditions.checkState(mImagePixHeight >= 0); | |
| return mImagePixHeight; | |
| } | |
| /** | |
| * Returns the height of the MTP object in pixels | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image height | |
| */ | |
| public final long getImagePixHeightLong() { | |
| return uint32ToLong(mImagePixHeight); | |
| } | |
| /** | |
| * Returns the depth of the MTP object in bits per pixel | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image depth | |
| */ | |
| public final int getImagePixDepth() { | |
| Preconditions.checkState(mImagePixDepth >= 0); | |
| return mImagePixDepth; | |
| } | |
| /** | |
| * Returns the depth of the MTP object in bits per pixel | |
| * Will be zero for non-image objects | |
| * | |
| * @return the image depth | |
| */ | |
| public final long getImagePixDepthLong() { | |
| return uint32ToLong(mImagePixDepth); | |
| } | |
| /** | |
| * Returns the object handle for the object's parent | |
| * Will be zero for the root directory of a storage unit | |
| * | |
| * @return the object's parent | |
| */ | |
| public final int getParent() { | |
| return mParent; | |
| } | |
| /** | |
| * Returns the association type for the MTP object | |
| * Will be zero objects that are not of format | |
| * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION} | |
| * For directories the association type is typically | |
| * {@link android.mtp.MtpConstants#ASSOCIATION_TYPE_GENERIC_FOLDER} | |
| * | |
| * @return the object's association type | |
| */ | |
| public final int getAssociationType() { | |
| return mAssociationType; | |
| } | |
| /** | |
| * Returns the association description for the MTP object | |
| * Will be zero objects that are not of format | |
| * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION} | |
| * | |
| * @return the object's association description | |
| */ | |
| public final int getAssociationDesc() { | |
| return mAssociationDesc; | |
| } | |
| /** | |
| * Returns the sequence number for the MTP object | |
| * This field is typically not used for MTP devices, | |
| * but is sometimes used to define a sequence of photos | |
| * on PTP cameras. | |
| * | |
| * @return the object's sequence number | |
| */ | |
| public final int getSequenceNumber() { | |
| Preconditions.checkState(mSequenceNumber >= 0); | |
| return mSequenceNumber; | |
| } | |
| /** | |
| * Returns the sequence number for the MTP object | |
| * This field is typically not used for MTP devices, | |
| * but is sometimes used to define a sequence of photos | |
| * on PTP cameras. | |
| * | |
| * @return the object's sequence number | |
| */ | |
| public final long getSequenceNumberLong() { | |
| return uint32ToLong(mSequenceNumber); | |
| } | |
| /** | |
| * Returns the name of the MTP object | |
| * | |
| * @return the object's name | |
| */ | |
| public final @NonNull String getName() { | |
| return mName; | |
| } | |
| /** | |
| * Returns the creation date of the MTP object | |
| * The value is represented as milliseconds since January 1, 1970 | |
| * | |
| * @return the object's creation date | |
| */ | |
| public final long getDateCreated() { | |
| return mDateCreated; | |
| } | |
| /** | |
| * Returns the modification date of the MTP object | |
| * The value is represented as milliseconds since January 1, 1970 | |
| * | |
| * @return the object's modification date | |
| */ | |
| public final long getDateModified() { | |
| return mDateModified; | |
| } | |
| /** | |
| * Returns a comma separated list of keywords for the MTP object | |
| * | |
| * @return the object's keyword list | |
| */ | |
| public final @NonNull String getKeywords() { | |
| return mKeywords; | |
| } | |
| /** | |
| * Builds a new object info instance. | |
| */ | |
| public static class Builder { | |
| private MtpObjectInfo mObjectInfo; | |
| public Builder() { | |
| mObjectInfo = new MtpObjectInfo(); | |
| mObjectInfo.mHandle = -1; | |
| } | |
| /** | |
| * Creates a builder on a copy of an existing object info. | |
| * All fields, except the object handle will be copied. | |
| * | |
| * @param objectInfo object info of an existing entry | |
| */ | |
| public Builder(MtpObjectInfo objectInfo) { | |
| mObjectInfo = new MtpObjectInfo(); | |
| mObjectInfo.mHandle = -1; | |
| mObjectInfo.mAssociationDesc = objectInfo.mAssociationDesc; | |
| mObjectInfo.mAssociationType = objectInfo.mAssociationType; | |
| mObjectInfo.mCompressedSize = objectInfo.mCompressedSize; | |
| mObjectInfo.mDateCreated = objectInfo.mDateCreated; | |
| mObjectInfo.mDateModified = objectInfo.mDateModified; | |
| mObjectInfo.mFormat = objectInfo.mFormat; | |
| mObjectInfo.mImagePixDepth = objectInfo.mImagePixDepth; | |
| mObjectInfo.mImagePixHeight = objectInfo.mImagePixHeight; | |
| mObjectInfo.mImagePixWidth = objectInfo.mImagePixWidth; | |
| mObjectInfo.mKeywords = objectInfo.mKeywords; | |
| mObjectInfo.mName = objectInfo.mName; | |
| mObjectInfo.mParent = objectInfo.mParent; | |
| mObjectInfo.mProtectionStatus = objectInfo.mProtectionStatus; | |
| mObjectInfo.mSequenceNumber = objectInfo.mSequenceNumber; | |
| mObjectInfo.mStorageId = objectInfo.mStorageId; | |
| mObjectInfo.mThumbCompressedSize = objectInfo.mThumbCompressedSize; | |
| mObjectInfo.mThumbFormat = objectInfo.mThumbFormat; | |
| mObjectInfo.mThumbPixHeight = objectInfo.mThumbPixHeight; | |
| mObjectInfo.mThumbPixWidth = objectInfo.mThumbPixWidth; | |
| } | |
| public Builder setObjectHandle(int value) { | |
| mObjectInfo.mHandle = value; | |
| return this; | |
| } | |
| public Builder setAssociationDesc(int value) { | |
| mObjectInfo.mAssociationDesc = value; | |
| return this; | |
| } | |
| public Builder setAssociationType(int value) { | |
| mObjectInfo.mAssociationType = value; | |
| return this; | |
| } | |
| public Builder setCompressedSize(long value) { | |
| mObjectInfo.mCompressedSize = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setDateCreated(long value) { | |
| mObjectInfo.mDateCreated = value; | |
| return this; | |
| } | |
| public Builder setDateModified(long value) { | |
| mObjectInfo.mDateModified = value; | |
| return this; | |
| } | |
| public Builder setFormat(int value) { | |
| mObjectInfo.mFormat = value; | |
| return this; | |
| } | |
| public Builder setImagePixDepth(long value) { | |
| mObjectInfo.mImagePixDepth = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setImagePixHeight(long value) { | |
| mObjectInfo.mImagePixHeight = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setImagePixWidth(long value) { | |
| mObjectInfo.mImagePixWidth = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setKeywords(@NonNull String value) { | |
| if (VMRuntime.getRuntime().getTargetSdkVersion() > Build.VERSION_CODES.N_MR1) { | |
| Preconditions.checkNotNull(value); | |
| } else if (value == null) { | |
| // Before N_MR1 we accept null value and it was regarded as an empty string in | |
| // MtpDevice#sendObjectInfo. | |
| value = ""; | |
| } | |
| mObjectInfo.mKeywords = value; | |
| return this; | |
| } | |
| public Builder setName(@NonNull String value) { | |
| Preconditions.checkNotNull(value); | |
| mObjectInfo.mName = value; | |
| return this; | |
| } | |
| public Builder setParent(int value) { | |
| mObjectInfo.mParent = value; | |
| return this; | |
| } | |
| public Builder setProtectionStatus(int value) { | |
| mObjectInfo.mProtectionStatus = value; | |
| return this; | |
| } | |
| public Builder setSequenceNumber(long value) { | |
| mObjectInfo.mSequenceNumber = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setStorageId(int value) { | |
| mObjectInfo.mStorageId = value; | |
| return this; | |
| } | |
| public Builder setThumbCompressedSize(long value) { | |
| mObjectInfo.mThumbCompressedSize = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setThumbFormat(int value) { | |
| mObjectInfo.mThumbFormat = value; | |
| return this; | |
| } | |
| public Builder setThumbPixHeight(long value) { | |
| mObjectInfo.mThumbPixHeight = longToUint32(value, "value"); | |
| return this; | |
| } | |
| public Builder setThumbPixWidth(long value) { | |
| mObjectInfo.mThumbPixWidth = longToUint32(value, "value"); | |
| return this; | |
| } | |
| /** | |
| * Builds the object info instance. Once called, methods of the builder | |
| * must not be called anymore. | |
| * | |
| * @return the object info of the newly created file, or NULL in case | |
| * of an error. | |
| */ | |
| public MtpObjectInfo build() { | |
| MtpObjectInfo result = mObjectInfo; | |
| mObjectInfo = null; | |
| return result; | |
| } | |
| } | |
| private static long uint32ToLong(int value) { | |
| return value < 0 ? 0x100000000L + value : value; | |
| } | |
| private static int longToUint32(long value, String valueName) { | |
| Preconditions.checkArgumentInRange(value, 0, 0xffffffffL, valueName); | |
| return (int) value; | |
| } | |
| } |