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

Commit 1360868d authored by Daichi Hirono's avatar Daichi Hirono Committed by Android (Google) Code Review
Browse files

Merge "Add suffix number when copying a file." into nyc-dev

parents ffaf9445 fc7fb753
Loading
Loading
Loading
Loading
+27 −10
Original line number Diff line number Diff line
@@ -605,6 +605,30 @@ public class FileUtils {
     */
    public static File buildUniqueFile(File parent, String mimeType, String displayName)
            throws FileNotFoundException {
        final String[] parts = splitFileName(mimeType, displayName);
        final String name = parts[0];
        final String ext = parts[1];
        File file = buildFile(parent, name, ext);

        // If conflicting file, try adding counter suffix
        int n = 0;
        while (file.exists()) {
            if (n++ >= 32) {
                throw new FileNotFoundException("Failed to create unique file");
            }
            file = buildFile(parent, name + " (" + n + ")", ext);
        }

        return file;
    }

    /**
     * Splits file name into base name and extension.
     * If the display name doesn't have an extension that matches the requested MIME type, the
     * extension is regarded as a part of filename and default extension for that MIME type is
     * appended.
     */
    public static String[] splitFileName(String mimeType, String displayName) {
        String name;
        String ext;

@@ -642,18 +666,11 @@ public class FileUtils {
            }
        }

        File file = buildFile(parent, name, ext);

        // If conflicting file, try adding counter suffix
        int n = 0;
        while (file.exists()) {
            if (n++ >= 32) {
                throw new FileNotFoundException("Failed to create unique file");
            }
            file = buildFile(parent, name + " (" + n + ")", ext);
        if (ext == null) {
            ext = "";
        }

        return file;
        return new String[] { name, ext };
    }

    private static File buildFile(File parent, String name, String ext) {
+5 −2
Original line number Diff line number Diff line
@@ -14,12 +14,15 @@
 * limitations under the License.
 */

package com.android.mtp.exceptions;
package com.android.mtp;

import java.io.IOException;

/**
 * Exception thrown when the device is busy and the requested operation cannon be completed.
 */
public class BusyDeviceException extends IOException {
class BusyDeviceException extends IOException {
    BusyDeviceException() {
        super("The MTP device is busy.");
    }
}
+57 −17
Original line number Diff line number Diff line
@@ -30,6 +30,8 @@ import android.mtp.MtpObjectInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.FileUriExposedException;
import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
import android.os.storage.StorageManager;
import android.provider.DocumentsContract.Document;
@@ -41,7 +43,6 @@ import android.util.Log;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.mtp.exceptions.BusyDeviceException;

import java.io.FileNotFoundException;
import java.io.IOException;
@@ -324,25 +325,61 @@ public class MtpDocumentsProvider extends DocumentsProvider {
        if (DEBUG) {
            Log.d(TAG, "createDocument: " + displayName);
        }
        final Identifier parentId;
        final MtpDeviceRecord record;
        final ParcelFileDescriptor[] pipe;
        try {
            final Identifier parentId = mDatabase.createIdentifier(parentDocumentId);
            parentId = mDatabase.createIdentifier(parentDocumentId);
            openDevice(parentId.mDeviceId);
            final MtpDeviceRecord record = getDeviceToolkit(parentId.mDeviceId).mDeviceRecord;
            record = getDeviceToolkit(parentId.mDeviceId).mDeviceRecord;
            if (!MtpDeviceRecord.isWritingSupported(record.operationsSupported)) {
                throw new UnsupportedOperationException();
                throw new UnsupportedOperationException(
                        "Writing operation is not supported by the device.");
            }
            final ParcelFileDescriptor pipe[] = ParcelFileDescriptor.createReliablePipe();
            pipe = ParcelFileDescriptor.createReliablePipe();
            int objectHandle = -1;
            MtpObjectInfo info = null;
            try {
                pipe[0].close();  // 0 bytes for a new document.

                final int formatCode = Document.MIME_TYPE_DIR.equals(mimeType) ?
                        MtpConstants.FORMAT_ASSOCIATION :
                        MediaFile.getFormatCode(displayName, mimeType);
            final MtpObjectInfo info = new MtpObjectInfo.Builder()
                info = new MtpObjectInfo.Builder()
                        .setStorageId(parentId.mStorageId)
                        .setParent(parentId.mObjectHandle)
                        .setFormat(formatCode)
                        .setName(displayName)
                        .build();
            final int objectHandle = mMtpManager.createDocument(parentId.mDeviceId, info, pipe[1]);

                final String[] parts = FileUtils.splitFileName(mimeType, displayName);
                final String baseName = parts[0];
                final String extension = parts[1];
                for (int i = 0; i <= 32; i++) {
                    final MtpObjectInfo infoUniqueName;
                    if (i == 0) {
                        infoUniqueName = info;
                    } else {
                        infoUniqueName = new MtpObjectInfo.Builder(info).setName(
                                baseName + " (" + i + ")." + extension).build();
                    }
                    try {
                        objectHandle = mMtpManager.createDocument(
                                parentId.mDeviceId, infoUniqueName, pipe[1]);
                        break;
                    } catch (SendObjectInfoFailure exp) {
                        // This can be caused when we have an existing file with the same name.
                        continue;
                    }
                }
            } finally {
                pipe[1].close();
            }
            if (objectHandle == -1) {
                throw new IllegalArgumentException(
                        "The file name \"" + displayName + "\" is conflicted with existing files " +
                        "and the provider failed to find unique name.");
            }
            final MtpObjectInfo infoWithHandle =
                    new MtpObjectInfo.Builder(info).setObjectHandle(objectHandle).build();
            final String documentId = mDatabase.putNewDocument(
@@ -351,9 +388,12 @@ public class MtpDocumentsProvider extends DocumentsProvider {
            getDocumentLoader(parentId).clearTask(parentId);
            notifyChildDocumentsChange(parentDocumentId);
            return documentId;
        } catch (FileNotFoundException | RuntimeException error) {
            Log.e(TAG, "createDocument", error);
            throw error;
        } catch (IOException error) {
            Log.e(TAG, "createDocument", error);
            throw new FileNotFoundException(error.getMessage());
            throw new IllegalStateException(error);
        }
    }

+1 −2
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.util.Log;
import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.mtp.exceptions.BusyDeviceException;

import java.io.FileNotFoundException;
import java.io.IOException;
@@ -190,7 +189,7 @@ class MtpManager {
        synchronized (device) {
            final MtpObjectInfo sendObjectInfoResult = device.sendObjectInfo(objectInfo);
            if (sendObjectInfoResult == null) {
                throw new IOException("Failed to create a document");
                throw new SendObjectInfoFailure();
            }
            if (objectInfo.getFormat() != MtpConstants.FORMAT_ASSOCIATION) {
                if (!device.sendObject(sendObjectInfoResult.getObjectHandle(),
+28 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.mtp;

import java.io.IOException;

/**
 * Exception thrown when sendObjectInfo failed.
 */
class SendObjectInfoFailure extends IOException {
    SendObjectInfoFailure() {
        super("Failed to MtpDevice#sendObjectInfo.");
    }
}
Loading