Home | History | Annotate | Download | only in data
      1 /*
      2  * Copyright (C) 2013 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.ingest.data;
     18 
     19 import android.annotation.TargetApi;
     20 import android.content.Context;
     21 import android.mtp.MtpDevice;
     22 import android.os.Build;
     23 import android.os.Environment;
     24 import android.os.PowerManager;
     25 import android.os.StatFs;
     26 import android.util.Log;
     27 
     28 import java.io.File;
     29 import java.util.Collection;
     30 import java.util.LinkedList;
     31 import java.util.List;
     32 
     33 /**
     34  * Task that handles the copying of items from an MTP device.
     35  */
     36 @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
     37 public class ImportTask implements Runnable {
     38 
     39   private static final String TAG = "ImportTask";
     40 
     41   /**
     42    * Import progress listener.
     43    */
     44   public interface Listener {
     45     void onImportProgress(int visitedCount, int totalCount, String pathIfSuccessful);
     46 
     47     void onImportFinish(Collection<IngestObjectInfo> objectsNotImported, int visitedCount);
     48   }
     49 
     50   private static final String WAKELOCK_LABEL = "Google Photos MTP Import Task";
     51 
     52   private Listener mListener;
     53   private String mDestAlbumName;
     54   private Collection<IngestObjectInfo> mObjectsToImport;
     55   private MtpDevice mDevice;
     56   private PowerManager.WakeLock mWakeLock;
     57 
     58   public ImportTask(MtpDevice device, Collection<IngestObjectInfo> objectsToImport,
     59       String destAlbumName, Context context) {
     60     mDestAlbumName = destAlbumName;
     61     mObjectsToImport = objectsToImport;
     62     mDevice = device;
     63     PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
     64     mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAKELOCK_LABEL);
     65   }
     66 
     67   public void setListener(Listener listener) {
     68     mListener = listener;
     69   }
     70 
     71   @Override
     72   public void run() {
     73     mWakeLock.acquire();
     74     try {
     75       List<IngestObjectInfo> objectsNotImported = new LinkedList<IngestObjectInfo>();
     76       int visited = 0;
     77       int total = mObjectsToImport.size();
     78       mListener.onImportProgress(visited, total, null);
     79       File dest = new File(Environment.getExternalStorageDirectory(), mDestAlbumName);
     80       dest.mkdirs();
     81       for (IngestObjectInfo object : mObjectsToImport) {
     82         visited++;
     83         String importedPath = null;
     84         if (hasSpaceForSize(object.getCompressedSize())) {
     85           importedPath = new File(dest, object.getName(mDevice)).getAbsolutePath();
     86           if (!mDevice.importFile(object.getObjectHandle(), importedPath)) {
     87             importedPath = null;
     88           }
     89         }
     90         if (importedPath == null) {
     91           objectsNotImported.add(object);
     92         }
     93         if (mListener != null) {
     94           mListener.onImportProgress(visited, total, importedPath);
     95         }
     96       }
     97       if (mListener != null) {
     98         mListener.onImportFinish(objectsNotImported, visited);
     99       }
    100     } finally {
    101       mListener = null;
    102       mWakeLock.release();
    103     }
    104   }
    105 
    106   private static boolean hasSpaceForSize(long size) {
    107     String state = Environment.getExternalStorageState();
    108     if (!Environment.MEDIA_MOUNTED.equals(state)) {
    109       return false;
    110     }
    111 
    112     String path = Environment.getExternalStorageDirectory().getPath();
    113     try {
    114       StatFs stat = new StatFs(path);
    115       return stat.getAvailableBlocks() * (long) stat.getBlockSize() > size;
    116     } catch (Exception e) {
    117       Log.i(TAG, "Fail to access external storage", e);
    118     }
    119     return false;
    120   }
    121 }
    122