Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43fe1b34 authored by Tomasz Mikolajewski's avatar Tomasz Mikolajewski Committed by Android (Google) Code Review
Browse files

Merge "Implement retrying copying in case of an error in DocumentsUI."

parents 7fadb2f5 f8c3f322
Loading
Loading
Loading
Loading
+32 −4
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.app.PendingIntent;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.CancellationSignal;
@@ -37,12 +38,14 @@ import android.provider.DocumentsContract;
import android.provider.DocumentsContract.Document;
import android.text.format.DateUtils;
import android.util.Log;
import android.widget.Toast;

import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;

import libcore.io.IoUtils;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -70,7 +73,7 @@ public class CopyService extends IntentService {
    private volatile boolean mIsCancelled;
    // Parameters of the copy job. Requests to an IntentService are serialized so this code only
    // needs to deal with one job at a time.
    private final ArrayList<Uri> mFailedFiles;
    private final ArrayList<DocumentInfo> mFailedFiles;
    private long mBatchSize;
    private long mBytesCopied;
    private long mStartTime;
@@ -88,7 +91,27 @@ public class CopyService extends IntentService {
    public CopyService() {
        super("CopyService");

        mFailedFiles = new ArrayList<Uri>();
        mFailedFiles = new ArrayList<DocumentInfo>();
    }

    /**
     * Starts the service for a copy operation.
     *
     * @param context Context for the intent.
     * @param srcDocs A list of src files to copy.
     * @param dstStack The copy destination stack.
     */
    public static void start(Context context, List<DocumentInfo> srcDocs, DocumentStack dstStack) {
        final Resources res = context.getResources();
        final Intent copyIntent = new Intent(context, CopyService.class);
        copyIntent.putParcelableArrayListExtra(
                EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(srcDocs));
        copyIntent.putExtra(EXTRA_STACK, (Parcelable) dstStack);

        Toast.makeText(context,
                res.getQuantityString(R.plurals.copy_begin, srcDocs.size(), srcDocs.size()),
                Toast.LENGTH_SHORT).show();
        context.startService(copyIntent);
    }

    @Override
@@ -360,7 +383,7 @@ public class CopyService extends IntentService {
        if (dstUri == null) {
            // If this is a directory, the entire subdir will not be copied over.
            Log.e(TAG, "Error while copying " + srcInfo.displayName);
            mFailedFiles.add(srcInfo.derivedUri);
            mFailedFiles.add(srcInfo);
            return;
        }

@@ -444,7 +467,12 @@ public class CopyService extends IntentService {
        } catch (IOException e) {
            errorOccurred = true;
            Log.e(TAG, "Error while copying " + srcUri.toString(), e);
            mFailedFiles.add(srcUri);
            try {
                mFailedFiles.add(DocumentInfo.fromUri(getContentResolver(), srcUri));
            } catch (FileNotFoundException ignore) {
                Log.w(TAG, "Source file gone: " + srcUri, e);
              // The source file is gone.
            }
        } finally {
            // This also ensures the file descriptors are closed.
            IoUtils.closeQuietly(src);
+3 −12
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ import com.android.documentsui.BaseActivity.State;
import com.android.documentsui.ProviderExecutor.Preemptable;
import com.android.documentsui.RecentsProvider.StateColumns;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;
import com.android.documentsui.model.RootInfo;
import com.google.android.collect.Lists;

@@ -341,9 +342,6 @@ public class DirectoryFragment extends Fragment {

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        final Context context = getActivity();
        final Resources res = context.getResources();

        // There's only one request code right now. Replace this with a switch statement or
        // something more scalable when more codes are added.
        if (requestCode != REQUEST_COPY_DESTINATION) {
@@ -355,15 +353,8 @@ public class DirectoryFragment extends Fragment {
            return;
        }

        final List<DocumentInfo> docs = getDisplayState(this).selectedDocumentsForCopy;
        final Intent copyIntent = new Intent(context, CopyService.class);
        copyIntent.putParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST, new ArrayList<DocumentInfo>(docs));
        copyIntent.putExtra(CopyService.EXTRA_STACK, data.getParcelableExtra(CopyService.EXTRA_STACK));

        Toast.makeText(context,
                res.getQuantityString(R.plurals.copy_begin, docs.size(), docs.size()),
                Toast.LENGTH_SHORT).show();
        context.startService(copyIntent);
        CopyService.start(getActivity(), getDisplayState(this).selectedDocumentsForCopy,
                (DocumentStack) data.getParcelableExtra(CopyService.EXTRA_STACK));
    }

    @Override
+13 −13
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.DialogInterface;
@@ -27,7 +28,9 @@ import android.net.Uri;
import android.os.Bundle;
import android.text.Html;

import com.android.documentsui.CopyService;
import com.android.documentsui.model.DocumentInfo;
import com.android.documentsui.model.DocumentStack;

import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -40,9 +43,10 @@ public class FailureDialogFragment extends DialogFragment
    private static final String TAG = "FailureDialogFragment";

    private int mFailure;
    private ArrayList<Uri> mFailedSrcList;
    private ArrayList<DocumentInfo> mFailedSrcList;

    public static void show(FragmentManager fm, int failure, ArrayList<Uri> failedSrcList) {
    public static void show(FragmentManager fm, int failure,
            ArrayList<DocumentInfo> failedSrcList, DocumentStack dstStack) {
        // TODO: Add support for other failures than copy.
        if (failure != CopyService.FAILURE_COPY) {
            return;
@@ -62,7 +66,11 @@ public class FailureDialogFragment extends DialogFragment

    @Override
    public void onClick(DialogInterface dialog, int whichButton) {
      // TODO: Pass mFailure and mFailedSrcList to the parent fragment.
      if (whichButton == DialogInterface.BUTTON_POSITIVE) {
          CopyService.start(getActivity(), mFailedSrcList,
                  (DocumentStack) getActivity().getIntent().getParcelableExtra(
                          CopyService.EXTRA_STACK));
      }
    }

    @Override
@@ -73,16 +81,9 @@ public class FailureDialogFragment extends DialogFragment
        mFailedSrcList = getArguments().getParcelableArrayList(CopyService.EXTRA_SRC_LIST);

        final StringBuilder list = new StringBuilder("<p>");
        for (Uri documentUri : mFailedSrcList) {
            try {
                final DocumentInfo documentInfo = DocumentInfo.fromUri(
                    getActivity().getContentResolver(), documentUri);
        for (DocumentInfo documentInfo : mFailedSrcList) {
            list.append(String.format("&#8226; %s<br>", documentInfo.displayName));
        }
            catch (FileNotFoundException ignore) {
                // Source file most probably gone.
            }
        }
        list.append("</p>");
        final String message = String.format(getString(R.string.copy_failure_alert_content),
                list.toString());
@@ -90,7 +91,6 @@ public class FailureDialogFragment extends DialogFragment
        return new AlertDialog.Builder(getActivity())
            .setTitle(getString(R.string.copy_failure_alert_title))
            .setMessage(Html.fromHtml(message))
            // TODO: Implement retrying the copy operation.
            .setPositiveButton(R.string.retry, this)
            .setNegativeButton(android.R.string.cancel, this)
            .setIcon(android.R.drawable.ic_dialog_alert)
+6 −3
Original line number Diff line number Diff line
@@ -106,12 +106,15 @@ public class StandaloneActivity extends BaseActivity {
        RootsFragment.show(getFragmentManager(), null);
        if (!mState.restored) {
            new RestoreStackTask().execute();

            // Show a failure dialog if there was a failed operation.
            final Intent intent = getIntent();
            final DocumentStack dstStack = intent.getParcelableExtra(CopyService.EXTRA_STACK);
            final int failure = intent.getIntExtra(CopyService.EXTRA_FAILURE, 0);
            if (failure != 0) {
                final ArrayList<Uri> failedSrcList = intent.getParcelableArrayListExtra(
                        CopyService.EXTRA_SRC_LIST);
                FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList);
                final ArrayList<DocumentInfo> failedSrcList =
                        intent.getParcelableArrayListExtra(CopyService.EXTRA_SRC_LIST);
                FailureDialogFragment.show(getFragmentManager(), failure, failedSrcList, dstStack);
            }
        } else {
            onCurrentDirectoryChanged(ANIM_NONE);