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

Commit 09496f95 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix screenshot failure with transcoding"

parents 6656f0fc 7fe47a64
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
@@ -115,6 +116,9 @@ public final class FileUtils {
    private FileUtils() {
    }

    private static final String CAMERA_DIR_LOWER_CASE = "/storage/emulated/" + UserHandle.myUserId()
            + "/dcim/camera";

    /** Regular expression for safe filenames: no spaces or metacharacters.
      *
      * Use a preload holder so that FileUtils can be compile-time initialized.
@@ -1432,18 +1436,27 @@ public final class FileUtils {
        }
    }

    // TODO(b/170488060): Consider better approach
    /** {@hide} */
    @VisibleForTesting
    public static FileDescriptor convertToModernFd(FileDescriptor fd) {
        try {
            Context context = AppGlobals.getInitialApplication();
            File realFile = ParcelFileDescriptor.getFile(fd);
            String fileName = realFile.getName();
            boolean isCameraVideo = !fileName.startsWith(".") && fileName.endsWith(".mp4")
                    && contains(CAMERA_DIR_LOWER_CASE, realFile.getAbsolutePath().toLowerCase(
                                    Locale.ROOT));

            if (!SystemProperties.getBoolean("sys.fuse.transcode_enabled", false)
                    || UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)) {
                // If transcode is enabled we optimize by default, unless explicitly disabled.
                // Never convert modern fd for MediaProvider, because this requires
                    || UserHandle.getAppId(Process.myUid()) == getMediaProviderAppId(context)
                    || !isCameraVideo) {
                // 1. If transcode is enabled we optimize by default, unless explicitly disabled.
                // 2. Never convert modern fd for MediaProvider, because this requires
                // MediaStore#scanFile and can cause infinite loops when MediaProvider scans
                // 3. Only convert published mp4 videos in the DCIM/Camera dir
                return null;
            }
            File realFile = ParcelFileDescriptor.getFile(fd);
            Log.i(TAG, "Changing to modern format dataSource for: " + realFile);
            ContentResolver resolver = context.getContentResolver();

+53 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.os;

import static android.os.FileUtils.convertToModernFd;
import static android.os.FileUtils.roundStorageSize;
import static android.os.FileUtils.translateModeAccessToPosix;
import static android.os.FileUtils.translateModePfdToPosix;
@@ -45,6 +46,8 @@ import static android.text.format.DateUtils.WEEK_IN_MILLIS;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

@@ -67,6 +70,7 @@ import org.junit.runner.RunWith;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
@@ -562,6 +566,55 @@ public class FileUtilsTest {
        assertEquals(O_RDWR, translateModeAccessToPosix(R_OK | W_OK | X_OK));
    }

    @Test
    public void testConvertToModernFd() throws Exception {
        final String nonce = String.valueOf(System.nanoTime());

        final File cameraDir = new File("/storage/emulated/0/DCIM/Camera");
        final File nonCameraDir = new File("/storage/emulated/0/Pictures");
        cameraDir.mkdirs();
        nonCameraDir.mkdirs();

        final File validVideoCameraDir = new File(cameraDir, "validVideo-" + nonce + ".mp4");
        final File validImageCameraDir = new File(cameraDir, "validImage-" + nonce + ".jpg");
        final File invalidVideoCameraDir = new File(cameraDir, ".invalidVideo-" + nonce + ".mp4");

        final File validVideoNonCameraDir = new File(nonCameraDir, "validVideo-" + nonce + ".mp4");
        final File validImageNonCameraDir = new File(nonCameraDir, "validImage-" + nonce + ".jpg");

        try {
            FileDescriptor pfdValidVideoCameraDir =
                    ParcelFileDescriptor.open(validVideoCameraDir,
                            MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();
            FileDescriptor pfdValidImageCameraDir =
                    ParcelFileDescriptor.open(validImageCameraDir,
                            MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();
            FileDescriptor pfdInvalidVideoCameraDir =
                    ParcelFileDescriptor.open(invalidVideoCameraDir,
                            MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();

            FileDescriptor pfdValidVideoNonCameraDir =
                    ParcelFileDescriptor.open(validVideoNonCameraDir,
                            MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();
            FileDescriptor pfdValidImageNonCameraDir =
                    ParcelFileDescriptor.open(validImageNonCameraDir,
                            MODE_CREATE | MODE_READ_WRITE).getFileDescriptor();

            assertNotNull(convertToModernFd(pfdValidVideoCameraDir));

            assertNull(convertToModernFd(pfdValidImageCameraDir));
            assertNull(convertToModernFd(pfdInvalidVideoCameraDir));
            assertNull(convertToModernFd(pfdValidVideoNonCameraDir));
            assertNull(convertToModernFd(pfdValidImageNonCameraDir));
        } finally {
            validVideoCameraDir.delete();
            validImageCameraDir.delete();
            invalidVideoCameraDir.delete();
            validVideoNonCameraDir.delete();
            validImageNonCameraDir.delete();
        }
    }

    private static void assertTranslate(String string, int posix, int pfd) {
        assertEquals(posix, translateModeStringToPosix(string));
        assertEquals(string, translateModePosixToString(posix));