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

Commit 931f3aaa authored by Diksha Gohlyan's avatar Diksha Gohlyan
Browse files

File copy, move, if timeout, re acquire contentprovider

Test: atest DocumentsUIGoogleTests
Bug: 152820926

Change-Id: Iff9b83309f43d2dd522ab0c6e6202ba7e1e42004
parent d2db36ca
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import android.content.res.AssetFileDescriptor;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.DeadObjectException;
import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
@@ -359,6 +360,9 @@ class CopyJob extends ResolvedResourcesJob {
                        return;
                    }
                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                    if (e instanceof DeadObjectException) {
                        releaseClient(src);
                    }
                    Log.e(TAG, "Provider side copy failed for: " + src.derivedUri
                            + " due to an exception.", e);
                    Metrics.logFileOperationFailure(
@@ -427,6 +431,9 @@ class CopyJob extends ResolvedResourcesJob {
            dstUri = DocumentsContract.createDocument(
                    wrap(getClient(dest)), dest.derivedUri, dstMimeType, dstDisplayName);
        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
            if (e instanceof DeadObjectException) {
                releaseClient(dest);
            }
            Metrics.logFileOperationFailure(
                    appContext, MetricConsts.SUBFILEOP_CREATE_DOCUMENT, dest.derivedUri);
            throw new ResourceException(
@@ -486,6 +493,9 @@ class CopyJob extends ResolvedResourcesJob {
            try {
                cursor = queryChildren(srcDir, queryColumns);
            } catch (RemoteException | RuntimeException e) {
                if (e instanceof DeadObjectException) {
                    releaseClient(srcDir);
                }
                Metrics.logFileOperationFailure(
                        appContext, MetricConsts.SUBFILEOP_QUERY_CHILDREN, srcDir.derivedUri);
                throw new ResourceException("Failed to query children of %s due to an exception.",
@@ -545,6 +555,9 @@ class CopyJob extends ResolvedResourcesJob {
                    srcFileAsAsset = getClient(src).openTypedAssetFileDescriptor(
                                src.derivedUri, mimeType, null, mSignal);
                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                    if (e instanceof DeadObjectException) {
                        releaseClient(src);
                    }
                    Metrics.logFileOperationFailure(
                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                    throw new ResourceException("Failed to open a file as asset for %s due to an "
@@ -565,6 +578,9 @@ class CopyJob extends ResolvedResourcesJob {
                try {
                    srcFile = getClient(src).openFile(src.derivedUri, "r", mSignal);
                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                    if (e instanceof DeadObjectException) {
                        releaseClient(src);
                    }
                    Metrics.logFileOperationFailure(
                            appContext, MetricConsts.SUBFILEOP_OPEN_FILE, src.derivedUri);
                    throw new ResourceException(
@@ -578,6 +594,9 @@ class CopyJob extends ResolvedResourcesJob {
            try {
                dstFile = getClient(dest).openFile(dest.derivedUri, "w", mSignal);
            } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                if (e instanceof DeadObjectException) {
                    releaseClient(dest);
                }
                Metrics.logFileOperationFailure(
                        appContext, MetricConsts.SUBFILEOP_OPEN_FILE, dest.derivedUri);
                throw new ResourceException("Failed to open the destination file %s for writing "
@@ -744,6 +763,9 @@ class CopyJob extends ResolvedResourcesJob {
                }
            }
        } catch (RemoteException | RuntimeException e) {
            if (e instanceof DeadObjectException) {
                releaseClient(uri);
            }
            throw new ResourceException(
                    "Failed to calculate size for %s due to an exception.", uri, e);
        } finally {
@@ -824,6 +846,9 @@ class CopyJob extends ResolvedResourcesJob {
            try {
                return isChildDocument(wrap(getClient(doc)), doc.derivedUri, parent.derivedUri);
            } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                if (e instanceof DeadObjectException) {
                    releaseClient(doc);
                }
                throw new ResourceException(
                        "Failed to check if %s is a child of %s due to an exception.",
                        doc.derivedUri, parent.derivedUri, e);
@@ -887,6 +912,9 @@ class CopyJob extends ResolvedResourcesJob {
                }
            }
        } catch (Throwable t) {
            if (t instanceof DeadObjectException) {
                releaseClient(target);
            }
            Log.w(TAG, String.format("Failed to determine if isRecursiveCopy" +
                " for source %s and target %s", sourceUri, targetUri), t);
        }
+20 −3
Original line number Diff line number Diff line
@@ -27,9 +27,6 @@ import static com.android.documentsui.services.FileOperationService.EXTRA_JOB_ID
import static com.android.documentsui.services.FileOperationService.EXTRA_OPERATION_TYPE;
import static com.android.documentsui.services.FileOperationService.OPERATION_UNKNOWN;

import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.PluralsRes;
import android.app.Notification;
import android.app.Notification.Builder;
import android.app.PendingIntent;
@@ -39,12 +36,17 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.CancellationSignal;
import android.os.DeadObjectException;
import android.os.FileUtils;
import android.os.Parcelable;
import android.os.RemoteException;
import android.provider.DocumentsContract;
import android.util.Log;

import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.PluralsRes;

import com.android.documentsui.Metrics;
import com.android.documentsui.OperationDialogFragment;
import com.android.documentsui.R;
@@ -211,6 +213,18 @@ abstract public class Job implements Runnable {
        return getClient(doc.derivedUri);
    }

    void releaseClient(Uri uri) {
        ContentProviderClient client = mClients.get(uri.getAuthority());
        if (client != null) {
            client.close();
            mClients.remove(uri.getAuthority());
        }
    }

    void releaseClient(DocumentInfo doc) {
        releaseClient(doc.derivedUri);
    }

    final void cleanup() {
        for (ContentProviderClient client : mClients.values()) {
            FileUtils.closeQuietly(client);
@@ -270,6 +284,9 @@ abstract public class Job implements Runnable {
                        + "File is not deletable or removable: %s.", doc.derivedUri);
            }
        } catch (FileNotFoundException | RemoteException | RuntimeException e) {
            if (e instanceof DeadObjectException) {
                releaseClient(doc);
            }
            throw new ResourceException("Failed to delete file %s due to an exception.",
                    doc.derivedUri, e);
        }
+4 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.app.Notification;
import android.app.Notification.Builder;
import android.content.Context;
import android.net.Uri;
import android.os.DeadObjectException;
import android.os.Messenger;
import android.os.RemoteException;
import android.provider.DocumentsContract;
@@ -154,6 +155,9 @@ final class MoveJob extends CopyJob {
                        return;
                    }
                } catch (FileNotFoundException | RemoteException | RuntimeException e) {
                    if (e instanceof DeadObjectException) {
                        releaseClient(src);
                    }
                    Metrics.logFileOperationFailure(
                            appContext, MetricConsts.SUBFILEOP_QUICK_MOVE, src.derivedUri);
                    Log.e(TAG, "Provider side move failed for: " + src.derivedUri