Home | History | Annotate | Download | only in data
      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 com.android.gallery3d.data;
     18 
     19 import android.annotation.TargetApi;
     20 import android.hardware.usb.UsbDevice;
     21 import android.mtp.MtpConstants;
     22 import android.mtp.MtpObjectInfo;
     23 import android.mtp.MtpStorageInfo;
     24 import android.net.Uri;
     25 import android.util.Log;
     26 
     27 import com.android.gallery3d.app.GalleryApp;
     28 import com.android.gallery3d.common.ApiHelper;
     29 
     30 import java.util.ArrayList;
     31 import java.util.List;
     32 
     33 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB_MR1)
     34 public class MtpDevice extends MediaSet {
     35     private static final String TAG = "MtpDevice";
     36 
     37     private final GalleryApp mApplication;
     38     private final int mDeviceId;
     39     private final String mDeviceName;
     40     private final MtpContext mMtpContext;
     41     private final String mName;
     42     private final ChangeNotifier mNotifier;
     43     private final Path mItemPath;
     44     private List<MtpObjectInfo> mJpegChildren;
     45 
     46     public MtpDevice(Path path, GalleryApp application, int deviceId,
     47             String name, MtpContext mtpContext) {
     48         super(path, nextVersionNumber());
     49         mApplication = application;
     50         mDeviceId = deviceId;
     51         mDeviceName = UsbDevice.getDeviceName(deviceId);
     52         mMtpContext = mtpContext;
     53         mName = name;
     54         mNotifier = new ChangeNotifier(this, Uri.parse("mtp://"), application);
     55         mItemPath = Path.fromString("/mtp/item/" + String.valueOf(deviceId));
     56         mJpegChildren = new ArrayList<MtpObjectInfo>();
     57     }
     58 
     59     public MtpDevice(Path path, GalleryApp application, int deviceId,
     60             MtpContext mtpContext) {
     61         this(path, application, deviceId,
     62                 MtpDeviceSet.getDeviceName(mtpContext, deviceId), mtpContext);
     63     }
     64 
     65     private List<MtpObjectInfo> loadItems() {
     66         ArrayList<MtpObjectInfo> result = new ArrayList<MtpObjectInfo>();
     67 
     68         List<MtpStorageInfo> storageList = mMtpContext.getMtpClient()
     69                  .getStorageList(mDeviceName);
     70         if (storageList == null) return result;
     71 
     72         for (MtpStorageInfo info : storageList) {
     73             collectJpegChildren(info.getStorageId(), 0, result);
     74         }
     75 
     76         return result;
     77     }
     78 
     79     private void collectJpegChildren(int storageId, int objectId,
     80             ArrayList<MtpObjectInfo> result) {
     81         ArrayList<MtpObjectInfo> dirChildren = new ArrayList<MtpObjectInfo>();
     82 
     83         queryChildren(storageId, objectId, result, dirChildren);
     84 
     85         for (int i = 0, n = dirChildren.size(); i < n; i++) {
     86             MtpObjectInfo info = dirChildren.get(i);
     87             collectJpegChildren(storageId, info.getObjectHandle(), result);
     88         }
     89     }
     90 
     91     private void queryChildren(int storageId, int objectId,
     92             ArrayList<MtpObjectInfo> jpeg, ArrayList<MtpObjectInfo> dir) {
     93         List<MtpObjectInfo> children = mMtpContext.getMtpClient().getObjectList(
     94                 mDeviceName, storageId, objectId);
     95         if (children == null) return;
     96 
     97         for (MtpObjectInfo obj : children) {
     98             int format = obj.getFormat();
     99             switch (format) {
    100                 case MtpConstants.FORMAT_JFIF:
    101                 case MtpConstants.FORMAT_EXIF_JPEG:
    102                     jpeg.add(obj);
    103                     break;
    104                 case MtpConstants.FORMAT_ASSOCIATION:
    105                     dir.add(obj);
    106                     break;
    107                 default:
    108                     Log.w(TAG, "other type: name = " + obj.getName()
    109                             + ", format = " + format);
    110             }
    111         }
    112     }
    113 
    114     public static MtpObjectInfo getObjectInfo(MtpContext mtpContext, int deviceId,
    115             int objectId) {
    116         String deviceName = UsbDevice.getDeviceName(deviceId);
    117         return mtpContext.getMtpClient().getObjectInfo(deviceName, objectId);
    118     }
    119 
    120     @Override
    121     public ArrayList<MediaItem> getMediaItem(int start, int count) {
    122         ArrayList<MediaItem> result = new ArrayList<MediaItem>();
    123         int begin = start;
    124         int end = Math.min(start + count, mJpegChildren.size());
    125 
    126         DataManager dataManager = mApplication.getDataManager();
    127         for (int i = begin; i < end; i++) {
    128             MtpObjectInfo child = mJpegChildren.get(i);
    129             Path childPath = mItemPath.getChild(child.getObjectHandle());
    130             synchronized (DataManager.LOCK) {
    131                 MtpImage image = (MtpImage) dataManager.peekMediaObject(childPath);
    132                 if (image == null) {
    133                     image = new MtpImage(
    134                             childPath, mApplication, mDeviceId, child, mMtpContext);
    135                 } else {
    136                     image.updateContent(child);
    137                 }
    138                 result.add(image);
    139             }
    140         }
    141         return result;
    142     }
    143 
    144     @Override
    145     public int getMediaItemCount() {
    146         return mJpegChildren.size();
    147     }
    148 
    149     @Override
    150     public String getName() {
    151         return mName;
    152     }
    153 
    154     @Override
    155     public long reload() {
    156         if (mNotifier.isDirty()) {
    157             mDataVersion = nextVersionNumber();
    158             mJpegChildren = loadItems();
    159         }
    160         return mDataVersion;
    161     }
    162 
    163     @Override
    164     public int getSupportedOperations() {
    165         return SUPPORT_IMPORT;
    166     }
    167 
    168     @Override
    169     public boolean Import() {
    170         return mMtpContext.copyAlbum(mDeviceName, mName, mJpegChildren);
    171     }
    172 
    173     @Override
    174     public boolean isLeafAlbum() {
    175         return true;
    176     }
    177 }
    178