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

Commit e46f1dce authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Change the created archive name in CompressJob" into main

parents 3e273cda 7ce738da
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -618,6 +618,11 @@
    <!-- File name of an archive file created when compressing files, without the file extension (.zip). -->
    <string name="new_archive_file_name">archive<xliff:g id="extension" example=".zip">%s</xliff:g></string>

    <!-- This string is used by the File Manager as the file name for the created ZIP archive when
    two or more item are zipped (i.e. bundled and compressed) together. In this context, the word
    "Archive" is a noun as in "An archive", and not a verb. [CHAR_LIMIT=28] -->
    <string name="new_archive_file_name_2">Archive</string>

    <!-- Dialog text shown when confirming if they want to overwrite a file -->
    <string name="overwrite_file_confirmation_message">Overwrite <xliff:g id="name" example="foobar.txt">%1$s</xliff:g>?</string>

+36 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.documentsui.services;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import static com.android.documentsui.base.SharedMinimal.redact;
import static com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS;
import static com.android.documentsui.util.FlagUtils.isZipNgFlagEnabled;
import static com.android.documentsui.util.Material3Config.getRes;

import android.app.Notification;
@@ -32,6 +33,7 @@ import android.os.ParcelFileDescriptor;
import android.provider.DocumentsContract;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.documentsui.R;
@@ -51,7 +53,7 @@ import java.io.IOException;
final class CompressJob extends CopyJob {

    private static final String TAG = "CompressJob";
    private static final String NEW_ARCHIVE_EXTENSION = ".zip";
    private static final String ZIP_EXTENSION = ".zip";

    private @Nullable Uri mArchiveUri;
    private @Nullable ContentProviderClient mClient;
@@ -102,13 +104,12 @@ final class CompressJob extends CopyJob {
            return false;
        }

        String displayName;
        final String displayName;
        if (mResolvedDocs.size() == 1) {
            displayName = mResolvedDocs.get(0).displayName + NEW_ARCHIVE_EXTENSION;
            final DocumentInfo doc = mResolvedDocs.get(0);
            displayName = getArchiveName(doc.displayName, doc.isDirectory());
        } else {
            displayName =
                    service.getString(
                            getRes(R.string.new_archive_file_name), NEW_ARCHIVE_EXTENSION);
            displayName = getGenericArchiveName();
        }

        try {
@@ -133,6 +134,35 @@ final class CompressJob extends CopyJob {
        }
    }

    /** Generates a suitable archive name when zipping several items together. */
    public @NonNull String getGenericArchiveName() {
        if (isZipNgFlagEnabled()) {
            return service.getString(getRes(R.string.new_archive_file_name_2)) + ZIP_EXTENSION;
        } else {
            return service.getString(getRes(R.string.new_archive_file_name), ZIP_EXTENSION);
        }
    }

    /** Generates a suitable archive name when zipping a single item with the given name. */
    public static @NonNull String getArchiveName(@NonNull String name, boolean isDir) {
        if (!isDir && isZipNgFlagEnabled()) {
            // Find the last dot in `name`.
            final int i = name.lastIndexOf('.');
            if (i > 0) {
                // There is a last dot, and it is not the first character of `name`.
                // Compute the candidate extension length (excluding its leading dot).
                final int n = name.length() - i - 1;
                // Consider an extension as valid if it is between 1 and 10 characters long.
                if (1 <= n && n <= 10) {
                    // Found a valid filename extension. Drop this extension.
                    name = name.substring(0, i);
                }
            }
        }

        return name + ZIP_EXTENSION;
    }

