• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
MtpObjectInfo()54      private MtpObjectInfo() {
55      }
56  
57      /**
58       * Returns the object handle for the MTP object
59       *
60       * @return the object handle
61       */
getObjectHandle()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       */
getStorageId()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       */
getFormat()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       */
getProtectionStatus()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       */
getCompressedSize()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       */
getCompressedSizeLong()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       */
getThumbFormat()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       */
getThumbCompressedSize()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       */
getThumbCompressedSizeLong()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       */
getThumbPixWidth()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       */
getThumbPixWidthLong()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       */
getThumbPixHeight()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       */
getThumbPixHeightLong()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       */
getImagePixWidth()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       */
getImagePixWidthLong()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       */
getImagePixHeight()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       */
getImagePixHeightLong()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       */
getImagePixDepth()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       */
getImagePixDepthLong()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       */
getParent()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       */
getAssociationType()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       */
getAssociationDesc()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       */
getSequenceNumber()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       */
getSequenceNumberLong()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       */
getName()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       */
getDateCreated()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       */
getDateModified()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       */
getKeywords()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  
Builder()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           */
Builder(MtpObjectInfo objectInfo)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  
setObjectHandle(int value)393          public Builder setObjectHandle(int value) {
394              mObjectInfo.mHandle = value;
395              return this;
396          }
397  
setAssociationDesc(int value)398          public Builder setAssociationDesc(int value) {
399              mObjectInfo.mAssociationDesc = value;
400              return this;
401          }
402  
setAssociationType(int value)403          public Builder setAssociationType(int value) {
404              mObjectInfo.mAssociationType = value;
405              return this;
406          }
407  
setCompressedSize(long value)408          public Builder setCompressedSize(long value) {
409              mObjectInfo.mCompressedSize = longToUint32(value, "value");
410              return this;
411          }
412  
setDateCreated(long value)413          public Builder setDateCreated(long value) {
414              mObjectInfo.mDateCreated = value;
415              return this;
416          }
417  
setDateModified(long value)418          public Builder setDateModified(long value) {
419              mObjectInfo.mDateModified = value;
420              return this;
421          }
422  
setFormat(int value)423          public Builder setFormat(int value) {
424              mObjectInfo.mFormat = value;
425              return this;
426          }
427  
setImagePixDepth(long value)428          public Builder setImagePixDepth(long value) {
429              mObjectInfo.mImagePixDepth = longToUint32(value, "value");
430              return this;
431          }
432  
setImagePixHeight(long value)433          public Builder setImagePixHeight(long value) {
434              mObjectInfo.mImagePixHeight = longToUint32(value, "value");
435              return this;
436          }
437  
setImagePixWidth(long value)438          public Builder setImagePixWidth(long value) {
439              mObjectInfo.mImagePixWidth = longToUint32(value, "value");
440              return this;
441          }
442  
setKeywords(@onNull String value)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  
setName(@onNull String value)455          public Builder setName(@NonNull String value) {
456              Preconditions.checkNotNull(value);
457              mObjectInfo.mName = value;
458              return this;
459          }
460  
setParent(int value)461          public Builder setParent(int value) {
462              mObjectInfo.mParent = value;
463              return this;
464          }
465  
setProtectionStatus(int value)466          public Builder setProtectionStatus(int value) {
467              mObjectInfo.mProtectionStatus = value;
468              return this;
469          }
470  
setSequenceNumber(long value)471          public Builder setSequenceNumber(long value) {
472              mObjectInfo.mSequenceNumber = longToUint32(value, "value");
473              return this;
474          }
475  
setStorageId(int value)476          public Builder setStorageId(int value) {
477              mObjectInfo.mStorageId = value;
478              return this;
479          }
480  
setThumbCompressedSize(long value)481          public Builder setThumbCompressedSize(long value) {
482              mObjectInfo.mThumbCompressedSize = longToUint32(value, "value");
483              return this;
484          }
485  
setThumbFormat(int value)486          public Builder setThumbFormat(int value) {
487              mObjectInfo.mThumbFormat = value;
488              return this;
489          }
490  
setThumbPixHeight(long value)491          public Builder setThumbPixHeight(long value) {
492              mObjectInfo.mThumbPixHeight = longToUint32(value, "value");
493              return this;
494          }
495  
setThumbPixWidth(long value)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           */
build()508          public MtpObjectInfo build() {
509              MtpObjectInfo result = mObjectInfo;
510              mObjectInfo = null;
511              return result;
512          }
513      }
514  
uint32ToLong(int value)515      private static long uint32ToLong(int value) {
516          return value < 0 ? 0x100000000L + value : value;
517      }
518  
longToUint32(long value, String valueName)519      private static int longToUint32(long value, String valueName) {
520          Preconditions.checkArgumentInRange(value, 0, 0xffffffffL, valueName);
521          return (int) value;
522      }
523  }
524