Merge "Fallback to byte-by-byte copy/move if optimized fails." into nyc-dev

This commit is contained in:
Steve McKay
2016-03-10 23:18:49 +00:00
committed by Android (Google) Code Review
6 changed files with 63 additions and 25 deletions

View File

@@ -299,18 +299,15 @@ class CopyJob extends Job {
if ((src.flags & Document.FLAG_SUPPORTS_COPY) != 0) {
try {
if (DocumentsContract.copyDocument(getClient(src), src.derivedUri,
dstDirInfo.derivedUri) == null) {
throw new ResourceException("Provider side copy failed for document %s.",
src.derivedUri);
dstDirInfo.derivedUri) != null) {
return;
}
} catch (ResourceException e) {
throw e;
} catch (RemoteException | RuntimeException e) {
throw new ResourceException(
"Provider side copy failed for document %s due to an exception.",
src.derivedUri, e);
Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
+ " due to an exception: " + e);
}
return;
// If optimized copy fails, then fallback to byte-by-byte copy.
if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte copy for: " + src.derivedUri);
}
}

View File

@@ -16,6 +16,7 @@
package com.android.documentsui.services;
import static com.android.documentsui.Shared.DEBUG;
import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE;
import android.app.Notification;
@@ -24,6 +25,7 @@ import android.content.Context;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.util.Log;
import com.android.documentsui.R;
import com.android.documentsui.model.DocumentInfo;
@@ -34,6 +36,8 @@ import java.util.List;
// TODO: Stop extending CopyJob.
final class MoveJob extends CopyJob {
private static final String TAG = "MoveJob";
final DocumentInfo mSrcParent;
/**
@@ -89,16 +93,15 @@ final class MoveJob extends CopyJob {
try {
if (DocumentsContract.moveDocument(getClient(src), src.derivedUri,
srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri,
dest.derivedUri) == null) {
throw new ResourceException("Provider side move failed for document %s.",
src.derivedUri);
dest.derivedUri) != null) {
return;
}
} catch (RuntimeException | RemoteException e) {
throw new ResourceException(
"Provider side move failed for document %s due to an exception.",
src.derivedUri, e);
} catch (RemoteException | RuntimeException e) {
Log.e(TAG, "Provider side move failed for: " + src.derivedUri
+ " due to an exception: " + e);
}
return;
// If optimized move fails, then fallback to byte-by-byte copy.
if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte move for: " + src.derivedUri);
}
}

View File

@@ -106,13 +106,15 @@ public class DocumentsProviderHelper {
return createDocument(root.documentId, mimeType, name);
}
public Uri createDocumentWithFlags(String documentId, String mimeType, String name, int flags)
public Uri createDocumentWithFlags(String documentId, String mimeType, String name, int flags,
String... streamTypes)
throws RemoteException {
Bundle in = new Bundle();
in.putInt(StubProvider.EXTRA_FLAGS, flags);
in.putString(StubProvider.EXTRA_PARENT_ID, documentId);
in.putString(Document.COLUMN_MIME_TYPE, mimeType);
in.putString(Document.COLUMN_DISPLAY_NAME, name);
in.putStringArrayList(StubProvider.EXTRA_STREAM_TYPES, Lists.newArrayList(streamTypes));
Bundle out = mClient.call("createDocumentWithFlags", null, in);
Uri uri = out.getParcelable(DocumentsContract.EXTRA_URI);

View File

@@ -518,28 +518,29 @@ public class StubProvider extends DocumentsProvider {
String rootId = extras.getString(EXTRA_PARENT_ID);
String mimeType = extras.getString(Document.COLUMN_MIME_TYPE);
String name = extras.getString(Document.COLUMN_DISPLAY_NAME);
List<String> streamTypes = extras.getStringArrayList(EXTRA_STREAM_TYPES);
int flags = extras.getInt(EXTRA_FLAGS);
Bundle out = new Bundle();
String documentId = null;
try {
documentId = createDocument(rootId, mimeType, name, flags);
documentId = createDocument(rootId, mimeType, name, flags, streamTypes);
Uri uri = DocumentsContract.buildDocumentUri(mAuthority, documentId);
out.putParcelable(DocumentsContract.EXTRA_URI, uri);
} catch (FileNotFoundException e) {
Log.d(TAG, "Cretaing document with flags failed" + name);
Log.d(TAG, "Creating document with flags failed" + name);
}
return out;
}
public String createDocument(String parentId, String mimeType, String displayName, int flags)
throws FileNotFoundException {
public String createDocument(String parentId, String mimeType, String displayName, int flags,
List<String> streamTypes) throws FileNotFoundException {
StubDocument parent = mStorage.get(parentId);
File file = createFile(parent, mimeType, displayName);
final StubDocument document = StubDocument.createDocumentWithFlags(file, mimeType, parent,
flags);
flags, streamTypes);
mStorage.put(document.documentId, document);
Log.d(TAG, "Created document " + document.documentId);
notifyParentChanged(document.parentId);
@@ -787,8 +788,9 @@ public class StubProvider extends DocumentsProvider {
}
public static StubDocument createDocumentWithFlags(
File file, String mimeType, StubDocument parent, int flags) {
return new StubDocument(file, mimeType, new ArrayList<String>(), flags, parent);
File file, String mimeType, StubDocument parent, int flags,
List<String> streamTypes) {
return new StubDocument(file, mimeType, streamTypes, flags, parent);
}
public static StubDocument createVirtualDocument(

View File

@@ -16,6 +16,10 @@
package com.android.documentsui.services;
import static com.google.common.collect.Lists.newArrayList;
import android.net.Uri;
import android.provider.DocumentsContract.Document;
import android.test.suitebuilder.annotation.MediumTest;
import com.android.documentsui.model.DocumentInfo;
@@ -38,6 +42,21 @@ public class CopyJobTest extends AbstractCopyJobTest<CopyJob> {
runCopyVirtualNonTypedFileTest();
}
public void testCopy_BackendSideVirtualTypedFile_Fallback() throws Exception {
mDocs.assertChildCount(mDestRoot, 0);
Uri testFile = mDocs.createDocumentWithFlags(
mSrcRoot.documentId, "virtual/mime-type", "tokyo.sth",
Document.FLAG_VIRTUAL_DOCUMENT | Document.FLAG_SUPPORTS_COPY
| Document.FLAG_SUPPORTS_MOVE, "application/pdf");
createJob(newArrayList(testFile)).run();
mJobListener.waitForFinished();
mDocs.assertChildCount(mDestRoot, 1);
mDocs.assertHasFile(mDestRoot, "tokyo.sth.pdf"); // Copy should convert file to PDF.
}
public void testCopyEmptyDir() throws Exception {
runCopyEmptyDirTest();
}

View File

@@ -59,6 +59,21 @@ public class MoveJobTest extends AbstractCopyJobTest<MoveJob> {
mDocs.assertChildCount(mSrcRoot, 1);
}
public void testMove_BackendSideVirtualTypedFile_Fallback() throws Exception {
Uri testFile = mDocs.createDocumentWithFlags(
mSrcRoot.documentId, "virtual/mime-type", "tokyo.sth",
Document.FLAG_VIRTUAL_DOCUMENT | Document.FLAG_SUPPORTS_COPY
| Document.FLAG_SUPPORTS_MOVE, "application/pdf");
createJob(newArrayList(testFile)).run();
mJobListener.waitForFinished();
// Should have failed, source not deleted. Moving by bytes for virtual files
// is not supported.
mDocs.assertChildCount(mDestRoot, 0);
mDocs.assertChildCount(mSrcRoot, 1);
}
public void testMoveEmptyDir() throws Exception {
runCopyEmptyDirTest();