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