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

Commit c6a1167e authored by George Mount's avatar George Mount Committed by Android (Google) Code Review
Browse files

Merge "Remove ImageCache from PhotoProvider in favor of MediaCache." into gb-ub-photos-bryce

parents 5997a013 d4681a3c
Loading
Loading
Loading
Loading
+11 −8
Original line number Diff line number Diff line
@@ -276,7 +276,7 @@ public class MediaCache {
        mCacheDir = cacheDir;
    }

    private File getCacheDir() {
    public File getCacheDir() {
        synchronized (mContext) {
            if (mCacheDir == null) {
                String state = Environment.getExternalStorageState();
@@ -398,6 +398,10 @@ public class MediaCache {
        File file = null;
        if (cachedId != null) {
            file = createCacheImagePath(cachedId);
            if (!file.exists()) {
                mDatabaseHelper.delete(contentUri, size, mDeleteFile);
                file = null;
            }
        }
        return file;
    }
@@ -479,9 +483,9 @@ public class MediaCache {
        }
        size = retriever.normalizeMediaSize(uri, size);

        Long cachedId = mDatabaseHelper.getCached(uri, size);
        if (cachedId != null) {
            addNotification(complete, createCacheImagePath(cachedId));
        File cachedFile = getCachedFile(uri, size);
        if (cachedFile != null) {
            addNotification(complete, cachedFile);
            return;
        }
        String differentiator = getDifferentiator(uri.getScheme(), uri.getAuthority());
@@ -540,10 +544,9 @@ public class MediaCache {
    }

    private void processTask(ProcessingJob job) {
        Long cachedId = mDatabaseHelper.getCached(job.contentUri, job.size);
        if (cachedId != null) {
            File file = createCacheImagePath(cachedId);
            addNotification(job.complete, file);
        File cachedFile = getCachedFile(job.contentUri, job.size);
        if (cachedFile != null) {
            addNotification(job.complete, cachedFile);
            return;
        }

+26 −12
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
    }

    static interface Action {
        void execute(Uri uri, long id, MediaRetriever.MediaSize size, Object parameter);
        void execute(Uri uri, long id, MediaSize size, Object parameter);
    }

    private static final String[] PROJECTION_ID = {
@@ -89,10 +89,10 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
    static class QueryCacheResults {
        public QueryCacheResults(long id, int sizeVal) {
            this.id = id;
            this.size = MediaRetriever.MediaSize.fromInteger(sizeVal);
            this.size = MediaSize.fromInteger(sizeVal);
        }
        public long id;
        public MediaRetriever.MediaSize size;
        public MediaSize size;
    }

    public MediaCacheDatabase(Context context) {
@@ -111,7 +111,7 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
        MediaCache.getInstance().clearCacheDir();
    }

    public Long getCached(Uri uri, MediaRetriever.MediaSize size) {
    public Long getCached(Uri uri, MediaSize size) {
        String where = Columns.URI + " = ? AND " + Columns.MEDIA_SIZE + " = ?";
        SQLiteDatabase db = getWritableDatabase();
        String[] whereArgs = {
@@ -140,7 +140,7 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
        return id;
    }

    public MediaRetriever.MediaSize executeOnBestCached(Uri uri, MediaRetriever.MediaSize size, Action action) {
    public MediaSize executeOnBestCached(Uri uri, MediaSize size, Action action) {
        String where = Columns.URI + " = ? AND " + Columns.MEDIA_SIZE + " < ?";
        String orderBy = Columns.MEDIA_SIZE + " DESC";
        SQLiteDatabase db = getReadableDatabase();
@@ -148,10 +148,10 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
                uri.toString(), String.valueOf(size.getValue()),
        };
        Cursor cursor = db.query(TABLE, PROJECTION_CACHED, where, whereArgs, null, null, orderBy);
        MediaRetriever.MediaSize bestSize = null;
        MediaSize bestSize = null;
        if (cursor.moveToNext()) {
            long id = cursor.getLong(0);
            bestSize = MediaRetriever.MediaSize.fromInteger(cursor.getInt(1));
            bestSize = MediaSize.fromInteger(cursor.getInt(1));
            long fileSize = cursor.getLong(2);
            action.execute(uri, id, bestSize, fileSize);
        }
@@ -159,7 +159,7 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
        return bestSize;
    }

    public long insert(Uri uri, MediaRetriever.MediaSize size, Action action, File tempFile) {
    public long insert(Uri uri, MediaSize size, Action action, File tempFile) {
        SQLiteDatabase db = getWritableDatabase();
        db.beginTransaction();
        try {
@@ -195,20 +195,34 @@ class MediaCacheDatabase extends SQLiteOpenHelper {
        }
    }

    public void delete(Uri uri, MediaSize size, Action action) {
        String where = Columns.URI + " = ? AND " + Columns.MEDIA_SIZE + " = ?";
        String[] whereArgs = {
                uri.toString(), String.valueOf(size.getValue()),
        };
        deleteRows(uri, where, whereArgs, action);
    }

    public void delete(Uri uri, Action action) {
        SQLiteDatabase db = getWritableDatabase();
        String where = Columns.URI + " = ?";
        String[] whereArgs = {
            uri.toString()
        };
        deleteRows(uri, where, whereArgs, action);
    }

    private void deleteRows(Uri uri, String where, String[] whereArgs, Action action) {
        SQLiteDatabase db = getWritableDatabase();
        // Make this an atomic operation
        db.beginTransaction();
        Cursor cursor = db.query(TABLE, PROJECTION_CACHED, where, whereArgs, null, null, null);
        while (cursor.moveToNext()) {
            long id = cursor.getLong(0);
            MediaRetriever.MediaSize size = MediaRetriever.MediaSize.fromInteger(cursor.getInt(1));
            action.execute(uri, id, size, null);
            MediaSize size = MediaSize.fromInteger(cursor.getInt(1));
            long length = cursor.getLong(2);
            action.execute(uri, id, size, length);
        }
        cursor.close();
        db.beginTransaction();
        try {
            db.delete(TABLE, where, whereArgs);
            db.setTransactionSuccessful();
+28 −0
Original line number Diff line number Diff line
@@ -21,9 +21,12 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.util.Pools.SimplePool;
import android.util.Pools.SynchronizedPool;

import com.android.gallery3d.R;
import com.android.gallery3d.common.BitmapUtils;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DecodeUtils;
import com.android.gallery3d.data.MediaItem;
import com.android.gallery3d.util.ThreadPool.CancelListener;
@@ -33,10 +36,15 @@ import com.android.photos.data.MediaRetriever.MediaSize;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class MediaCacheUtils {
    private static final String TAG = MediaCacheUtils.class.getSimpleName();
    private static int QUALITY = 80;
    private static final int BUFFER_SIZE = 4096;
    private static final SimplePool<byte[]> mBufferPool = new SynchronizedPool<byte[]>(5);

    private static final JobContext sJobStub = new JobContext() {

        @Override
@@ -136,4 +144,24 @@ public class MediaCacheUtils {
        }
        return success;
    }

    public static int copyStream(InputStream in, OutputStream out) throws IOException {
        byte[] buffer = mBufferPool.acquire();
        if (buffer == null) {
            buffer = new byte[BUFFER_SIZE];
        }
        try {
            int totalWritten = 0;
            int bytesRead;
            while ((bytesRead = in.read(buffer)) >= 0) {
                out.write(buffer, 0, bytesRead);
                totalWritten += bytesRead;
            }
            return totalWritten;
        } finally {
            Utils.closeSilently(in);
            Utils.closeSilently(out);
            mBufferPool.release(buffer);
        }
    }
}
+8 −55
Original line number Diff line number Diff line
@@ -85,6 +85,12 @@ public class PhotoProvider extends SQLiteContentProvider {
     * Contains columns that can be accessed via Photos.CONTENT_URI.
     */
    public static interface Photos extends BaseColumns {
        /**
         * The image_type query parameter required for requesting a specific
         * size of image.
         */
        public static final String MEDIA_SIZE_QUERY_PARAMETER = "media_size";

        /** Internal database table used for basic photo information. */
        public static final String TABLE = "photos";
        /** Content URI for basic photo and video information. */
@@ -203,49 +209,6 @@ public class PhotoProvider extends SQLiteContentProvider {
        public static final String KEY_EXIF_ISO = ExifInterface.TAG_ISO;
    }

    /**
     * Contains columns and Uri for maintaining the image cache.
     */
    public static interface ImageCache extends BaseColumns {
        /** Internal database table used for the image cache */
        public static final String TABLE = "image_cache";

        /**
         * The image_type query parameter required for accessing a specific
         * image
         */
        public static final String IMAGE_TYPE_QUERY_PARAMETER = "image_type";

        // ImageCache.IMAGE_TYPE values
        public static final int IMAGE_TYPE_ALBUM_COVER = 1;
        public static final int IMAGE_TYPE_THUMBNAIL = 2;
        public static final int IMAGE_TYPE_PREVIEW = 3;
        public static final int IMAGE_TYPE_ORIGINAL = 4;

        /**
         * Content URI for retrieving image paths. The
         * IMAGE_TYPE_QUERY_PARAMETER must be used in queries.
         */
        public static final Uri CONTENT_URI = Uri.withAppendedPath(BASE_CONTENT_URI, TABLE);

        /**
         * Content URI for retrieving the album cover art. The album ID must be
         * appended to the URI.
         */
        public static final Uri ALBUM_COVER_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI,
                Albums.TABLE);

        /**
         * An _ID from Albums or Photos, depending on whether IMAGE_TYPE is
         * IMAGE_TYPE_ALBUM or not. Long value.
         */
        public static final String REMOTE_ID = "remote_id";
        /** One of IMAGE_TYPE_* values. */
        public static final String IMAGE_TYPE = "image_type";
        /** The String path to the image. */
        public static final String PATH = "path";
    };

    // SQL used within this class.
    protected static final String WHERE_ID = BaseColumns._ID + " = ?";
    protected static final String WHERE_METADATA_ID = Metadata.PHOTO_ID + " = ? AND "
@@ -284,10 +247,8 @@ public class PhotoProvider extends SQLiteContentProvider {
    protected static final int MATCH_ALBUM_ID = 4;
    protected static final int MATCH_METADATA = 5;
    protected static final int MATCH_METADATA_ID = 6;
    protected static final int MATCH_IMAGE = 7;
    protected static final int MATCH_ALBUM_COVER = 8;
    protected static final int MATCH_ACCOUNT = 9;
    protected static final int MATCH_ACCOUNT_ID = 10;
    protected static final int MATCH_ACCOUNT = 7;
    protected static final int MATCH_ACCOUNT_ID = 8;

    static {
        sUriMatcher.addURI(AUTHORITY, Photos.TABLE, MATCH_PHOTO);
@@ -299,11 +260,6 @@ public class PhotoProvider extends SQLiteContentProvider {
        sUriMatcher.addURI(AUTHORITY, Metadata.TABLE, MATCH_METADATA);
        // match against metadata/<Metadata._ID>
        sUriMatcher.addURI(AUTHORITY, Metadata.TABLE + "/#", MATCH_METADATA_ID);
        // match against image_cache/<ImageCache.PHOTO_ID>
        sUriMatcher.addURI(AUTHORITY, ImageCache.TABLE + "/#", MATCH_IMAGE);
        // match against image_cache/album/<Albums._ID>
        sUriMatcher.addURI(AUTHORITY, ImageCache.TABLE + "/" + Albums.TABLE + "/#",
                MATCH_ALBUM_COVER);
        sUriMatcher.addURI(AUTHORITY, Accounts.TABLE, MATCH_ACCOUNT);
        // match against Accounts._ID
        sUriMatcher.addURI(AUTHORITY, Accounts.TABLE + "/#", MATCH_ACCOUNT_ID);
@@ -476,9 +432,6 @@ public class PhotoProvider extends SQLiteContentProvider {
        if (match == UriMatcher.NO_MATCH) {
            throw unknownUri(uri);
        }
        if (match == MATCH_IMAGE || match == MATCH_ALBUM_COVER) {
            throw new IllegalArgumentException("Operation not allowed on image cache database");
        }
        return match;
    }

+9 −9
Original line number Diff line number Diff line
@@ -157,7 +157,7 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
    public void testRetrieveOriginal() throws IOException {
        copyResourceToFile(R.raw.galaxy_nexus, mImage.getPath());
        Uri uri = Uri.fromFile(mImage);
        mMediaCache.retrieveOriginal(uri, mReady, mReady);
        mMediaCache.retrieveOriginal(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        assertNull(mReady.mInputStream);
        assertEquals(mImage, mReady.mOriginalFile);
@@ -236,13 +236,13 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
        copyResourceToFile(R.raw.android_lawn, mImage.getPath());
        Uri uri = Uri.fromFile(mImage);

        mMediaCache.retrieveOriginal(uri, mReady, mReady);
        mMediaCache.retrieveOriginal(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        assertNull(mReady.mInputStream);
        assertNotNull(mReady.mOriginalFile);

        mReady = new ReadyCollector();
        mMediaCache.retrievePreview(uri, mReady, mReady);
        mMediaCache.retrievePreview(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        assertNotNull(mReady.mInputStream);
        assertNull(mReady.mOriginalFile);
@@ -254,7 +254,7 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
        assertTrue(maxDimension < (targetSize * 2));

        mReady = new ReadyCollector();
        mMediaCache.retrieveThumbnail(uri, mReady, mReady);
        mMediaCache.retrieveThumbnail(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        assertNotNull(mReady.mInputStream);
        assertNull(mReady.mOriginalFile);
@@ -269,11 +269,11 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
    public void testFastImage() throws IOException {
        copyResourceToFile(R.raw.galaxy_nexus, mImage.getPath());
        Uri uri = Uri.fromFile(mImage);
        mMediaCache.retrieveThumbnail(uri, mReady, mReady);
        mMediaCache.retrieveThumbnail(uri, mReady, null);
        mReady.waitForNotification();
        mReady.mInputStream.close();

        mMediaCache.retrieveOriginal(uri, mReady, mReady);
        mMediaCache.retrieveOriginal(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        assertNotNull(mReady.mInputStream);
        mReady.mInputStream.close();
@@ -282,7 +282,7 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
    public void testBadRetriever() {
        Uri uri = Photos.CONTENT_URI;
        try {
            mMediaCache.retrieveOriginal(uri, mReady, mReady);
            mMediaCache.retrieveOriginal(uri, mReady, null);
            fail("Expected exception");
        } catch (IllegalArgumentException e) {
            // expected
@@ -295,7 +295,7 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
        copyResourceToFile(R.raw.android_lawn, mImage.getPath());
        Uri uri = Uri.fromFile(mImage);

        mMediaCache.retrieveThumbnail(uri, mReady, mReady);
        mMediaCache.retrieveThumbnail(uri, mReady, null);
        assertTrue(mReady.waitForNotification());
        mReady.mInputStream.close();
        assertNotNull(mMediaCache.getCachedFile(uri, MediaSize.Preview));
@@ -307,7 +307,7 @@ public class MediaCacheTest extends ProviderTestCase2<PhotoProvider> {
        mMediaCache.addRetriever(uri.getScheme(), uri.getAuthority(), retriever);
        retriever.setNullUri();
        try {
            mMediaCache.retrieveOriginal(uri, mReady, mReady);
            mMediaCache.retrieveOriginal(uri, mReady, null);
            fail("Expected IllegalArgumentException");
        } catch (IllegalArgumentException e) {
            // expected