MoveJob.java revision 87156dc8aebbe8a186569db7e660a981beab830c
1/* 2 * Copyright (C) 2016 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 17package com.android.documentsui.services; 18 19import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE; 20 21import android.app.Notification; 22import android.app.Notification.Builder; 23import android.content.Context; 24import android.os.RemoteException; 25import android.provider.DocumentsContract; 26import android.provider.DocumentsContract.Document; 27import android.util.Log; 28 29import com.android.documentsui.R; 30import com.android.documentsui.model.DocumentInfo; 31import com.android.documentsui.model.DocumentStack; 32 33import java.util.List; 34 35final class MoveJob extends CopyJob { 36 37 private static final String TAG = "MoveJob"; 38 39 /** 40 * Moves files to a destination identified by {@code destination}. 41 * Performs most work by delegating to CopyJob, then deleting 42 * a file after it has been copied. 43 * 44 * @see @link {@link Job} constructor for most param descriptions. 45 * 46 * @param srcs List of files to be moved. 47 */ 48 MoveJob(Context service, Context appContext, Listener listener, 49 String id, DocumentStack destination, List<DocumentInfo> srcs) { 50 super(service, appContext, listener, OPERATION_MOVE, id, destination, srcs); 51 } 52 53 @Override 54 Builder createProgressBuilder() { 55 return super.createProgressBuilder( 56 service.getString(R.string.move_notification_title), 57 R.drawable.ic_menu_copy, 58 service.getString(android.R.string.cancel), 59 R.drawable.ic_cab_cancel); 60 } 61 62 @Override 63 public Notification getSetupNotification() { 64 return getSetupNotification(service.getString(R.string.move_preparing)); 65 } 66 67 @Override 68 public Notification getProgressNotification() { 69 return getProgressNotification(R.string.copy_preparing); 70 } 71 72 @Override 73 Notification getFailureNotification() { 74 return getFailureNotification( 75 R.plurals.move_error_notification_title, R.drawable.ic_menu_copy); 76 } 77 78 @Override 79 boolean processDocument(DocumentInfo src, DocumentInfo dest) throws RemoteException { 80 81 // TODO: When optimized move kicks in, we're not making any progress updates. FIX IT! 82 83 // When moving within the same provider, try to use optimized moving. 84 // If not supported, then fallback to byte-by-byte copy/move. 85 if (src.authority.equals(dest.authority)) { 86 if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) { 87 if (DocumentsContract.moveDocument(getClient(src), src.derivedUri, 88 dest.derivedUri) == null) { 89 onFileFailed(src); 90 return false; 91 } 92 return true; 93 } 94 } 95 96 // Moving virtual files by bytes is not supported. This is because, it would involve 97 // conversion, and the source file should not be deleted in such case (as it's a different 98 // file). 99 if (src.isVirtualDocument()) { 100 Log.w(TAG, "Cannot move virtual files byte by byte."); 101 onFileFailed(src); 102 return false; 103 } 104 105 // If we couldn't do an optimized copy...we fall back to vanilla byte copy. 106 boolean copied = byteCopyDocument(src, dest); 107 108 return copied && !isCanceled() && deleteDocument(src); 109 } 110 111 @Override 112 public String toString() { 113 return new StringBuilder() 114 .append("MoveJob") 115 .append("{") 116 .append("id=" + id) 117 .append("srcs=" + mSrcs) 118 .append(", destination=" + stack) 119 .append("}") 120 .toString(); 121 } 122} 123