MoveJob.java revision a1f7680f535a30aa816d129c072870031c8a2eb6
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; 27 28import com.android.documentsui.R; 29import com.android.documentsui.model.DocumentInfo; 30import com.android.documentsui.model.DocumentStack; 31 32import java.util.List; 33 34// TODO: Stop extending CopyJob. 35final class MoveJob extends CopyJob { 36 37 final DocumentInfo mSrcParent; 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 * @param srcParent Parent of all source files. 48 */ 49 MoveJob(Context service, Context appContext, Listener listener, 50 String id, DocumentStack destination, List<DocumentInfo> srcs, DocumentInfo srcParent) { 51 super(service, appContext, listener, OPERATION_MOVE, id, destination, srcs); 52 this.mSrcParent = srcParent; 53 } 54 55 @Override 56 Builder createProgressBuilder() { 57 return super.createProgressBuilder( 58 service.getString(R.string.move_notification_title), 59 R.drawable.ic_menu_copy, 60 service.getString(android.R.string.cancel), 61 R.drawable.ic_cab_cancel); 62 } 63 64 @Override 65 public Notification getSetupNotification() { 66 return getSetupNotification(service.getString(R.string.move_preparing)); 67 } 68 69 @Override 70 public Notification getProgressNotification() { 71 return getProgressNotification(R.string.copy_preparing); 72 } 73 74 @Override 75 Notification getFailureNotification() { 76 return getFailureNotification( 77 R.plurals.move_error_notification_title, R.drawable.ic_menu_copy); 78 } 79 80 void processDocument(DocumentInfo src, DocumentInfo srcParent, DocumentInfo dest) 81 throws ResourceException { 82 83 // TODO: When optimized move kicks in, we're not making any progress updates. FIX IT! 84 85 // When moving within the same provider, try to use optimized moving. 86 // If not supported, then fallback to byte-by-byte copy/move. 87 if (src.authority.equals(dest.authority)) { 88 if ((src.flags & Document.FLAG_SUPPORTS_MOVE) != 0) { 89 try { 90 if (DocumentsContract.moveDocument(getClient(src), src.derivedUri, 91 srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri, 92 dest.derivedUri) == null) { 93 throw new ResourceException("Provider side move failed for document %s.", 94 src.derivedUri); 95 } 96 } catch (RuntimeException | RemoteException e) { 97 throw new ResourceException( 98 "Provider side move failed for document %s due to an exception.", 99 src.derivedUri, e); 100 } 101 return; 102 } 103 } 104 105 // Moving virtual files by bytes is not supported. This is because, it would involve 106 // conversion, and the source file should not be deleted in such case (as it's a different 107 // file). 108 if (src.isVirtualDocument()) { 109 throw new ResourceException("Cannot move virtual file %s byte by byte.", 110 src.derivedUri); 111 } 112 113 // If we couldn't do an optimized copy...we fall back to vanilla byte copy. 114 byteCopyDocument(src, dest); 115 116 // Remove the source document. 117 deleteDocument(src, srcParent); 118 } 119 120 @Override 121 public String toString() { 122 return new StringBuilder() 123 .append("MoveJob") 124 .append("{") 125 .append("id=" + id) 126 .append(", srcs=" + mSrcs) 127 .append(", srcParent=" + mSrcParent) 128 .append(", destination=" + stack) 129 .append("}") 130 .toString(); 131 } 132} 133