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.mtp.MtpDeviceInfo;
     21 import android.net.Uri;
     22 import android.os.Handler;
     23 import android.util.Log;
     24 
     25 import com.android.gallery3d.R;
     26 import com.android.gallery3d.app.GalleryApp;
     27 import com.android.gallery3d.common.ApiHelper;
     28 import com.android.gallery3d.util.Future;
     29 import com.android.gallery3d.util.FutureListener;
     30 import com.android.gallery3d.util.MediaSetUtils;
     31 import com.android.gallery3d.util.ThreadPool.Job;
     32 import com.android.gallery3d.util.ThreadPool.JobContext;
     33 
     34 import java.util.ArrayList;
     35 import java.util.Collections;
     36 import java.util.List;
     37 
     38 // MtpDeviceSet -- MtpDevice -- MtpImage
     39 @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB_MR1)
     40 public class MtpDeviceSet extends MediaSet
     41         implements FutureListener<ArrayList<MediaSet>> {
     42     private static final String TAG = "MtpDeviceSet";
     43 
     44     private GalleryApp mApplication;
     45     private final ChangeNotifier mNotifier;
     46     private final MtpContext mMtpContext;
     47     private final String mName;
     48     private final Handler mHandler;
     49 
     50     private Future<ArrayList<MediaSet>> mLoadTask;
     51     private ArrayList<MediaSet> mDeviceSet = new ArrayList<MediaSet>();
     52     private ArrayList<MediaSet> mLoadBuffer;
     53     private boolean mIsLoading;
     54 
     55     public MtpDeviceSet(Path path, GalleryApp application, MtpContext mtpContext) {
     56         super(path, nextVersionNumber());
     57         mApplication = application;
     58         mNotifier = new ChangeNotifier(this, Uri.parse("mtp://"), application);
     59         mMtpContext = mtpContext;
     60         mName = application.getResources().getString(R.string.set_label_mtp_devices);
     61         mHandler = new Handler(mApplication.getMainLooper());
     62     }
     63 
     64     private class DevicesLoader implements Job<ArrayList<MediaSet>> {
     65         @Override
     66         public ArrayList<MediaSet> run(JobContext jc) {
     67             DataManager dataManager = mApplication.getDataManager();
     68             ArrayList<MediaSet> result = new ArrayList<MediaSet>();
     69 
     70             // Enumerate all devices
     71             List<android.mtp.MtpDevice> devices = mMtpContext.getMtpClient().getDeviceList();
     72             Log.v(TAG, "loadDevices: " + devices + ", size=" + devices.size());
     73             for (android.mtp.MtpDevice mtpDevice : devices) {
     74                 synchronized (DataManager.LOCK) {
     75                     int deviceId = mtpDevice.getDeviceId();
     76                     Path childPath = mPath.getChild(deviceId);
     77                     MtpDevice device = (MtpDevice) dataManager.peekMediaObject(childPath);
     78                     if (device == null) {
     79                         device = new MtpDevice(childPath, mApplication, deviceId, mMtpContext);
     80                     }
     81                     Log.d(TAG, "add device " + device);
     82                     result.add(device);
     83                 }
     84             }
     85             Collections.sort(result, MediaSetUtils.NAME_COMPARATOR);
     86             return result;
     87         }
     88     }
     89 
     90     public static String getDeviceName(MtpContext mtpContext, int deviceId) {
     91         android.mtp.MtpDevice device = mtpContext.getMtpClient().getDevice(deviceId);
     92         if (device == null) {
     93             return "";
     94         }
     95         MtpDeviceInfo info = device.getDeviceInfo();
     96         if (info == null) {
     97             return "";
     98         }
     99         String manufacturer = info.getManufacturer().trim();
    100         String model = info.getModel().trim();
    101         return manufacturer + " " + model;
    102     }
    103 
    104     @Override
    105     public MediaSet getSubMediaSet(int index) {
    106         return index < mDeviceSet.size() ? mDeviceSet.get(index) : null;
    107     }
    108 
    109     @Override
    110     public int getSubMediaSetCount() {
    111         return mDeviceSet.size();
    112     }
    113 
    114     @Override
    115     public String getName() {
    116         return mName;
    117     }
    118 
    119     @Override
    120     public synchronized boolean isLoading() {
    121         return mIsLoading;
    122     }
    123 
    124     @Override
    125     public synchronized long reload() {
    126         if (mNotifier.isDirty()) {
    127             if (mLoadTask != null) mLoadTask.cancel();
    128             mIsLoading = true;
    129             mLoadTask = mApplication.getThreadPool().submit(new DevicesLoader(), this);
    130         }
    131         if (mLoadBuffer != null) {
    132             mDeviceSet = mLoadBuffer;
    133             mLoadBuffer = null;
    134             for (MediaSet device : mDeviceSet) {
    135                 device.reload();
    136             }
    137             mDataVersion = nextVersionNumber();
    138         }
    139         return mDataVersion;
    140     }
    141 
    142     @Override
    143     public synchronized void onFutureDone(Future<ArrayList<MediaSet>> future) {
    144         if (future != mLoadTask) return;
    145         mLoadBuffer = future.get();
    146         mIsLoading = false;
    147         if (mLoadBuffer == null) mLoadBuffer = new ArrayList<MediaSet>();
    148 
    149         mHandler.post(new Runnable() {
    150             @Override
    151             public void run() {
    152                 notifyContentChanged();
    153             }
    154         });
    155     }
    156 }
    157