    @Override
    void finish() {
        if (mClient != null) {
+120 −2
Original line number Diff line number Diff line
@@ -16,13 +16,19 @@
package com.android.documentsui.services

import android.net.Uri
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.provider.DocumentsContract.Document.MIME_TYPE_DIR
import android.provider.DocumentsContract.buildDocumentUri
import android.util.Log
import androidx.test.filters.MediumTest
import com.android.documentsui.base.DocumentInfo
import com.android.documentsui.flags.Flags.FLAG_USE_MATERIAL3
import com.android.documentsui.flags.Flags.FLAG_ZIP_NG_RO
import com.android.documentsui.rules.OverrideFlagsRule
import com.android.documentsui.services.CompressJob.getArchiveName
import com.android.documentsui.services.FileOperationService.OPERATION_COMPRESS
import com.android.documentsui.util.FlagUtils.Companion.isZipNgFlagEnabled
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
@@ -35,6 +41,76 @@ internal class CompressJobTest : AbstractJobTest<CompressJob>() {

    private data class Entry(val size: Long, val mimeType: String)

    /* Tests CompressJob.getArchiveName(). */
    @Test
    @EnableFlags(FLAG_USE_MATERIAL3, FLAG_ZIP_NG_RO)
    fun archiveName() {
        assertThat(getArchiveName("Test", false)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.", false)).isEqualTo("Test..zip")
        assertThat(getArchiveName("Test.a", false)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.a.b.c", false)).isEqualTo("Test.a.b.zip")
        assertThat(getArchiveName("Test.txt", false)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.TooLongToBeAnExtension", false))
            .isEqualTo("Test.TooLongToBeAnExtension.zip")
        assertThat(getArchiveName("Test....txt", false)).isEqualTo("Test....zip")
        assertThat(getArchiveName("Test...", false)).isEqualTo("Test....zip")
        assertThat(getArchiveName(".Test", false)).isEqualTo(".Test.zip")
        assertThat(getArchiveName(".Test.", false)).isEqualTo(".Test..zip")
        assertThat(getArchiveName(".Test.txt", false)).isEqualTo(".Test.zip")
        assertThat(getArchiveName("...", false)).isEqualTo("....zip")
        assertThat(getArchiveName("...Test", false)).isEqualTo("...zip")

        assertThat(getArchiveName("Test", true)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.", true)).isEqualTo("Test..zip")
        assertThat(getArchiveName("Test.a", true)).isEqualTo("Test.a.zip")
        assertThat(getArchiveName("Test.a.b.c", true)).isEqualTo("Test.a.b.c.zip")
        assertThat(getArchiveName("Test.txt", true)).isEqualTo("Test.txt.zip")
        assertThat(getArchiveName("Test.ToLongToBeAnExtension", true))
            .isEqualTo("Test.ToLongToBeAnExtension.zip")
        assertThat(getArchiveName("Test....txt", true)).isEqualTo("Test....txt.zip")
        assertThat(getArchiveName("Test...", true)).isEqualTo("Test....zip")
        assertThat(getArchiveName(".Test", true)).isEqualTo(".Test.zip")
        assertThat(getArchiveName(".Test.", true)).isEqualTo(".Test..zip")
        assertThat(getArchiveName(".Test.txt", true)).isEqualTo(".Test.txt.zip")
        assertThat(getArchiveName("...", true)).isEqualTo("....zip")
        assertThat(getArchiveName("...Test", true)).isEqualTo("...Test.zip")
    }

    /* Tests CompressJob.getArchiveName(). */
    @Test
    @DisableFlags(FLAG_ZIP_NG_RO)
    fun archiveNameOld() {
        assertThat(getArchiveName("Test", false)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.", false)).isEqualTo("Test..zip")
        assertThat(getArchiveName("Test.a", false)).isEqualTo("Test.a.zip")
        assertThat(getArchiveName("Test.a.b.c", false)).isEqualTo("Test.a.b.c.zip")
        assertThat(getArchiveName("Test.txt", false)).isEqualTo("Test.txt.zip")
        assertThat(getArchiveName("Test.ToLongToBeAnExtension", false))
            .isEqualTo("Test.ToLongToBeAnExtension.zip")
        assertThat(getArchiveName("Test....txt", false)).isEqualTo("Test....txt.zip")
        assertThat(getArchiveName("Test...", false)).isEqualTo("Test....zip")
        assertThat(getArchiveName(".Test", false)).isEqualTo(".Test.zip")
        assertThat(getArchiveName(".Test.", false)).isEqualTo(".Test..zip")
        assertThat(getArchiveName(".Test.txt", false)).isEqualTo(".Test.txt.zip")
        assertThat(getArchiveName("...", false)).isEqualTo("....zip")
        assertThat(getArchiveName("...Test", false)).isEqualTo("...Test.zip")

        assertThat(getArchiveName("Test", true)).isEqualTo("Test.zip")
        assertThat(getArchiveName("Test.", true)).isEqualTo("Test..zip")
        assertThat(getArchiveName("Test.a", true)).isEqualTo("Test.a.zip")
        assertThat(getArchiveName("Test.a.b.c", true)).isEqualTo("Test.a.b.c.zip")
        assertThat(getArchiveName("Test.txt", true)).isEqualTo("Test.txt.zip")
        assertThat(getArchiveName("Test.ToLongToBeAnExtension", true))
            .isEqualTo("Test.ToLongToBeAnExtension.zip")
        assertThat(getArchiveName("Test....txt", true)).isEqualTo("Test....txt.zip")
        assertThat(getArchiveName("Test...", true)).isEqualTo("Test....zip")
        assertThat(getArchiveName(".Test", true)).isEqualTo(".Test.zip")
        assertThat(getArchiveName(".Test.", true)).isEqualTo(".Test..zip")
        assertThat(getArchiveName(".Test.txt", true)).isEqualTo(".Test.txt.zip")
        assertThat(getArchiveName("...", true)).isEqualTo("....zip")
        assertThat(getArchiveName("...Test", true)).isEqualTo("...Test.zip")
    }

    /** Tests zipping one file. */
    @Test
    fun zipOneFile() {
@@ -70,7 +146,45 @@ internal class CompressJobTest : AbstractJobTest<CompressJob>() {
            assertThat(destination!!.peek().displayName).isEqualTo("TEST_ROOT_0")
        }

        assertTreeIs(mutableMapOf("/Test.txt" to textEntry(14), "/Test.txt.zip" to zipEntry(146)))
        val archivePath = if (isZipNgFlagEnabled()) "/Test.zip" else "/Test.txt.zip"
        assertTreeIs(mutableMapOf("/Test.txt" to textEntry(14), archivePath to zipEntry(146)))
    }

    /** Tests zipping one folder. */
    @Test
    fun zipOneFolder() {
        val uri = mDocs.createDocument(mSrcRoot, MIME_TYPE_DIR, "Test.a")

        assertTreeIs(mutableMapOf("/Test.a" to dirEntry))

        val job = createJob(listOf(uri))

        with(job.getJobProgress()) {
            assertThat(operationType).isEqualTo(OPERATION_COMPRESS)
            assertThat(id).isEqualTo(job.id)
            assertThat(state).isEqualTo(Job.STATE_CREATED)
            assertThat(hasFailures).isFalse()
            assertThat(currentBytes).isEqualTo(-1)
            assertThat(requiredBytes).isEqualTo(-1)
            assertThat(msRemaining).isLessThan(0)
        }

        job.run()
        mJobListener.assertFinished()

        with(job.getJobProgress()) {
            assertThat(operationType).isEqualTo(OPERATION_COMPRESS)
            assertThat(id).isEqualTo(job.id)
            assertThat(state).isEqualTo(Job.STATE_COMPLETED)
            assertThat(hasFailures).isFalse()
            assertThat(msg).isEqualTo("Zipping “Test.a”")
            assertThat(currentBytes).isEqualTo(-1)
            assertThat(requiredBytes).isEqualTo(-1)
            assertThat(msRemaining).isLessThan(0)
            assertThat(destination!!.peek().displayName).isEqualTo("TEST_ROOT_0")
        }

        assertTreeIs(mutableMapOf("/Test.a" to dirEntry, "/Test.a.zip" to zipEntry(130)))
    }

    /** Tests zipping two files. */
@@ -111,11 +225,12 @@ internal class CompressJobTest : AbstractJobTest<CompressJob>() {
            assertThat(destination!!.peek().displayName).isEqualTo("TEST_ROOT_0")
        }

        val archivePath = if (isZipNgFlagEnabled()) "/Archive.zip" else "/archive.zip"
        assertTreeIs(
            mutableMapOf(
                "/Test1.txt" to textEntry(14),
                "/Test2.txt" to textEntry(19),
                "/archive.zip" to zipEntry(279),
                archivePath to zipEntry(279),
            )
        )
    }
@@ -130,12 +245,14 @@ internal class CompressJobTest : AbstractJobTest<CompressJob>() {
        mDocs.writeDocument(uri2, FRUITY_BYTES)

        mDocs.createDocument(mSrcRoot, "application/zip", "archive.zip")
        mDocs.createDocument(mSrcRoot, "application/zip", "Archive.zip")

        assertTreeIs(
            mutableMapOf(
                "/Test1.txt" to textEntry(14),
                "/Test2.txt" to textEntry(19),
                "/archive.zip" to zipEntry(0),
                "/Archive.zip" to zipEntry(0),
            )
        )

@@ -176,6 +293,7 @@ internal class CompressJobTest : AbstractJobTest<CompressJob>() {
                "/Test1.txt" to textEntry(14),
                "/Test2.txt" to textEntry(19),
                "/archive.zip" to zipEntry(0),
                "/Archive.zip" to zipEntry(0),
            )
        )
    }