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 { onImportProgress(int visitedCount, int totalCount, String pathIfSuccessful)45 void onImportProgress(int visitedCount, int totalCount, String pathIfSuccessful); 46 onImportFinish(Collection<IngestObjectInfo> objectsNotImported, int visitedCount)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 ImportTask(MtpDevice device, Collection<IngestObjectInfo> objectsToImport, String destAlbumName, Context context)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 setListener(Listener listener)67 public void setListener(Listener listener) { 68 mListener = listener; 69 } 70 71 @Override run()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 hasSpaceForSize(long size)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