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

Commit 47ad186a authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Calculate MediaColumns.HASH when demanded.

We'll come back in a future change to wire up automatic hashing in
onIdleMaintenance(), but we'll hold off on that until we've
implemented our optimized in-kernel hashing.

For now, generate the has when demanded via canonicalize(), and
clear any hash whenever the file is edited.  Tests to verify sanity.

Bug: 120782363
Test: atest android.provider.cts.MediaStoreTest
Change-Id: I287f7a204655b37e4efd519579b12084ee4fb8e3
parent 52fe5dd9
Loading
Loading
Loading
Loading
+54 −0
Original line number Original line Diff line number Diff line
@@ -66,6 +66,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.charset.StandardCharsets;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Comparator;
import java.util.Objects;
import java.util.Objects;
@@ -716,6 +719,57 @@ public class FileUtils {
        }
        }
    }
    }


    /**
     * Compute the digest of the given file using the requested algorithm.
     *
     * @param algorithm Any valid algorithm accepted by
     *            {@link MessageDigest#getInstance(String)}.
     * @hide
     */
    public static byte[] digest(@NonNull File file, @NonNull String algorithm)
            throws IOException, NoSuchAlgorithmException {
        try (FileInputStream in = new FileInputStream(file)) {
            return digest(in, algorithm);
        }
    }

    /**
     * Compute the digest of the given file using the requested algorithm.
     *
     * @param algorithm Any valid algorithm accepted by
     *            {@link MessageDigest#getInstance(String)}.
     * @hide
     */
    public static byte[] digest(@NonNull InputStream in, @NonNull String algorithm)
            throws IOException, NoSuchAlgorithmException {
        // TODO: implement kernel optimizations
        return digestInternalUserspace(in, algorithm);
    }

    /**
     * Compute the digest of the given file using the requested algorithm.
     *
     * @param algorithm Any valid algorithm accepted by
     *            {@link MessageDigest#getInstance(String)}.
     * @hide
     */
    public static byte[] digest(FileDescriptor fd, String algorithm)
            throws IOException, NoSuchAlgorithmException {
        // TODO: implement kernel optimizations
        return digestInternalUserspace(new FileInputStream(fd), algorithm);
    }

    private static byte[] digestInternalUserspace(InputStream in, String algorithm)
            throws IOException, NoSuchAlgorithmException {
        final MessageDigest digest = MessageDigest.getInstance(algorithm);
        try (DigestInputStream digestStream = new DigestInputStream(in, digest)) {
            final byte[] buffer = new byte[8192];
            while (digestStream.read(buffer) != -1) {
            }
        }
        return digest.digest();
    }

    /**
    /**
     * Delete older files in a directory until only those matching the given
     * Delete older files in a directory until only those matching the given
     * constraints remain.
     * constraints remain.