From e606b862f26ba9e499db4f15940f8200841b9dc3 Mon Sep 17 00:00:00 2001 From: John Reck Date: Tue, 29 Jan 2013 13:55:57 -0800 Subject: [PATCH] Extract constants/boilerplate Change-Id: I52ba51bab6ec12f2925384c1eedbba96e02bfa97 --- .../android/gallery3d/provider/CanvasProvider.java | 544 ++++----------------- .../gallery3d/provider/CanvasProviderBase.java | 411 ++++++++++++++++ 2 files changed, 506 insertions(+), 449 deletions(-) create mode 100644 src/com/android/gallery3d/provider/CanvasProviderBase.java diff --git a/src/com/android/gallery3d/provider/CanvasProvider.java b/src/com/android/gallery3d/provider/CanvasProvider.java index 95c02dc7a..76cf4887d 100644 --- a/src/com/android/gallery3d/provider/CanvasProvider.java +++ b/src/com/android/gallery3d/provider/CanvasProvider.java @@ -18,13 +18,9 @@ package com.android.gallery3d.provider; import android.app.Activity; import android.content.ActivityNotFoundException; -import android.content.ContentProvider; import android.content.ContentResolver; -import android.content.ContentValues; import android.content.Intent; -import android.content.UriMatcher; import android.content.res.Configuration; -import android.database.Cursor; import android.database.MatrixCursor; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; @@ -32,7 +28,6 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Binder; import android.os.ParcelFileDescriptor; -import android.provider.BaseColumns; import android.util.Log; import com.android.gallery3d.app.GalleryApp; @@ -51,229 +46,38 @@ import com.google.android.canvas.provider.CanvasContract; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -public class CanvasProvider extends ContentProvider { +public class CanvasProvider extends CanvasProviderBase { private static final String TAG = "GalleryCanvasProvider"; - private static final String AUTHORITY = "com.android.gallery3d.provider.CanvasProvider"; - - public static Uri NOTIFY_CHANGED_URI = Uri.parse("content://" + AUTHORITY); - - private static final String PATH_IMAGE = "image"; - - private static final String PATH_LAUNCHER = "launcher"; - private static final String PATH_LAUNCHER_ITEM = PATH_LAUNCHER + "/" - + CanvasContract.PATH_LAUNCHER_ITEM; - private static final String PATH_BROWSE = "browse"; - private static final String PATH_BROWSE_HEADERS = PATH_BROWSE + "/" - + CanvasContract.PATH_BROWSE_HEADERS; - - private static final int LAUNCHER = 1; - private static final int LAUNCHER_ITEMS = 2; - private static final int LAUNCHER_ITEM_ID = 3; - private static final int BROWSE_HEADERS = 4; - private static final int BROWSE = 5; - private static final int IMAGE = 6; - - private static final Uri BROWSER_ROOT_URI = Uri.parse("content://" + AUTHORITY + "/" + PATH_BROWSE); - - private static final UriMatcher sUriMatcher = new UriMatcher( - UriMatcher.NO_MATCH); - - static { - sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER, LAUNCHER); - sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER_ITEM, LAUNCHER_ITEMS); - sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER_ITEM + "/#", - LAUNCHER_ITEM_ID); - sUriMatcher.addURI(AUTHORITY, PATH_BROWSE_HEADERS, BROWSE_HEADERS); - sUriMatcher.addURI(AUTHORITY, PATH_BROWSE + "/#", BROWSE); - sUriMatcher.addURI(AUTHORITY, PATH_IMAGE + "/*", IMAGE); - } - - private static final HashMap LAUNCHER_COLUMN_CASES = new HashMap(); - private static final String[] LAUNCHER_PROJECTION_ALL; - - private static final int LAUNCHER_CASE_ID = 0; - private static final int LAUNCHER_CASE_COUNT = 1; - private static final int LAUNCHER_CASE_NAME = 2; - private static final int LAUNCHER_CASE_IMPORTANCE = 3; - private static final int LAUNCHER_CASE_DISPLAY_NAME = 4; - private static final int LAUNCHER_CASE_VISIBLE_COUNT = 5; - private static final int LAUNCHER_CASE_CROP_ALLOWED = 6; - private static final int LAUNCHER_CASE_CACHE_TIME = 7; - private static final int LAUNCHER_CASE_INTENT_URI = 8; - - static { - LAUNCHER_COLUMN_CASES - .put(CanvasContract.Launcher._ID, LAUNCHER_CASE_ID); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher._COUNT, - LAUNCHER_CASE_COUNT); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.NAME, - LAUNCHER_CASE_NAME); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.IMPORTANCE, - LAUNCHER_CASE_IMPORTANCE); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.DISPLAY_NAME, - LAUNCHER_CASE_DISPLAY_NAME); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.VISIBLE_COUNT, - LAUNCHER_CASE_VISIBLE_COUNT); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.IMAGE_CROP_ALLOWED, - LAUNCHER_CASE_CROP_ALLOWED); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.CACHE_TIME_MS, - LAUNCHER_CASE_CACHE_TIME); - LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.INTENT_URI, - LAUNCHER_CASE_INTENT_URI); - - LAUNCHER_PROJECTION_ALL = LAUNCHER_COLUMN_CASES.keySet().toArray( - new String[] {}); - } - - private static final HashMap CLUSTER_COLUMN_CASES = new HashMap(); - private static final String[] CLUSTER_PROJECTION_ALL; - - private static final int CLUSTER_CASE_ID = 0; - private static final int CLUSTER_CASE_COUNT = 1; - private static final int CLUSTER_CASE_PARENT_ID = 2; - private static final int CLUSTER_CASE_IMAGE_URI = 3; - - static { - CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem._ID, - CLUSTER_CASE_ID); - CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem._COUNT, - CLUSTER_CASE_COUNT); - CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem.PARENT_ID, - CLUSTER_CASE_PARENT_ID); - CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem.IMAGE_URI, - CLUSTER_CASE_IMAGE_URI); - - CLUSTER_PROJECTION_ALL = CLUSTER_COLUMN_CASES.keySet().toArray( - new String[] {}); - } - - private static final HashMap BROWSE_HEADER_COLUMN_CASES = new HashMap(); - private static final String[] BROWSE_HEADER_PROJECTION_ALL; - - private static final int BROWSE_HEADER_CASE_ID = 0; - private static final int BROWSE_HEADER_CASE_COUNT = 1; - private static final int BROWSE_HEADER_CASE_NAME = 2; - private static final int BROWSE_HEADER_CASE_DISPLAY_NAME = 3; - private static final int BROWSE_HEADER_CASE_ICON_URI = 4; - private static final int BROWSE_HEADER_CASE_BADGE_URI = 5; - private static final int BROWSE_HEADER_CASE_COLOR_HINT = 6; - private static final int BROWSE_HEADER_CASE_TEXT_COLOR_HINT = 7; - private static final int BROWSE_HEADER_CASE_BG_IMAGE_URI = 8; - private static final int BROWSE_HEADER_CASE_EXPAND_GROUP = 9; - private static final int BROWSE_HEADER_CASE_WRAP = 10; - private static final int BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH = 11; - private static final int BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT = 12; - - static { - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders._ID, - BROWSE_HEADER_CASE_ID); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders._COUNT, - BROWSE_HEADER_CASE_COUNT); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.NAME, - BROWSE_HEADER_CASE_NAME); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.DISPLAY_NAME, - BROWSE_HEADER_CASE_DISPLAY_NAME); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.ICON_URI, - BROWSE_HEADER_CASE_ICON_URI); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.BADGE_URI, - BROWSE_HEADER_CASE_BADGE_URI); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.COLOR_HINT, - BROWSE_HEADER_CASE_COLOR_HINT); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.TEXT_COLOR_HINT, - BROWSE_HEADER_CASE_TEXT_COLOR_HINT); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.BG_IMAGE_URI, - BROWSE_HEADER_CASE_BG_IMAGE_URI); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.EXPAND_GROUP, - BROWSE_HEADER_CASE_EXPAND_GROUP); - BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.WRAP_ITEMS, - BROWSE_HEADER_CASE_WRAP); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.DEFAULT_ITEM_WIDTH, - BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH); - BROWSE_HEADER_COLUMN_CASES.put( - CanvasContract.BrowseHeaders.DEFAULT_ITEM_HEIGHT, - BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT); - - BROWSE_HEADER_PROJECTION_ALL = BROWSE_HEADER_COLUMN_CASES.keySet() - .toArray(new String[] {}); - } - - private static final HashMap BROWSE_COLUMN_CASES = new HashMap(); - private static final String[] BROWSE_PROJECTION_ALL; - - private static final int BROWSE_CASE_ID = 0; - private static final int BROWSE_CASE_COUNT = 1; - private static final int BROWSE_CASE_PARENT_ID = 2; - private static final int BROWSE_CASE_DISPLAY_NAME = 3; - private static final int BROWSE_CASE_DISPLAY_DESCRIPTION = 4; - private static final int BROWSE_CASE_IMAGE_URI = 5; - private static final int BROWSE_CASE_WIDTH = 6; - private static final int BROWSE_CASE_HEIGHT = 7; - private static final int BROWSE_CASE_INTENT_URI = 8; - - static { - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems._ID, BROWSE_CASE_ID); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems._COUNT, - BROWSE_CASE_COUNT); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.PARENT_ID, - BROWSE_CASE_PARENT_ID); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.DISPLAY_NAME, - BROWSE_CASE_DISPLAY_NAME); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.DISPLAY_DESCRIPTION, - BROWSE_CASE_DISPLAY_DESCRIPTION); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.IMAGE_URI, - BROWSE_CASE_IMAGE_URI); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.WIDTH, - BROWSE_CASE_WIDTH); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.HEIGHT, - BROWSE_CASE_HEIGHT); - BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.INTENT_URI, - BROWSE_CASE_INTENT_URI); - - BROWSE_PROJECTION_ALL = BROWSE_COLUMN_CASES.keySet().toArray( - new String[] {}); - } - - // The max clusters that we'll return for a single launcher - private static final int MAX_CLUSTER_SIZE = 3; - // The max amount of items we'll return for a cluster - private static final int MAX_CLUSTER_ITEM_SIZE = 10; - private static final Integer CACHE_TIME_MS = 1*1000; - - private DataManager mDataManager; + DataManager mDataManager; private MediaSet mRootSet; - private ArrayList mClusters = new ArrayList(MAX_CLUSTER_SIZE); - - @Override - public boolean onCreate() { - GalleryApp app = (GalleryApp) getContext().getApplicationContext(); - mDataManager = app.getDataManager(); - return true; - } private final static SyncListener sNullSyncListener = new SyncListener() { + @Override public void onSyncDone(MediaSet mediaSet, int resultCode) { } }; private final ContentListener mChangedListener = new ContentListener() { + @Override public void onContentDirty() { - getContext().getContentResolver().notifyChange( - NOTIFY_CHANGED_URI, null, false); + getContext().getContentResolver().notifyChange(NOTIFY_CHANGED_URI, + null, false); } }; + @Override + public boolean onCreate() { + GalleryApp app = (GalleryApp) getContext().getApplicationContext(); + mDataManager = app.getDataManager(); + return true; + } + private MediaSet loadRootMediaSet() { if (mRootSet == null) { String path = mDataManager.getTopSetPath(DataManager.INCLUDE_ALL); @@ -298,14 +102,11 @@ public class CanvasProvider extends ContentProvider { set.loadIfDirty(); } - private void loadClustersIfEmpty() { - if (mClusters.size() > 0) { - return; - } - + @Override + protected void loadClusters(List clusters) { MediaSet root = loadRootMediaSet(); int count = root.getSubMediaSetCount(); - for (int i = 0; i < count && mClusters.size() < MAX_CLUSTER_SIZE; i++) { + for (int i = 0; i < count && clusters.size() < MAX_CLUSTER_SIZE; i++) { MediaSet set = root.getSubMediaSet(i); loadMediaSet(set); Log.d(TAG, "Building set: " + set.getName()); @@ -316,10 +117,12 @@ public class CanvasProvider extends ContentProvider { bob.intent(intent); bob.imageCropAllowed(true); bob.cacheTimeMs(CACHE_TIME_MS); - int itemCount = Math.min(set.getMediaItemCount(), MAX_CLUSTER_ITEM_SIZE); + int itemCount = Math.min(set.getMediaItemCount(), + MAX_CLUSTER_ITEM_SIZE); List items = set.getMediaItem(0, itemCount); if (itemCount != items.size()) { - Log.d(TAG, "Size mismatch, expected " + itemCount + ", got " + items.size()); + Log.d(TAG, "Size mismatch, expected " + itemCount + ", got " + + items.size()); } // This is done because not all items may have been synced yet itemCount = items.size(); @@ -330,65 +133,12 @@ public class CanvasProvider extends ContentProvider { for (MediaItem item : items) { bob.addItem(createImageUri(item)); } - mClusters.add(bob.build()); - } - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, - String[] selectionArgs, String sortOrder) { - long identity = Binder.clearCallingIdentity(); - try { - MatrixCursor c; - int match = sUriMatcher.match(uri); - Log.d(TAG, "query: " + uri.toString() + ", match = " + match); - switch (match) { - case LAUNCHER: - if (projection == null) { - projection = LAUNCHER_PROJECTION_ALL; - } - c = new MatrixCursor(projection); - buildClusters(projection, c); - break; - case LAUNCHER_ITEMS: - if (projection == null) { - projection = CLUSTER_PROJECTION_ALL; - } - c = new MatrixCursor(projection); - buildMultiCluster(projection, c, uri); - break; - case LAUNCHER_ITEM_ID: - if (projection == null) { - projection = CLUSTER_PROJECTION_ALL; - } - c = new MatrixCursor(projection); - buildSingleCluster(projection, c, uri); - break; - case BROWSE_HEADERS: - if (projection == null) { - projection = BROWSE_HEADER_PROJECTION_ALL; - } - c = new MatrixCursor(projection); - buildBrowseHeaders(projection, c); - break; - case BROWSE: - if (projection == null) { - projection = BROWSE_PROJECTION_ALL; - } - c = new MatrixCursor(projection); - buildBrowseRow(projection, c, uri); - break; - default: - c = new MatrixCursor(new String[] {BaseColumns._ID}); - break; - } - return c; - } finally { - Binder.restoreCallingIdentity(identity); + clusters.add(bob.build()); } } private static final JobContext sJobStub = new JobContext() { + @Override public boolean isCancelled() { return false; @@ -412,11 +162,14 @@ public class CanvasProvider extends ContentProvider { MediaItem item = (MediaItem) mDataManager.getMediaObject(path); Job job = item.requestImage(MediaItem.TYPE_MICROTHUMBNAIL); final Bitmap bitmap = job.run(sJobStub); - final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe(); + final ParcelFileDescriptor[] fds = ParcelFileDescriptor + .createPipe(); AsyncTask task = new AsyncTask() { + @Override protected Object doInBackground(Object... params) { - OutputStream stream = new ParcelFileDescriptor.AutoCloseOutputStream(fds[1]); + OutputStream stream = new ParcelFileDescriptor.AutoCloseOutputStream( + fds[1]); bitmap.compress(CompressFormat.PNG, 100, stream); try { fds[1].close(); @@ -426,7 +179,8 @@ public class CanvasProvider extends ContentProvider { return null; } }; - task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[])null); + task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, + (Object[]) null); return fds[0]; } catch (IOException e) { @@ -441,107 +195,14 @@ public class CanvasProvider extends ContentProvider { // for which to proxy to avoid things with // android.permission.ACCESS_APP_BROWSE_DATA being able to make // any request it wants on our behalf. - return new Uri.Builder() - .scheme(ContentResolver.SCHEME_CONTENT) - .authority(AUTHORITY) - .path(PATH_IMAGE) + return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority(AUTHORITY).path(PATH_IMAGE) .appendQueryParameter("path", item.getPath().toString()) .build(); } - private void buildClusters(String[] projection, MatrixCursor c) { - mClusters.clear(); - loadClustersIfEmpty(); - - int clusterCount = mClusters.size(); - for (Cluster cluster : mClusters) { - - Object[] row = new Object[projection.length]; - long id = cluster.getId(); - for (int j = 0; j < projection.length; j++) { - if (!LAUNCHER_COLUMN_CASES.containsKey(projection[j])) { - continue; - } - int column = LAUNCHER_COLUMN_CASES.get(projection[j]); - Object obj = null; - switch (column) { - case LAUNCHER_CASE_ID: - obj = id; - break; - case LAUNCHER_CASE_COUNT: - obj = clusterCount; - break; - case LAUNCHER_CASE_NAME: - obj = cluster.getName(); - break; - case LAUNCHER_CASE_IMPORTANCE: - obj = cluster.getImportance(); - break; - case LAUNCHER_CASE_DISPLAY_NAME: - obj = cluster.getDisplayName(); - break; - case LAUNCHER_CASE_VISIBLE_COUNT: - obj = cluster.getVisibleCount(); - break; - case LAUNCHER_CASE_CACHE_TIME: - obj = cluster.getCacheTimeMs(); - break; - case LAUNCHER_CASE_INTENT_URI: - obj = cluster.getIntent().toUri(Intent.URI_INTENT_SCHEME); - break; - case LAUNCHER_CASE_CROP_ALLOWED: - obj = cluster.isImageCropAllowed(); - break; - } - row[j] = obj; - } - c.addRow(row); - } - } - - private void buildMultiCluster(String[] projection, MatrixCursor c, Uri uri) { - for (int index = 0; index < mClusters.size(); ++index) { - buildSingleCluster(projection, c, - uri.buildUpon().appendPath(String.valueOf(index)).build()); - } - } - - private void buildSingleCluster(String[] projection, MatrixCursor c, Uri uri) { - loadClustersIfEmpty(); - - int parentId = Integer.parseInt(uri.getLastPathSegment()); - - Cluster cluster = mClusters.get(parentId); - int numItems = Math.min(cluster.getItemCount(), MAX_CLUSTER_ITEM_SIZE); - for (int i = 0; i < numItems; i++) { - Cluster.ClusterItem item = cluster.getItem(i); - Object[] row = new Object[projection.length]; - - for (int j = 0; j < projection.length; j++) { - if (!CLUSTER_COLUMN_CASES.containsKey(projection[j])) { - continue; - } - int column = CLUSTER_COLUMN_CASES.get(projection[j]); - switch (column) { - case CLUSTER_CASE_ID: - row[j] = i; - break; - case CLUSTER_CASE_COUNT: - row[j] = numItems; - break; - case CLUSTER_CASE_PARENT_ID: - row[j] = parentId; - break; - case CLUSTER_CASE_IMAGE_URI: - row[j] = item.getImageUri(); - break; - } - } - c.addRow(row); - } - } - - private void buildBrowseHeaders(String[] projection, MatrixCursor c) { + @Override + protected void buildBrowseHeaders(String[] projection, MatrixCursor c) { // TODO: All images MediaSet root = loadRootMediaSet(); int itemCount = root.getSubMediaSetCount(); @@ -555,36 +216,37 @@ public class CanvasProvider extends ContentProvider { int column = BROWSE_HEADER_COLUMN_CASES.get(projection[j]); Object obj = null; switch (column) { - case BROWSE_HEADER_CASE_ID: - obj = i; - break; - case BROWSE_HEADER_CASE_COUNT: - obj = itemCount; - break; - case BROWSE_HEADER_CASE_NAME: - case BROWSE_HEADER_CASE_DISPLAY_NAME: - obj = item.getName(); - break; - case BROWSE_HEADER_CASE_ICON_URI: - break; - case BROWSE_HEADER_CASE_BADGE_URI: - break; - case BROWSE_HEADER_CASE_COLOR_HINT: - break; - case BROWSE_HEADER_CASE_TEXT_COLOR_HINT: - break; - case BROWSE_HEADER_CASE_BG_IMAGE_URI: - break; - case BROWSE_HEADER_CASE_EXPAND_GROUP: - obj = 0; - break; - case BROWSE_HEADER_CASE_WRAP: - obj = i % 2; - break; - case BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH: - case BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT: - obj = MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL); - break; + case BROWSE_HEADER_CASE_ID: + obj = i; + break; + case BROWSE_HEADER_CASE_COUNT: + obj = itemCount; + break; + case BROWSE_HEADER_CASE_NAME: + case BROWSE_HEADER_CASE_DISPLAY_NAME: + obj = item.getName(); + break; + case BROWSE_HEADER_CASE_ICON_URI: + break; + case BROWSE_HEADER_CASE_BADGE_URI: + break; + case BROWSE_HEADER_CASE_COLOR_HINT: + break; + case BROWSE_HEADER_CASE_TEXT_COLOR_HINT: + break; + case BROWSE_HEADER_CASE_BG_IMAGE_URI: + break; + case BROWSE_HEADER_CASE_EXPAND_GROUP: + obj = 0; + break; + case BROWSE_HEADER_CASE_WRAP: + obj = i % 2; + break; + case BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH: + case BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT: + obj = MediaItem + .getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL); + break; } header[j] = obj; } @@ -592,7 +254,8 @@ public class CanvasProvider extends ContentProvider { } } - private void buildBrowseRow(String[] projection, MatrixCursor c, Uri uri) { + @Override + protected void buildBrowseRow(String[] projection, MatrixCursor c, Uri uri) { int row = Integer.parseInt(uri.getLastPathSegment()); MediaSet album = loadRootMediaSet().getSubMediaSet(row); loadMediaSet(album); @@ -609,29 +272,31 @@ public class CanvasProvider extends ContentProvider { int column = BROWSE_COLUMN_CASES.get(projection[j]); Object obj = null; switch (column) { - case BROWSE_CASE_ID: - obj = i; - break; - case BROWSE_CASE_COUNT: - obj = itemCount; - break; - case BROWSE_CASE_DISPLAY_NAME: - obj = item.getName(); - break; - case BROWSE_CASE_DISPLAY_DESCRIPTION: - obj = item.getFilePath(); - break; - case BROWSE_CASE_IMAGE_URI: - obj = createImageUri(item); - break; - case BROWSE_CASE_WIDTH: - case BROWSE_CASE_HEIGHT: - obj = MediaItem.getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL); - break; - case BROWSE_CASE_INTENT_URI: - Intent intent = new Intent(Intent.ACTION_VIEW, item.getContentUri()); - obj = intent.toUri(Intent.URI_INTENT_SCHEME); - break; + case BROWSE_CASE_ID: + obj = i; + break; + case BROWSE_CASE_COUNT: + obj = itemCount; + break; + case BROWSE_CASE_DISPLAY_NAME: + obj = item.getName(); + break; + case BROWSE_CASE_DISPLAY_DESCRIPTION: + obj = item.getFilePath(); + break; + case BROWSE_CASE_IMAGE_URI: + obj = createImageUri(item); + break; + case BROWSE_CASE_WIDTH: + case BROWSE_CASE_HEIGHT: + obj = MediaItem + .getTargetSize(MediaItem.TYPE_MICROTHUMBNAIL); + break; + case BROWSE_CASE_INTENT_URI: + Intent intent = new Intent(Intent.ACTION_VIEW, + item.getContentUri()); + obj = intent.toUri(Intent.URI_INTENT_SCHEME); + break; } header[j] = obj; } @@ -639,36 +304,17 @@ public class CanvasProvider extends ContentProvider { } } - @Override - public String getType(Uri uri) { - return null; - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - throw new UnsupportedOperationException("Insert not supported"); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException("Delete not supported"); - } - - @Override - public int update(Uri uri, ContentValues values, String selection, - String[] selectionArgs) { - throw new UnsupportedOperationException("Update not supported"); - } - // TODO: Remove once b/8079561 is resolved public static boolean startBrowseActivity(Activity activity) { Configuration config = activity.getResources().getConfiguration(); if (config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH) { try { - Intent intent = CanvasContract.getBrowseIntent(BROWSER_ROOT_URI, 0); + Intent intent = CanvasContract.getBrowseIntent( + BROWSER_ROOT_URI, 0); activity.startActivity(intent); return true; - } catch (ActivityNotFoundException ex) {} + } catch (ActivityNotFoundException ex) { + } } return false; } diff --git a/src/com/android/gallery3d/provider/CanvasProviderBase.java b/src/com/android/gallery3d/provider/CanvasProviderBase.java new file mode 100644 index 000000000..9e0c1de53 --- /dev/null +++ b/src/com/android/gallery3d/provider/CanvasProviderBase.java @@ -0,0 +1,411 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.gallery3d.provider; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.Intent; +import android.content.UriMatcher; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.os.Binder; +import android.provider.BaseColumns; + +import com.google.android.canvas.data.Cluster; +import com.google.android.canvas.provider.CanvasContract; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public abstract class CanvasProviderBase extends ContentProvider { + + protected static final String AUTHORITY = "com.android.gallery3d.provider.CanvasProvider"; + public static Uri NOTIFY_CHANGED_URI = Uri.parse("content://" + AUTHORITY); + + // *************************************************** + // Provider path and URI matching + // *************************************************** + + protected static final String PATH_IMAGE = "image"; + protected static final String PATH_LAUNCHER = "launcher"; + protected static final String PATH_LAUNCHER_ITEM = PATH_LAUNCHER + "/" + + CanvasContract.PATH_LAUNCHER_ITEM; + protected static final String PATH_BROWSE = "browse"; + protected static final String PATH_BROWSE_HEADERS = PATH_BROWSE + "/" + + CanvasContract.PATH_BROWSE_HEADERS; + + protected static final int LAUNCHER = 1; + protected static final int LAUNCHER_ITEMS = 2; + protected static final int LAUNCHER_ITEM_ID = 3; + protected static final int BROWSE_HEADERS = 4; + protected static final int BROWSE = 5; + protected static final int IMAGE = 6; + protected static final Uri BROWSER_ROOT_URI = Uri.parse("content://" + + AUTHORITY + "/" + PATH_BROWSE); + protected static final UriMatcher sUriMatcher = new UriMatcher( + UriMatcher.NO_MATCH); + + static { + sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER, LAUNCHER); + sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER_ITEM, LAUNCHER_ITEMS); + sUriMatcher.addURI(AUTHORITY, PATH_LAUNCHER_ITEM + "/#", + LAUNCHER_ITEM_ID); + sUriMatcher.addURI(AUTHORITY, PATH_BROWSE_HEADERS, BROWSE_HEADERS); + sUriMatcher.addURI(AUTHORITY, PATH_BROWSE + "/#", BROWSE); + sUriMatcher.addURI(AUTHORITY, PATH_IMAGE + "/*", IMAGE); + } + + // *************************************************** + // Columns and projections + // *************************************************** + + protected static final HashMap LAUNCHER_COLUMN_CASES = new HashMap(); + protected static final String[] LAUNCHER_PROJECTION_ALL; + protected static final int LAUNCHER_CASE_ID = 0; + protected static final int LAUNCHER_CASE_COUNT = 1; + protected static final int LAUNCHER_CASE_NAME = 2; + protected static final int LAUNCHER_CASE_IMPORTANCE = 3; + protected static final int LAUNCHER_CASE_DISPLAY_NAME = 4; + protected static final int LAUNCHER_CASE_VISIBLE_COUNT = 5; + protected static final int LAUNCHER_CASE_CROP_ALLOWED = 6; + protected static final int LAUNCHER_CASE_CACHE_TIME = 7; + protected static final int LAUNCHER_CASE_INTENT_URI = 8; + + static { + LAUNCHER_COLUMN_CASES.put(BaseColumns._ID, LAUNCHER_CASE_ID); + LAUNCHER_COLUMN_CASES.put(BaseColumns._COUNT, LAUNCHER_CASE_COUNT); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.NAME, + LAUNCHER_CASE_NAME); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.IMPORTANCE, + LAUNCHER_CASE_IMPORTANCE); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.DISPLAY_NAME, + LAUNCHER_CASE_DISPLAY_NAME); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.VISIBLE_COUNT, + LAUNCHER_CASE_VISIBLE_COUNT); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.IMAGE_CROP_ALLOWED, + LAUNCHER_CASE_CROP_ALLOWED); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.CACHE_TIME_MS, + LAUNCHER_CASE_CACHE_TIME); + LAUNCHER_COLUMN_CASES.put(CanvasContract.Launcher.INTENT_URI, + LAUNCHER_CASE_INTENT_URI); + + LAUNCHER_PROJECTION_ALL = LAUNCHER_COLUMN_CASES.keySet().toArray( + new String[] {}); + } + + protected static final HashMap CLUSTER_COLUMN_CASES = new HashMap(); + protected static final String[] CLUSTER_PROJECTION_ALL; + protected static final int CLUSTER_CASE_ID = 0; + protected static final int CLUSTER_CASE_COUNT = 1; + protected static final int CLUSTER_CASE_PARENT_ID = 2; + protected static final int CLUSTER_CASE_IMAGE_URI = 3; + + static { + CLUSTER_COLUMN_CASES.put(BaseColumns._ID, CLUSTER_CASE_ID); + CLUSTER_COLUMN_CASES.put(BaseColumns._COUNT, CLUSTER_CASE_COUNT); + CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem.PARENT_ID, + CLUSTER_CASE_PARENT_ID); + CLUSTER_COLUMN_CASES.put(CanvasContract.LauncherItem.IMAGE_URI, + CLUSTER_CASE_IMAGE_URI); + + CLUSTER_PROJECTION_ALL = CLUSTER_COLUMN_CASES.keySet().toArray( + new String[] {}); + } + + protected static final HashMap BROWSE_HEADER_COLUMN_CASES = new HashMap(); + protected static final String[] BROWSE_HEADER_PROJECTION_ALL; + protected static final int BROWSE_HEADER_CASE_ID = 0; + protected static final int BROWSE_HEADER_CASE_COUNT = 1; + protected static final int BROWSE_HEADER_CASE_NAME = 2; + protected static final int BROWSE_HEADER_CASE_DISPLAY_NAME = 3; + protected static final int BROWSE_HEADER_CASE_ICON_URI = 4; + protected static final int BROWSE_HEADER_CASE_BADGE_URI = 5; + protected static final int BROWSE_HEADER_CASE_COLOR_HINT = 6; + protected static final int BROWSE_HEADER_CASE_TEXT_COLOR_HINT = 7; + protected static final int BROWSE_HEADER_CASE_BG_IMAGE_URI = 8; + protected static final int BROWSE_HEADER_CASE_EXPAND_GROUP = 9; + protected static final int BROWSE_HEADER_CASE_WRAP = 10; + protected static final int BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH = 11; + protected static final int BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT = 12; + + static { + BROWSE_HEADER_COLUMN_CASES.put(BaseColumns._ID, BROWSE_HEADER_CASE_ID); + BROWSE_HEADER_COLUMN_CASES.put(BaseColumns._COUNT, + BROWSE_HEADER_CASE_COUNT); + BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.NAME, + BROWSE_HEADER_CASE_NAME); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.DISPLAY_NAME, + BROWSE_HEADER_CASE_DISPLAY_NAME); + BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.ICON_URI, + BROWSE_HEADER_CASE_ICON_URI); + BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.BADGE_URI, + BROWSE_HEADER_CASE_BADGE_URI); + BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.COLOR_HINT, + BROWSE_HEADER_CASE_COLOR_HINT); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.TEXT_COLOR_HINT, + BROWSE_HEADER_CASE_TEXT_COLOR_HINT); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.BG_IMAGE_URI, + BROWSE_HEADER_CASE_BG_IMAGE_URI); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.EXPAND_GROUP, + BROWSE_HEADER_CASE_EXPAND_GROUP); + BROWSE_HEADER_COLUMN_CASES.put(CanvasContract.BrowseHeaders.WRAP_ITEMS, + BROWSE_HEADER_CASE_WRAP); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.DEFAULT_ITEM_WIDTH, + BROWSE_HEADER_CASE_DEFAULT_ITEM_WIDTH); + BROWSE_HEADER_COLUMN_CASES.put( + CanvasContract.BrowseHeaders.DEFAULT_ITEM_HEIGHT, + BROWSE_HEADER_CASE_DEFAULT_ITEM_HEIGHT); + + BROWSE_HEADER_PROJECTION_ALL = BROWSE_HEADER_COLUMN_CASES.keySet() + .toArray(new String[] {}); + } + + protected static final HashMap BROWSE_COLUMN_CASES = new HashMap(); + protected static final String[] BROWSE_PROJECTION_ALL; + protected static final int BROWSE_CASE_ID = 0; + protected static final int BROWSE_CASE_COUNT = 1; + protected static final int BROWSE_CASE_PARENT_ID = 2; + protected static final int BROWSE_CASE_DISPLAY_NAME = 3; + protected static final int BROWSE_CASE_DISPLAY_DESCRIPTION = 4; + protected static final int BROWSE_CASE_IMAGE_URI = 5; + protected static final int BROWSE_CASE_WIDTH = 6; + protected static final int BROWSE_CASE_HEIGHT = 7; + protected static final int BROWSE_CASE_INTENT_URI = 8; + + static { + BROWSE_COLUMN_CASES.put(BaseColumns._ID, BROWSE_CASE_ID); + BROWSE_COLUMN_CASES.put(BaseColumns._COUNT, BROWSE_CASE_COUNT); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.PARENT_ID, + BROWSE_CASE_PARENT_ID); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.DISPLAY_NAME, + BROWSE_CASE_DISPLAY_NAME); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.DISPLAY_DESCRIPTION, + BROWSE_CASE_DISPLAY_DESCRIPTION); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.IMAGE_URI, + BROWSE_CASE_IMAGE_URI); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.WIDTH, + BROWSE_CASE_WIDTH); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.HEIGHT, + BROWSE_CASE_HEIGHT); + BROWSE_COLUMN_CASES.put(CanvasContract.BrowseItems.INTENT_URI, + BROWSE_CASE_INTENT_URI); + + BROWSE_PROJECTION_ALL = BROWSE_COLUMN_CASES.keySet().toArray( + new String[] {}); + } + + // *************************************************** + // Configuration stuff + // *************************************************** + + // The max clusters that we'll return for a single launcher + protected static final int MAX_CLUSTER_SIZE = 3; + // The max amount of items we'll return for a cluster + protected static final int MAX_CLUSTER_ITEM_SIZE = 10; + protected static final Integer CACHE_TIME_MS = 1 * 1000; + + private ArrayList mClusters = new ArrayList( + MAX_CLUSTER_SIZE); + + @Override + public Cursor query(Uri uri, String[] projection, String selection, + String[] selectionArgs, String sortOrder) { + long identity = Binder.clearCallingIdentity(); + try { + MatrixCursor c; + int match = sUriMatcher.match(uri); + switch (match) { + case LAUNCHER: + if (projection == null) { + projection = LAUNCHER_PROJECTION_ALL; + } + c = new MatrixCursor(projection); + buildClusters(projection, c); + break; + case LAUNCHER_ITEMS: + if (projection == null) { + projection = CLUSTER_PROJECTION_ALL; + } + c = new MatrixCursor(projection); + buildMultiCluster(projection, c, uri); + break; + case LAUNCHER_ITEM_ID: + if (projection == null) { + projection = CLUSTER_PROJECTION_ALL; + } + c = new MatrixCursor(projection); + buildSingleCluster(projection, c, uri); + break; + case BROWSE_HEADERS: + if (projection == null) { + projection = BROWSE_HEADER_PROJECTION_ALL; + } + c = new MatrixCursor(projection); + buildBrowseHeaders(projection, c); + break; + case BROWSE: + if (projection == null) { + projection = BROWSE_PROJECTION_ALL; + } + c = new MatrixCursor(projection); + buildBrowseRow(projection, c, uri); + break; + default: + c = new MatrixCursor(new String[] { BaseColumns._ID }); + break; + } + return c; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + private void loadClustersIfEmpty() { + if (mClusters.size() > 0) { + return; + } + loadClusters(mClusters); + } + + private void buildClusters(String[] projection, MatrixCursor c) { + mClusters.clear(); + loadClustersIfEmpty(); + + int clusterCount = mClusters.size(); + for (Cluster cluster : mClusters) { + + Object[] row = new Object[projection.length]; + long id = cluster.getId(); + for (int j = 0; j < projection.length; j++) { + if (!LAUNCHER_COLUMN_CASES.containsKey(projection[j])) { + continue; + } + int column = LAUNCHER_COLUMN_CASES.get(projection[j]); + Object obj = null; + switch (column) { + case LAUNCHER_CASE_ID: + obj = id; + break; + case LAUNCHER_CASE_COUNT: + obj = clusterCount; + break; + case LAUNCHER_CASE_NAME: + obj = cluster.getName(); + break; + case LAUNCHER_CASE_IMPORTANCE: + obj = cluster.getImportance(); + break; + case LAUNCHER_CASE_DISPLAY_NAME: + obj = cluster.getDisplayName(); + break; + case LAUNCHER_CASE_VISIBLE_COUNT: + obj = cluster.getVisibleCount(); + break; + case LAUNCHER_CASE_CACHE_TIME: + obj = cluster.getCacheTimeMs(); + break; + case LAUNCHER_CASE_INTENT_URI: + obj = cluster.getIntent().toUri(Intent.URI_INTENT_SCHEME); + break; + case LAUNCHER_CASE_CROP_ALLOWED: + obj = cluster.isImageCropAllowed(); + break; + } + row[j] = obj; + } + c.addRow(row); + } + } + + private void buildMultiCluster(String[] projection, MatrixCursor c, Uri uri) { + for (int index = 0; index < mClusters.size(); ++index) { + buildSingleCluster(projection, c, + uri.buildUpon().appendPath(String.valueOf(index)).build()); + } + } + + private void buildSingleCluster(String[] projection, MatrixCursor c, Uri uri) { + loadClustersIfEmpty(); + + int parentId = Integer.parseInt(uri.getLastPathSegment()); + + Cluster cluster = mClusters.get(parentId); + int numItems = Math.min(cluster.getItemCount(), MAX_CLUSTER_ITEM_SIZE); + for (int i = 0; i < numItems; i++) { + Cluster.ClusterItem item = cluster.getItem(i); + Object[] row = new Object[projection.length]; + + for (int j = 0; j < projection.length; j++) { + if (!CLUSTER_COLUMN_CASES.containsKey(projection[j])) { + continue; + } + int column = CLUSTER_COLUMN_CASES.get(projection[j]); + switch (column) { + case CLUSTER_CASE_ID: + row[j] = i; + break; + case CLUSTER_CASE_COUNT: + row[j] = numItems; + break; + case CLUSTER_CASE_PARENT_ID: + row[j] = parentId; + break; + case CLUSTER_CASE_IMAGE_URI: + row[j] = item.getImageUri(); + break; + } + } + c.addRow(row); + } + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + throw new UnsupportedOperationException("Insert not supported"); + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + throw new UnsupportedOperationException("Delete not supported"); + } + + @Override + public int update(Uri uri, ContentValues values, String selection, + String[] selectionArgs) { + throw new UnsupportedOperationException("Update not supported"); + } + + protected abstract void loadClusters(List clusters); + + protected abstract void buildBrowseRow(String[] projection, MatrixCursor c, + Uri uri); + + protected abstract void buildBrowseHeaders(String[] projection, + MatrixCursor c); +} -- 2.11.0