Home | History | Annotate | Download | only in mtp
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.mtp;
     18 
     19 import android.annotation.NonNull;
     20 import android.os.Build;
     21 
     22 import com.android.internal.util.Preconditions;
     23 
     24 import dalvik.system.VMRuntime;
     25 
     26 /**
     27  * This class encapsulates information about an object on an MTP device.
     28  * This corresponds to the ObjectInfo Dataset described in
     29  * section 5.3.1 of the MTP specification.
     30  */
     31 public final class MtpObjectInfo {
     32     private int mHandle;
     33     private int mStorageId;
     34     private int mFormat;
     35     private int mProtectionStatus;
     36     private int mCompressedSize;
     37     private int mThumbFormat;
     38     private int mThumbCompressedSize;
     39     private int mThumbPixWidth;
     40     private int mThumbPixHeight;
     41     private int mImagePixWidth;
     42     private int mImagePixHeight;
     43     private int mImagePixDepth;
     44     private int mParent;
     45     private int mAssociationType;
     46     private int mAssociationDesc;
     47     private int mSequenceNumber;
     48     private String mName = "";
     49     private long mDateCreated;
     50     private long mDateModified;
     51     private String mKeywords = "";
     52 
     53     // only instantiated via JNI or via a builder
     54     private MtpObjectInfo() {
     55     }
     56 
     57     /**
     58      * Returns the object handle for the MTP object
     59      *
     60      * @return the object handle
     61      */
     62     public final int getObjectHandle() {
     63         return mHandle;
     64     }
     65 
     66     /**
     67      * Returns the storage ID for the MTP object's storage unit
     68      *
     69      * @return the storage ID
     70      */
     71     public final int getStorageId() {
     72         return mStorageId;
     73     }
     74 
     75     /**
     76      * Returns the format code for the MTP object
     77      *
     78      * @return the format code
     79      */
     80     public final int getFormat() {
     81         return mFormat;
     82     }
     83 
     84     /**
     85      * Returns the protection status for the MTP object
     86      * Possible values are:
     87      *
     88      * <ul>
     89      * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NONE}
     90      * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_READ_ONLY}
     91      * <li> {@link android.mtp.MtpConstants#PROTECTION_STATUS_NON_TRANSFERABLE_DATA}
     92      * </ul>
     93      *
     94      * @return the protection status
     95      */
     96     public final int getProtectionStatus() {
     97         return mProtectionStatus;
     98     }
     99 
    100     /**
    101      * Returns the size of the MTP object
    102      *
    103      * @return the object size
    104      */
    105     public final int getCompressedSize() {
    106         Preconditions.checkState(mCompressedSize >= 0);
    107         return mCompressedSize;
    108     }
    109 
    110     /**
    111      * Returns the size of the MTP object
    112      *
    113      * @return the object size
    114      */
    115     public final long getCompressedSizeLong() {
    116         return uint32ToLong(mCompressedSize);
    117     }
    118 
    119     /**
    120      * Returns the format code for the MTP object's thumbnail
    121      * Will be zero for objects with no thumbnail
    122      *
    123      * @return the thumbnail format code
    124      */
    125     public final int getThumbFormat() {
    126         return mThumbFormat;
    127     }
    128 
    129     /**
    130      * Returns the size of the MTP object's thumbnail
    131      * Will be zero for objects with no thumbnail
    132      *
    133      * @return the thumbnail size
    134      */
    135     public final int getThumbCompressedSize() {
    136         Preconditions.checkState(mThumbCompressedSize >= 0);
    137         return mThumbCompressedSize;
    138     }
    139 
    140     /**
    141      * Returns the size of the MTP object's thumbnail
    142      * Will be zero for objects with no thumbnail
    143      *
    144      * @return the thumbnail size
    145      */
    146     public final long getThumbCompressedSizeLong() {
    147         return uint32ToLong(mThumbCompressedSize);
    148     }
    149 
    150     /**
    151      * Returns the width of the MTP object's thumbnail in pixels
    152      * Will be zero for objects with no thumbnail
    153      *
    154      * @return the thumbnail width
    155      */
    156     public final int getThumbPixWidth() {
    157         Preconditions.checkState(mThumbPixWidth >= 0);
    158         return mThumbPixWidth;
    159     }
    160 
    161     /**
    162      * Returns the width of the MTP object's thumbnail in pixels
    163      * Will be zero for objects with no thumbnail
    164      *
    165      * @return the thumbnail width
    166      */
    167     public final long getThumbPixWidthLong() {
    168         return uint32ToLong(mThumbPixWidth);
    169     }
    170 
    171     /**
    172      * Returns the height of the MTP object's thumbnail in pixels
    173      * Will be zero for objects with no thumbnail
    174      *
    175      * @return the thumbnail height
    176      */
    177     public final int getThumbPixHeight() {
    178         Preconditions.checkState(mThumbPixHeight >= 0);
    179         return mThumbPixHeight;
    180     }
    181 
    182     /**
    183      * Returns the height of the MTP object's thumbnail in pixels
    184      * Will be zero for objects with no thumbnail
    185      *
    186      * @return the thumbnail height
    187      */
    188     public final long getThumbPixHeightLong() {
    189         return uint32ToLong(mThumbPixHeight);
    190     }
    191 
    192     /**
    193      * Returns the width of the MTP object in pixels
    194      * Will be zero for non-image objects
    195      *
    196      * @return the image width
    197      */
    198     public final int getImagePixWidth() {
    199         Preconditions.checkState(mImagePixWidth >= 0);
    200         return mImagePixWidth;
    201     }
    202 
    203     /**
    204      * Returns the width of the MTP object in pixels
    205      * Will be zero for non-image objects
    206      *
    207      * @return the image width
    208      */
    209     public final long getImagePixWidthLong() {
    210         return uint32ToLong(mImagePixWidth);
    211     }
    212 
    213     /**
    214      * Returns the height of the MTP object in pixels
    215      * Will be zero for non-image objects
    216      *
    217      * @return the image height
    218      */
    219     public final int getImagePixHeight() {
    220         Preconditions.checkState(mImagePixHeight >= 0);
    221         return mImagePixHeight;
    222     }
    223 
    224     /**
    225      * Returns the height of the MTP object in pixels
    226      * Will be zero for non-image objects
    227      *
    228      * @return the image height
    229      */
    230     public final long getImagePixHeightLong() {
    231         return uint32ToLong(mImagePixHeight);
    232     }
    233 
    234     /**
    235      * Returns the depth of the MTP object in bits per pixel
    236      * Will be zero for non-image objects
    237      *
    238      * @return the image depth
    239      */
    240     public final int getImagePixDepth() {
    241         Preconditions.checkState(mImagePixDepth >= 0);
    242         return mImagePixDepth;
    243     }
    244 
    245     /**
    246      * Returns the depth of the MTP object in bits per pixel
    247      * Will be zero for non-image objects
    248      *
    249      * @return the image depth
    250      */
    251     public final long getImagePixDepthLong() {
    252         return uint32ToLong(mImagePixDepth);
    253     }
    254 
    255     /**
    256      * Returns the object handle for the object's parent
    257      * Will be zero for the root directory of a storage unit
    258      *
    259      * @return the object's parent
    260      */
    261     public final int getParent() {
    262         return mParent;
    263     }
    264 
    265     /**
    266      * Returns the association type for the MTP object
    267      * Will be zero objects that are not of format
    268      * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION}
    269      * For directories the association type is typically
    270      * {@link android.mtp.MtpConstants#ASSOCIATION_TYPE_GENERIC_FOLDER}
    271      *
    272      * @return the object's association type
    273      */
    274     public final int getAssociationType() {
    275         return mAssociationType;
    276     }
    277 
    278     /**
    279      * Returns the association description for the MTP object
    280      * Will be zero objects that are not of format
    281      * {@link android.mtp.MtpConstants#FORMAT_ASSOCIATION}
    282      *
    283      * @return the object's association description
    284      */
    285     public final int getAssociationDesc() {
    286         return mAssociationDesc;
    287     }
    288 
    289     /**
    290      * Returns the sequence number for the MTP object
    291      * This field is typically not used for MTP devices,
    292      * but is sometimes used to define a sequence of photos
    293      * on PTP cameras.
    294      *
    295      * @return the object's sequence number
    296      */
    297     public final int getSequenceNumber() {
    298         Preconditions.checkState(mSequenceNumber >= 0);
    299         return mSequenceNumber;
    300     }
    301 
    302     /**
    303      * Returns the sequence number for the MTP object
    304      * This field is typically not used for MTP devices,
    305      * but is sometimes used to define a sequence of photos
    306      * on PTP cameras.
    307      *
    308      * @return the object's sequence number
    309      */
    310     public final long getSequenceNumberLong() {
    311         return uint32ToLong(mSequenceNumber);
    312     }
    313 
    314    /**
    315      * Returns the name of the MTP object
    316      *
    317      * @return the object's name
    318      */
    319     public final @NonNull String getName() {
    320         return mName;
    321     }
    322 
    323    /**
    324      * Returns the creation date of the MTP object
    325      * The value is represented as milliseconds since January 1, 1970
    326      *
    327      * @return the object's creation date
    328      */
    329     public final long getDateCreated() {
    330         return mDateCreated;
    331     }
    332 
    333    /**
    334      * Returns the modification date of the MTP object
    335      * The value is represented as milliseconds since January 1, 1970
    336      *
    337      * @return the object's modification date
    338      */
    339     public final long getDateModified() {
    340         return mDateModified;
    341     }
    342 
    343    /**
    344      * Returns a comma separated list of keywords for the MTP object
    345      *
    346      * @return the object's keyword list
    347      */
    348     public final @NonNull String getKeywords() {
    349         return mKeywords;
    350     }
    351 
    352     /**
    353      * Builds a new object info instance.
    354      */
    355     public static class Builder {
    356         private MtpObjectInfo mObjectInfo;
    357 
    358         public Builder() {
    359             mObjectInfo = new MtpObjectInfo();
    360             mObjectInfo.mHandle = -1;
    361         }
    362 
    363         /**
    364          * Creates a builder on a copy of an existing object info.
    365          * All fields, except the object handle will be copied.
    366          *
    367          * @param objectInfo object info of an existing entry
    368          */
    369         public Builder(MtpObjectInfo objectInfo) {
    370             mObjectInfo = new MtpObjectInfo();
    371             mObjectInfo.mHandle = -1;
    372             mObjectInfo.mAssociationDesc = objectInfo.mAssociationDesc;
    373             mObjectInfo.mAssociationType = objectInfo.mAssociationType;
    374             mObjectInfo.mCompressedSize = objectInfo.mCompressedSize;
    375             mObjectInfo.mDateCreated = objectInfo.mDateCreated;
    376             mObjectInfo.mDateModified = objectInfo.mDateModified;
    377             mObjectInfo.mFormat = objectInfo.mFormat;
    378             mObjectInfo.mImagePixDepth = objectInfo.mImagePixDepth;
    379             mObjectInfo.mImagePixHeight = objectInfo.mImagePixHeight;
    380             mObjectInfo.mImagePixWidth = objectInfo.mImagePixWidth;
    381             mObjectInfo.mKeywords = objectInfo.mKeywords;
    382             mObjectInfo.mName = objectInfo.mName;
    383             mObjectInfo.mParent = objectInfo.mParent;
    384             mObjectInfo.mProtectionStatus = objectInfo.mProtectionStatus;
    385             mObjectInfo.mSequenceNumber = objectInfo.mSequenceNumber;
    386             mObjectInfo.mStorageId = objectInfo.mStorageId;
    387             mObjectInfo.mThumbCompressedSize = objectInfo.mThumbCompressedSize;
    388             mObjectInfo.mThumbFormat = objectInfo.mThumbFormat;
    389             mObjectInfo.mThumbPixHeight = objectInfo.mThumbPixHeight;
    390             mObjectInfo.mThumbPixWidth = objectInfo.mThumbPixWidth;
    391         }
    392 
    393         public Builder setObjectHandle(int value) {
    394             mObjectInfo.mHandle = value;
    395             return this;
    396         }
    397 
    398         public Builder setAssociationDesc(int value) {
    399             mObjectInfo.mAssociationDesc = value;
    400             return this;
    401         }
    402 
    403         public Builder setAssociationType(int value) {
    404             mObjectInfo.mAssociationType = value;
    405             return this;
    406         }
    407 
    408         public Builder setCompressedSize(long value) {
    409             mObjectInfo.mCompressedSize = longToUint32(value, "value");
    410             return this;
    411         }
    412 
    413         public Builder setDateCreated(long value) {
    414             mObjectInfo.mDateCreated = value;
    415             return this;
    416         }
    417 
    418         public Builder setDateModified(long value) {
    419             mObjectInfo.mDateModified = value;
    420             return this;
    421         }
    422 
    423         public Builder setFormat(int value) {
    424             mObjectInfo.mFormat = value;
    425             return this;
    426         }
    427 
    428         public Builder setImagePixDepth(long value) {
    429             mObjectInfo.mImagePixDepth = longToUint32(value, "value");
    430             return this;
    431         }
    432 
    433         public Builder setImagePixHeight(long value) {
    434             mObjectInfo.mImagePixHeight = longToUint32(value, "value");
    435             return this;
    436         }
    437 
    438         public Builder setImagePixWidth(long value) {
    439             mObjectInfo.mImagePixWidth = longToUint32(value, "value");
    440             return this;
    441         }
    442 
    443         public Builder setKeywords(@NonNull String value) {
    444             if (VMRuntime.getRuntime().getTargetSdkVersion() > Build.VERSION_CODES.N_MR1) {
    445                 Preconditions.checkNotNull(value);
    446             } else if (value == null) {
    447                 // Before N_MR1 we accept null value and it was regarded as an empty string in
    448                 // MtpDevice#sendObjectInfo.
    449                 value = "";
    450             }
    451             mObjectInfo.mKeywords = value;
    452             return this;
    453         }
    454 
    455         public Builder setName(@NonNull String value) {
    456             Preconditions.checkNotNull(value);
    457             mObjectInfo.mName = value;
    458             return this;
    459         }
    460 
    461         public Builder setParent(int value) {
    462             mObjectInfo.mParent = value;
    463             return this;
    464         }
    465 
    466         public Builder setProtectionStatus(int value) {
    467             mObjectInfo.mProtectionStatus = value;
    468             return this;
    469         }
    470 
    471         public Builder setSequenceNumber(long value) {
    472             mObjectInfo.mSequenceNumber = longToUint32(value, "value");
    473             return this;
    474         }
    475 
    476         public Builder setStorageId(int value) {
    477             mObjectInfo.mStorageId = value;
    478             return this;
    479         }
    480 
    481         public Builder setThumbCompressedSize(long value) {
    482             mObjectInfo.mThumbCompressedSize = longToUint32(value, "value");
    483             return this;
    484         }
    485 
    486         public Builder setThumbFormat(int value) {
    487             mObjectInfo.mThumbFormat = value;
    488             return this;
    489         }
    490 
    491         public Builder setThumbPixHeight(long value) {
    492             mObjectInfo.mThumbPixHeight = longToUint32(value, "value");
    493             return this;
    494         }
    495 
    496         public Builder setThumbPixWidth(long value) {
    497             mObjectInfo.mThumbPixWidth = longToUint32(value, "value");
    498             return this;
    499         }
    500 
    501         /**
    502          * Builds the object info instance. Once called, methods of the builder
    503          * must not be called anymore.
    504          *
    505          * @return the object info of the newly created file, or NULL in case
    506          *         of an error.
    507          */
    508         public MtpObjectInfo build() {
    509             MtpObjectInfo result = mObjectInfo;
    510             mObjectInfo = null;
    511             return result;
    512         }
    513     }
    514 
    515     private static long uint32ToLong(int value) {
    516         return value < 0 ? 0x100000000L + value : value;
    517     }
    518 
    519     private static int longToUint32(long value, String valueName) {
    520         Preconditions.checkArgumentInRange(value, 0, 0xffffffffL, valueName);
    521         return (int) value;
    522     }
    523 }
    524