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

Commit b8dad6c6 authored by Android Build Merger (Role)'s avatar Android Build Merger (Role)
Browse files

[automerger] DO NOT MERGE Rework thumbnail cleanup am: b514ce9b

Change-Id: I5cb1316547ced23a1259e068d1ea34631d105608
parents 1b6f3f9a b514ce9b
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -672,8 +672,8 @@ public final class MediaStore {
            // Log.v(TAG, "getThumbnail: origId="+origId+", kind="+kind+", isVideo="+isVideo);
            // If the magic is non-zero, we simply return thumbnail if it does exist.
            // querying MediaProvider and simply return thumbnail.
            MiniThumbFile thumbFile = new MiniThumbFile(isVideo ? Video.Media.EXTERNAL_CONTENT_URI
                    : Images.Media.EXTERNAL_CONTENT_URI);
            MiniThumbFile thumbFile = MiniThumbFile.instance(
                    isVideo ? Video.Media.EXTERNAL_CONTENT_URI : Images.Media.EXTERNAL_CONTENT_URI);
            Cursor c = null;
            try {
                long magic = thumbFile.getMagic(origId);
+0 −63
Original line number Diff line number Diff line
@@ -308,7 +308,6 @@ public class MediaScanner
    private Uri mAudioUri;
    private Uri mVideoUri;
    private Uri mImagesUri;
    private Uri mThumbsUri;
    private Uri mPlaylistsUri;
    private Uri mFilesUri;
    private Uri mFilesUriNoNotify;
@@ -1164,64 +1163,6 @@ public class MediaScanner
        }
    }

    private boolean inScanDirectory(String path, String[] directories) {
        for (int i = 0; i < directories.length; i++) {
            String directory = directories[i];
            if (path.startsWith(directory)) {
                return true;
            }
        }
        return false;
    }

    private void pruneDeadThumbnailFiles() {
        HashSet<String> existingFiles = new HashSet<String>();
        String directory = "/sdcard/DCIM/.thumbnails";
        String [] files = (new File(directory)).list();
        Cursor c = null;
        if (files == null)
            files = new String[0];

        for (int i = 0; i < files.length; i++) {
            String fullPathString = directory + "/" + files[i];
            existingFiles.add(fullPathString);
        }

        try {
            c = mMediaProvider.query(
                    mPackageName,
                    mThumbsUri,
                    new String [] { "_data" },
                    null,
                    null,
                    null, null);
            Log.v(TAG, "pruneDeadThumbnailFiles... " + c);
            if (c != null && c.moveToFirst()) {
                do {
                    String fullPathString = c.getString(0);
                    existingFiles.remove(fullPathString);
                } while (c.moveToNext());
            }

            for (String fileToDelete : existingFiles) {
                if (false)
                    Log.v(TAG, "fileToDelete is " + fileToDelete);
                try {
                    (new File(fileToDelete)).delete();
                } catch (SecurityException ex) {
                }
            }

            Log.v(TAG, "/pruneDeadThumbnailFiles... " + c);
        } catch (RemoteException e) {
            // We will soon be killed...
        } finally {
            if (c != null) {
                c.close();
            }
        }
    }

    static class MediaBulkDeleter {
        StringBuilder whereClause = new StringBuilder();
        ArrayList<String> whereArgs = new ArrayList<String>(100);
@@ -1267,9 +1208,6 @@ public class MediaScanner
            processPlayLists();
        }

        if (mOriginalCount == 0 && mImagesUri.equals(Images.Media.getContentUri("external")))
            pruneDeadThumbnailFiles();

        // allow GC to clean up
        mPlayLists = null;
        mMediaProvider = null;
@@ -1289,7 +1227,6 @@ public class MediaScanner
        mAudioUri = Audio.Media.getContentUri(volumeName);
        mVideoUri = Video.Media.getContentUri(volumeName);
        mImagesUri = Images.Media.getContentUri(volumeName);
        mThumbsUri = Images.Thumbnails.getContentUri(volumeName);
        mFilesUri = Files.getContentUri(volumeName);
        mFilesUriNoNotify = mFilesUri.buildUpon().appendQueryParameter("nonotify", "1").build();

+52 −2
Original line number Diff line number Diff line
@@ -44,13 +44,14 @@ import java.util.Hashtable;
 */
public class MiniThumbFile {
    private static final String TAG = "MiniThumbFile";
    private static final int MINI_THUMB_DATA_FILE_VERSION = 3;
    private static final int MINI_THUMB_DATA_FILE_VERSION = 4;
    public static final int BYTES_PER_MINTHUMB = 10000;
    private static final int HEADER_SIZE = 1 + 8 + 4;
    private Uri mUri;
    private RandomAccessFile mMiniThumbFile;
    private FileChannel mChannel;
    private ByteBuffer mBuffer;
    private ByteBuffer mEmptyBuffer;
    private static final Hashtable<String, MiniThumbFile> sThumbFiles =
        new Hashtable<String, MiniThumbFile>();

@@ -127,9 +128,10 @@ public class MiniThumbFile {
        return mMiniThumbFile;
    }

    public MiniThumbFile(Uri uri) {
    private MiniThumbFile(Uri uri) {
        mUri = uri;
        mBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
        mEmptyBuffer = ByteBuffer.allocateDirect(BYTES_PER_MINTHUMB);
    }

    public synchronized void deactivate() {
@@ -184,6 +186,54 @@ public class MiniThumbFile {
        return 0;
    }

    public synchronized void eraseMiniThumb(long id) {
        RandomAccessFile r = miniThumbDataFile();
        if (r != null) {
            long pos = id * BYTES_PER_MINTHUMB;
            FileLock lock = null;
            try {
                mBuffer.clear();
                mBuffer.limit(1 + 8);

                lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);
                // check that we can read the following 9 bytes
                // (1 for the "status" and 8 for the long)
                if (mChannel.read(mBuffer, pos) == 9) {
                    mBuffer.position(0);
                    if (mBuffer.get() == 1) {
                        long currentMagic = mBuffer.getLong();
                        if (currentMagic == 0) {
                            // there is no thumbnail stored here
                            Log.i(TAG, "no thumbnail for id " + id);
                            return;
                        }
                        // zero out the thumbnail slot
                        // Log.v(TAG, "clearing slot " + id + ", magic " + currentMagic
                        //         + " at offset " + pos);
                        mChannel.write(mEmptyBuffer, pos);
                    }
                } else {
                    // Log.v(TAG, "No slot");
                }
            } catch (IOException ex) {
                Log.v(TAG, "Got exception checking file magic: ", ex);
            } catch (RuntimeException ex) {
                // Other NIO related exception like disk full, read only channel..etc
                Log.e(TAG, "Got exception when reading magic, id = " + id +
                        ", disk full or mount read-only? " + ex.getClass());
            } finally {
                try {
                    if (lock != null) lock.release();
                }
                catch (IOException ex) {
                    // ignore it.
                }
            }
        } else {
            // Log.v(TAG, "No data file");
        }
    }

    public synchronized void saveMiniThumbToFile(byte[] data, long id, long magic)
            throws IOException {
        RandomAccessFile r = miniThumbDataFile();