summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAngus Kong <shkong@google.com>2013-08-07 14:52:56 -0700
committerAngus Kong <shkong@google.com>2013-08-07 14:57:07 -0700
commitbd26069d391830856c57c2141cd2efbc8423d871 (patch)
tree4608c69639ef9c9aacf8ad4902541cb6b453a2f7
parent764b07e6d5143b09c6f1bdd5504a89b81f7a7e74 (diff)
downloadandroid_packages_apps_Snap-bd26069d391830856c57c2141cd2efbc8423d871.tar.gz
android_packages_apps_Snap-bd26069d391830856c57c2141cd2efbc8423d871.tar.bz2
android_packages_apps_Snap-bd26069d391830856c57c2141cd2efbc8423d871.zip
Refactor data/LocalData.
Make the design more easily understood. Change-Id: I4f7dbe7d3f0a0534c13996b773f1767997848746
-rw-r--r--src/com/android/camera/CameraActivity.java3
-rw-r--r--src/com/android/camera/data/CameraDataAdapter.java32
-rw-r--r--src/com/android/camera/data/CameraPreviewData.java2
-rw-r--r--src/com/android/camera/data/LocalData.java697
-rw-r--r--src/com/android/camera/data/LocalMediaData.java600
-rw-r--r--src/com/android/camera/data/SimpleViewData.java143
6 files changed, 764 insertions, 713 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 57da90e60..508dfea34 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -49,6 +49,7 @@ import com.android.camera.data.FixedFirstDataAdapter;
import com.android.camera.data.FixedLastDataAdapter;
import com.android.camera.data.LocalData;
import com.android.camera.data.LocalDataAdapter;
+import com.android.camera.data.SimpleViewData;
import com.android.camera.support.common.ApiHelper;
import com.android.camera.ui.CameraSwitcher;
import com.android.camera.ui.CameraSwitcher.CameraSwitchListener;
@@ -388,7 +389,7 @@ public class CameraActivity extends Activity
R.layout.secure_album_placeholder, null);
mDataAdapter = new FixedLastDataAdapter(
mWrappedDataAdapter,
- new LocalData.LocalViewData(
+ new SimpleViewData(
v,
v.getDrawable().getIntrinsicWidth(),
v.getDrawable().getIntrinsicHeight(),
diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
index aaf5ebe59..b125bdc2e 100644
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ b/src/com/android/camera/data/CameraDataAdapter.java
@@ -146,14 +146,14 @@ public class CameraDataAdapter implements LocalDataAdapter {
@Override
public void addNewVideo(ContentResolver cr, Uri uri) {
Cursor c = cr.query(uri,
- LocalData.Video.QUERY_PROJECTION,
+ LocalMediaData.VideoData.QUERY_PROJECTION,
MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Video.QUERY_ORDER);
+ LocalMediaData.VideoData.QUERY_ORDER);
if (c == null || !c.moveToFirst()) {
return;
}
int pos = findDataByContentUri(uri);
- LocalData.Video newData = LocalData.Video.buildFromCursor(c);
+ LocalMediaData.VideoData newData = LocalMediaData.VideoData.buildFromCursor(c);
if (pos != -1) {
// A duplicate one, just do a substitute.
updateData(pos, newData);
@@ -167,14 +167,14 @@ public class CameraDataAdapter implements LocalDataAdapter {
@Override
public void addNewPhoto(ContentResolver cr, Uri uri) {
Cursor c = cr.query(uri,
- LocalData.Photo.QUERY_PROJECTION,
+ LocalMediaData.PhotoData.QUERY_PROJECTION,
MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Photo.QUERY_ORDER);
+ LocalMediaData.PhotoData.QUERY_ORDER);
if (c == null || !c.moveToFirst()) {
return;
}
int pos = findDataByContentUri(uri);
- LocalData.Photo newData = LocalData.Photo.buildFromCursor(c);
+ LocalMediaData.PhotoData newData = LocalMediaData.PhotoData.buildFromCursor(c);
if (pos != -1) {
// a duplicate one, just do a substitute.
Log.v(TAG, "found duplicate photo");
@@ -288,19 +288,19 @@ public class CameraDataAdapter implements LocalDataAdapter {
List<LocalData> l = new ArrayList<LocalData>();
// Photos
Cursor c = resolver[0].query(
- LocalData.Photo.CONTENT_URI,
- LocalData.Photo.QUERY_PROJECTION,
+ LocalMediaData.PhotoData.CONTENT_URI,
+ LocalMediaData.PhotoData.QUERY_PROJECTION,
MediaStore.Images.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Photo.QUERY_ORDER);
+ LocalMediaData.PhotoData.QUERY_ORDER);
if (c != null && c.moveToFirst()) {
// build up the list.
while (true) {
- LocalData data = LocalData.Photo.buildFromCursor(c);
+ LocalData data = LocalMediaData.PhotoData.buildFromCursor(c);
if (data != null) {
l.add(data);
} else {
Log.e(TAG, "Error loading data:"
- + c.getString(LocalData.Photo.COL_DATA));
+ + c.getString(LocalMediaData.PhotoData.COL_DATA));
}
if (c.isLast()) {
break;
@@ -313,20 +313,20 @@ public class CameraDataAdapter implements LocalDataAdapter {
}
c = resolver[0].query(
- LocalData.Video.CONTENT_URI,
- LocalData.Video.QUERY_PROJECTION,
+ LocalMediaData.VideoData.CONTENT_URI,
+ LocalMediaData.VideoData.QUERY_PROJECTION,
MediaStore.Video.Media.DATA + " like ? ", CAMERA_PATH,
- LocalData.Video.QUERY_ORDER);
+ LocalMediaData.VideoData.QUERY_ORDER);
if (c != null && c.moveToFirst()) {
// build up the list.
c.moveToFirst();
while (true) {
- LocalData data = LocalData.Video.buildFromCursor(c);
+ LocalData data = LocalMediaData.VideoData.buildFromCursor(c);
if (data != null) {
l.add(data);
} else {
Log.e(TAG, "Error loading data:"
- + c.getString(LocalData.Video.COL_DATA));
+ + c.getString(LocalMediaData.VideoData.COL_DATA));
}
if (!c.isLast()) {
c.moveToNext();
diff --git a/src/com/android/camera/data/CameraPreviewData.java b/src/com/android/camera/data/CameraPreviewData.java
index 8f8e2138d..a34f5787b 100644
--- a/src/com/android/camera/data/CameraPreviewData.java
+++ b/src/com/android/camera/data/CameraPreviewData.java
@@ -23,7 +23,7 @@ import com.android.camera.ui.FilmStripView.ImageData;
/**
* A class implementing {@link LocalData} to represent a camera preview.
*/
-public class CameraPreviewData extends LocalData.LocalViewData {
+public class CameraPreviewData extends SimpleViewData {
private boolean mPreviewLocked;
diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java
index 10cf9aec6..f71abaa0c 100644
--- a/src/com/android/camera/data/LocalData.java
+++ b/src/com/android/camera/data/LocalData.java
@@ -16,38 +16,16 @@
package com.android.camera.data;
-import java.io.File;
-import java.util.Comparator;
-import java.util.Date;
-
import android.content.ContentResolver;
import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Matrix;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.media.MediaMetadataRetriever;
import android.net.Uri;
-import android.os.AsyncTask;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images.ImageColumns;
-import android.provider.MediaStore.Video.VideoColumns;
-import android.util.Log;
-import android.view.Gravity;
import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import com.android.camera.Util;
-import com.android.camera.data.PanoramaMetadataLoader.PanoramaMetadataCallback;
import com.android.camera.ui.FilmStripView;
-import com.android.camera.util.PhotoSphereHelper.PanoramaMetadata;
import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
-import com.android.camera2.R;
+
+import java.util.Comparator;
/**
* An abstract interface that represents the local media data. Also implements
@@ -147,676 +125,5 @@ public interface LocalData extends FilmStripView.ImageData {
}
}
- // Implementations below.
-
- /**
- * A base class for all the local media files. The bitmap is loaded in
- * background thread. Subclasses should implement their own background
- * loading thread by sub-classing BitmapLoadTask and overriding
- * doInBackground() to return a bitmap.
- */
- abstract static class LocalMediaData implements LocalData {
- protected long id;
- protected String title;
- protected String mimeType;
- protected long dateTaken;
- protected long dateModified;
- protected String path;
- // width and height should be adjusted according to orientation.
- protected int width;
- protected int height;
-
- /** The panorama metadata information of this media data. */
- private PanoramaMetadata mPanoramaMetadata;
-
- /** Used to load photo sphere metadata from image files. */
- private PanoramaMetadataLoader mPanoramaMetadataLoader = null;
-
- // true if this data has a corresponding visible view.
- protected Boolean mUsing = false;
-
- @Override
- public long getDateTaken() {
- return dateTaken;
- }
-
- @Override
- public long getDateModified() {
- return dateModified;
- }
-
- @Override
- public String getTitle() {
- return new String(title);
- }
-
- @Override
- public int getWidth() {
- return width;
- }
-
- @Override
- public int getHeight() {
- return height;
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean delete(Context ctx) {
- File f = new File(path);
- return f.delete();
- }
-
- @Override
- public void viewPhotoSphere(PanoramaViewHelper helper) {
- helper.showPanorama(getContentUri());
- }
-
- @Override
- public void isPhotoSphere(Context context, final PanoramaSupportCallback callback) {
- // If we already have metadata, use it.
- if (mPanoramaMetadata != null) {
- callback.panoramaInfoAvailable(mPanoramaMetadata.mUsePanoramaViewer,
- mPanoramaMetadata.mIsPanorama360);
- }
-
- // Otherwise prepare a loader, if we don't have one already.
- if (mPanoramaMetadataLoader == null) {
- mPanoramaMetadataLoader = new PanoramaMetadataLoader(getContentUri());
- }
-
- // Load the metadata asynchronously.
- mPanoramaMetadataLoader.getPanoramaMetadata(context, new PanoramaMetadataCallback() {
- @Override
- public void onPanoramaMetadataLoaded(PanoramaMetadata metadata) {
- // Store the metadata and remove the loader to free up space.
- mPanoramaMetadata = metadata;
- mPanoramaMetadataLoader = null;
- callback.panoramaInfoAvailable(metadata.mUsePanoramaViewer,
- metadata.mIsPanorama360);
- }
- });
- }
-
- @Override
- public void onFullScreen(boolean fullScreen) {
- // do nothing.
- }
-
- @Override
- public boolean canSwipeInFullScreen() {
- return true;
- }
-
- protected ImageView fillImageView(Context ctx, ImageView v,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
- v.setScaleType(ImageView.ScaleType.FIT_XY);
- v.setImageDrawable(placeHolder);
-
- BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight);
- task.execute();
- return v;
- }
-
- @Override
- public View getView(Context ctx,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
- return fillImageView(ctx, new ImageView(ctx),
- decodeWidth, decodeHeight, placeHolder);
- }
-
- @Override
- public void prepare() {
- synchronized (mUsing) {
- mUsing = true;
- }
- }
-
- @Override
- public void recycle() {
- synchronized (mUsing) {
- mUsing = false;
- }
- }
-
- protected boolean isUsing() {
- synchronized (mUsing) {
- return mUsing;
- }
- }
-
- @Override
- public abstract int getType();
-
- protected abstract BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight);
-
- /**
- * An AsyncTask class that loads the bitmap in the background thread.
- * Sub-classes should implement their own "protected Bitmap doInBackground(Void... )"
- */
- protected abstract class BitmapLoadTask extends AsyncTask<Void, Void, Bitmap> {
- protected ImageView mView;
-
- protected BitmapLoadTask(ImageView v) {
- mView = v;
- }
-
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- if (!isUsing()) return;
- if (bitmap == null) {
- Log.e(TAG, "Failed decoding bitmap for file:" + path);
- return;
- }
- BitmapDrawable d = new BitmapDrawable(bitmap);
- mView.setScaleType(ImageView.ScaleType.FIT_XY);
- mView.setImageDrawable(d);
- }
- }
- }
-
- static class Photo extends LocalMediaData {
- public static final int COL_ID = 0;
- public static final int COL_TITLE = 1;
- public static final int COL_MIME_TYPE = 2;
- public static final int COL_DATE_TAKEN = 3;
- public static final int COL_DATE_MODIFIED = 4;
- public static final int COL_DATA = 5;
- public static final int COL_ORIENTATION = 6;
- public static final int COL_WIDTH = 7;
- public static final int COL_HEIGHT = 8;
-
- static final Uri CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-
- static final String QUERY_ORDER = ImageColumns.DATE_TAKEN + " DESC, "
- + ImageColumns._ID + " DESC";
- /**
- * These values should be kept in sync with column IDs (COL_*) above.
- */
- static final String[] QUERY_PROJECTION = {
- ImageColumns._ID, // 0, int
- ImageColumns.TITLE, // 1, string
- ImageColumns.MIME_TYPE, // 2, string
- ImageColumns.DATE_TAKEN, // 3, int
- ImageColumns.DATE_MODIFIED, // 4, int
- ImageColumns.DATA, // 5, string
- ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270
- ImageColumns.WIDTH, // 7, int
- ImageColumns.HEIGHT, // 8, int
- };
-
- private static final int mSupportedUIActions =
- FilmStripView.ImageData.ACTION_DEMOTE
- | FilmStripView.ImageData.ACTION_PROMOTE;
- private static final int mSupportedDataActions =
- LocalData.ACTION_DELETE;
-
- /** 32K buffer. */
- private static final byte[] DECODE_TEMP_STORAGE = new byte[32 * 1024];
-
- /** from MediaStore, can only be 0, 90, 180, 270 */
- public int orientation;
-
- static Photo buildFromCursor(Cursor c) {
- Photo d = new Photo();
- d.id = c.getLong(COL_ID);
- d.title = c.getString(COL_TITLE);
- d.mimeType = c.getString(COL_MIME_TYPE);
- d.dateTaken = c.getLong(COL_DATE_TAKEN);
- d.dateModified = c.getLong(COL_DATE_MODIFIED);
- d.path = c.getString(COL_DATA);
- d.orientation = c.getInt(COL_ORIENTATION);
- d.width = c.getInt(COL_WIDTH);
- d.height = c.getInt(COL_HEIGHT);
- if (d.width <= 0 || d.height <= 0) {
- Log.w(TAG, "Warning! zero dimension for "
- + d.path + ":" + d.width + "x" + d.height);
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(d.path, opts);
- if (opts.outWidth != -1 && opts.outHeight != -1) {
- d.width = opts.outWidth;
- d.height = opts.outHeight;
- } else {
- Log.w(TAG, "Warning! dimension decode failed for " + d.path);
- Bitmap b = BitmapFactory.decodeFile(d.path);
- if (b == null) {
- return null;
- }
- d.width = b.getWidth();
- d.height = b.getHeight();
- }
- }
- if (d.orientation == 90 || d.orientation == 270) {
- int b = d.width;
- d.width = d.height;
- d.height = b;
- }
- return d;
- }
-
- @Override
- public String toString() {
- return "Photo:" + ",data=" + path + ",mimeType=" + mimeType
- + "," + width + "x" + height + ",orientation=" + orientation
- + ",date=" + new Date(dateTaken);
- }
-
- @Override
- public int getType() {
- return TYPE_PHOTO;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return ((action & mSupportedUIActions) == action);
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return ((action & mSupportedDataActions) == action);
- }
-
- @Override
- public boolean delete(Context c) {
- ContentResolver cr = c.getContentResolver();
- cr.delete(CONTENT_URI, ImageColumns._ID + "=" + id, null);
- return super.delete(c);
- }
-
- @Override
- public Uri getContentUri() {
- Uri baseUri = CONTENT_URI;
- return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- Cursor c = resolver.query(
- getContentUri(), QUERY_PROJECTION, null, null, null);
- if (c == null || !c.moveToFirst()) {
- return false;
- }
- Photo newData = buildFromCursor(c);
- id = newData.id;
- title = newData.title;
- mimeType = newData.mimeType;
- dateTaken = newData.dateTaken;
- dateModified = newData.dateModified;
- path = newData.path;
- orientation = newData.orientation;
- width = newData.width;
- height = newData.height;
- return true;
- }
-
- @Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight) {
- return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight);
- }
-
- private final class PhotoBitmapLoadTask extends BitmapLoadTask {
- private int mDecodeWidth;
- private int mDecodeHeight;
-
- public PhotoBitmapLoadTask(ImageView v, int decodeWidth, int decodeHeight) {
- super(v);
- mDecodeWidth = decodeWidth;
- mDecodeHeight = decodeHeight;
- }
-
- @Override
- protected Bitmap doInBackground(Void... v) {
- BitmapFactory.Options opts = null;
- Bitmap b;
- int sample = 1;
- while (mDecodeWidth * sample < width
- || mDecodeHeight * sample < height) {
- sample *= 2;
- }
- opts = new BitmapFactory.Options();
- opts.inSampleSize = sample;
- opts.inTempStorage = DECODE_TEMP_STORAGE;
- if (isCancelled() || !isUsing()) {
- return null;
- }
- b = BitmapFactory.decodeFile(path, opts);
- if (orientation != 0) {
- if (isCancelled() || !isUsing()) {
- return null;
- }
- Matrix m = new Matrix();
- m.setRotate(orientation);
- b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
- }
- return b;
- }
- }
- }
-
- static class Video extends LocalMediaData {
- public static final int COL_ID = 0;
- public static final int COL_TITLE = 1;
- public static final int COL_MIME_TYPE = 2;
- public static final int COL_DATE_TAKEN = 3;
- public static final int COL_DATE_MODIFIED = 4;
- public static final int COL_DATA = 5;
- public static final int COL_WIDTH = 6;
- public static final int COL_HEIGHT = 7;
- public static final int COL_RESOLUTION = 8;
-
- static final Uri CONTENT_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
-
- private static final int mSupportedUIActions =
- FilmStripView.ImageData.ACTION_DEMOTE
- | FilmStripView.ImageData.ACTION_PROMOTE;
- private static final int mSupportedDataActions =
- LocalData.ACTION_DELETE
- | LocalData.ACTION_PLAY;
-
- static final String QUERY_ORDER = VideoColumns.DATE_TAKEN + " DESC, "
- + VideoColumns._ID + " DESC";
- /**
- * These values should be kept in sync with column IDs (COL_*) above.
- */
- static final String[] QUERY_PROJECTION = {
- VideoColumns._ID, // 0, int
- VideoColumns.TITLE, // 1, string
- VideoColumns.MIME_TYPE, // 2, string
- VideoColumns.DATE_TAKEN, // 3, int
- VideoColumns.DATE_MODIFIED, // 4, int
- VideoColumns.DATA, // 5, string
- VideoColumns.WIDTH, // 6, int
- VideoColumns.HEIGHT, // 7, int
- VideoColumns.RESOLUTION // 8, string
- };
-
- private Uri mPlayUri;
-
- static Video buildFromCursor(Cursor c) {
- Video d = new Video();
- d.id = c.getLong(COL_ID);
- d.title = c.getString(COL_TITLE);
- d.mimeType = c.getString(COL_MIME_TYPE);
- d.dateTaken = c.getLong(COL_DATE_TAKEN);
- d.dateModified = c.getLong(COL_DATE_MODIFIED);
- d.path = c.getString(COL_DATA);
- d.width = c.getInt(COL_WIDTH);
- d.height = c.getInt(COL_HEIGHT);
- d.mPlayUri = d.getContentUri();
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(d.path);
- String rotation = retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
- if (d.width == 0 || d.height == 0) {
- d.width = Integer.parseInt(retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
- d.height = Integer.parseInt(retriever.extractMetadata(
- MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
- }
- retriever.release();
- if (rotation != null
- && (rotation.equals("90") || rotation.equals("270"))) {
- int b = d.width;
- d.width = d.height;
- d.height = b;
- }
- return d;
- }
-
- @Override
- public String toString() {
- return "Video:" + ",data=" + path + ",mimeType=" + mimeType
- + "," + width + "x" + height + ",date=" + new Date(dateTaken);
- }
-
- @Override
- public int getType() {
- return TYPE_PHOTO;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return ((action & mSupportedUIActions) == action);
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return ((action & mSupportedDataActions) == action);
- }
-
- @Override
- public boolean delete(Context ctx) {
- ContentResolver cr = ctx.getContentResolver();
- cr.delete(CONTENT_URI, VideoColumns._ID + "=" + id, null);
- return super.delete(ctx);
- }
-
- @Override
- public Uri getContentUri() {
- Uri baseUri = CONTENT_URI;
- return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- Cursor c = resolver.query(
- getContentUri(), QUERY_PROJECTION, null, null, null);
- if (c == null && !c.moveToFirst()) {
- return false;
- }
- Video newData = buildFromCursor(c);
- id = newData.id;
- title = newData.title;
- mimeType = newData.mimeType;
- dateTaken = newData.dateTaken;
- dateModified = newData.dateModified;
- path = newData.path;
- width = newData.width;
- height = newData.height;
- mPlayUri = newData.mPlayUri;
- return true;
- }
-
- @Override
- public View getView(final Context ctx,
- int decodeWidth, int decodeHeight, Drawable placeHolder) {
-
- // ImageView for the bitmap.
- ImageView iv = new ImageView(ctx);
- iv.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
- fillImageView(ctx, iv, decodeWidth, decodeHeight, placeHolder);
-
- // ImageView for the play icon.
- ImageView icon = new ImageView(ctx);
- icon.setImageResource(R.drawable.ic_control_play);
- icon.setScaleType(ImageView.ScaleType.CENTER);
- icon.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT,
- ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
- icon.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Util.playVideo(ctx, mPlayUri, title);
- }
- });
-
- FrameLayout f = new FrameLayout(ctx);
- f.addView(iv);
- f.addView(icon);
- return f;
- }
-
- @Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight) {
- return new VideoBitmapLoadTask(v);
- }
-
- private final class VideoBitmapLoadTask extends BitmapLoadTask {
-
- public VideoBitmapLoadTask(ImageView v) {
- super(v);
- }
-
- @Override
- protected Bitmap doInBackground(Void... v) {
- if (isCancelled() || !isUsing()) {
- return null;
- }
- android.media.MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- retriever.setDataSource(path);
- byte[] data = retriever.getEmbeddedPicture();
- Bitmap bitmap = null;
- if (isCancelled() || !isUsing()) {
- retriever.release();
- return null;
- }
- if (data != null) {
- bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- if (bitmap == null) {
- bitmap = retriever.getFrameAtTime();
- }
- retriever.release();
- return bitmap;
- }
- }
- }
-
- /**
- * A LocalData that does nothing but only shows a view.
- */
- public static class LocalViewData implements LocalData {
- private int mWidth;
- private int mHeight;
- private View mView;
- private long mDateTaken;
- private long mDateModified;
-
- public LocalViewData(View v,
- int width, int height,
- int dateTaken, int dateModified) {
- mView = v;
- mWidth = width;
- mHeight = height;
- mDateTaken = dateTaken;
- mDateModified = dateModified;
- }
-
- @Override
- public long getDateTaken() {
- return mDateTaken;
- }
-
- @Override
- public long getDateModified() {
- return mDateModified;
- }
-
- @Override
- public String getTitle() {
- return "";
- }
-
- @Override
- public int getWidth() {
- return mWidth;
- }
-
- @Override
- public int getHeight() {
- return mHeight;
- }
-
- @Override
- public int getType() {
- return FilmStripView.ImageData.TYPE_PHOTO;
- }
-
- @Override
- public String getPath() {
- return "";
- }
-
- @Override
- public Uri getContentUri() {
- return Uri.EMPTY;
- }
-
- @Override
- public boolean refresh(ContentResolver resolver) {
- return false;
- }
-
- @Override
- public boolean isUIActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean isDataActionSupported(int action) {
- return false;
- }
-
- @Override
- public boolean delete(Context c) {
- return false;
- }
-
- @Override
- public View getView(Context c, int width, int height, Drawable placeHolder) {
- return mView;
- }
-
- @Override
- public void prepare() {
- // do nothing.
- }
-
- @Override
- public void recycle() {
- // do nothing.
- }
-
- @Override
- public void isPhotoSphere(Context context, PanoramaSupportCallback callback) {
- // Not a photo sphere panorama.
- callback.panoramaInfoAvailable(false, false);
- }
-
- @Override
- public void viewPhotoSphere(PanoramaViewHelper helper) {
- // do nothing.
- }
-
- @Override
- public void onFullScreen(boolean fullScreen) {
- // do nothing.
- }
-
- @Override
- public boolean canSwipeInFullScreen() {
- return true;
- }
- }
}
diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java
new file mode 100644
index 000000000..d80862cad
--- /dev/null
+++ b/src/com/android/camera/data/LocalMediaData.java
@@ -0,0 +1,600 @@
+/*
+ * 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.camera.data;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.media.MediaMetadataRetriever;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.camera.Util;
+import com.android.camera.ui.FilmStripView;
+import com.android.camera.util.PhotoSphereHelper;
+import com.android.camera2.R;
+
+import java.io.File;
+import java.util.Date;
+
+/**
+ * A base class for all the local media files. The bitmap is loaded in
+ * background thread. Subclasses should implement their own background
+ * loading thread by sub-classing BitmapLoadTask and overriding
+ * doInBackground() to return a bitmap.
+ */
+public abstract class LocalMediaData implements LocalData {
+ protected long id;
+ protected String title;
+ protected String mimeType;
+ protected long dateTaken;
+ protected long dateModified;
+ protected String path;
+ // width and height should be adjusted according to orientation.
+ protected int width;
+ protected int height;
+
+ /** The panorama metadata information of this media data. */
+ private PhotoSphereHelper.PanoramaMetadata mPanoramaMetadata;
+
+ /** Used to load photo sphere metadata from image files. */
+ private PanoramaMetadataLoader mPanoramaMetadataLoader = null;
+
+ // true if this data has a corresponding visible view.
+ protected Boolean mUsing = false;
+
+ @Override
+ public long getDateTaken() {
+ return dateTaken;
+ }
+
+ @Override
+ public long getDateModified() {
+ return dateModified;
+ }
+
+ @Override
+ public String getTitle() {
+ return new String(title);
+ }
+
+ @Override
+ public int getWidth() {
+ return width;
+ }
+
+ @Override
+ public int getHeight() {
+ return height;
+ }
+
+ @Override
+ public String getPath() {
+ return path;
+ }
+
+ @Override
+ public boolean isUIActionSupported(int action) {
+ return false;
+ }
+
+ @Override
+ public boolean isDataActionSupported(int action) {
+ return false;
+ }
+
+ @Override
+ public boolean delete(Context ctx) {
+ File f = new File(path);
+ return f.delete();
+ }
+
+ @Override
+ public void viewPhotoSphere(PhotoSphereHelper.PanoramaViewHelper helper) {
+ helper.showPanorama(getContentUri());
+ }
+
+ @Override
+ public void isPhotoSphere(Context context, final PanoramaSupportCallback callback) {
+ // If we already have metadata, use it.
+ if (mPanoramaMetadata != null) {
+ callback.panoramaInfoAvailable(mPanoramaMetadata.mUsePanoramaViewer,
+ mPanoramaMetadata.mIsPanorama360);
+ }
+
+ // Otherwise prepare a loader, if we don't have one already.
+ if (mPanoramaMetadataLoader == null) {
+ mPanoramaMetadataLoader = new PanoramaMetadataLoader(getContentUri());
+ }
+
+ // Load the metadata asynchronously.
+ mPanoramaMetadataLoader.getPanoramaMetadata(context, new PanoramaMetadataLoader.PanoramaMetadataCallback() {
+ @Override
+ public void onPanoramaMetadataLoaded(PhotoSphereHelper.PanoramaMetadata metadata) {
+ // Store the metadata and remove the loader to free up space.
+ mPanoramaMetadata = metadata;
+ mPanoramaMetadataLoader = null;
+ callback.panoramaInfoAvailable(metadata.mUsePanoramaViewer,
+ metadata.mIsPanorama360);
+ }
+ });
+ }
+
+ @Override
+ public void onFullScreen(boolean fullScreen) {
+ // do nothing.
+ }
+
+ @Override
+ public boolean canSwipeInFullScreen() {
+ return true;
+ }
+
+ protected ImageView fillImageView(Context ctx, ImageView v,
+ int decodeWidth, int decodeHeight, Drawable placeHolder) {
+ v.setScaleType(ImageView.ScaleType.FIT_XY);
+ v.setImageDrawable(placeHolder);
+
+ BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight);
+ task.execute();
+ return v;
+ }
+
+ @Override
+ public View getView(Context ctx,
+ int decodeWidth, int decodeHeight, Drawable placeHolder) {
+ return fillImageView(ctx, new ImageView(ctx),
+ decodeWidth, decodeHeight, placeHolder);
+ }
+
+ @Override
+ public void prepare() {
+ synchronized (mUsing) {
+ mUsing = true;
+ }
+ }
+
+ @Override
+ public void recycle() {
+ synchronized (mUsing) {
+ mUsing = false;
+ }
+ }
+
+ protected boolean isUsing() {
+ synchronized (mUsing) {
+ return mUsing;
+ }
+ }
+
+ @Override
+ public abstract int getType();
+
+ protected abstract BitmapLoadTask getBitmapLoadTask(
+ ImageView v, int decodeWidth, int decodeHeight);
+
+ public static class PhotoData extends LocalMediaData {
+ private static final String TAG = "CAM_PhotoData";
+
+ public static final int COL_ID = 0;
+ public static final int COL_TITLE = 1;
+ public static final int COL_MIME_TYPE = 2;
+ public static final int COL_DATE_TAKEN = 3;
+ public static final int COL_DATE_MODIFIED = 4;
+ public static final int COL_DATA = 5;
+ public static final int COL_ORIENTATION = 6;
+ public static final int COL_WIDTH = 7;
+ public static final int COL_HEIGHT = 8;
+
+ static final Uri CONTENT_URI = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
+
+ static final String QUERY_ORDER = MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC, "
+ + MediaStore.Images.ImageColumns._ID + " DESC";
+ /**
+ * These values should be kept in sync with column IDs (COL_*) above.
+ */
+ static final String[] QUERY_PROJECTION = {
+ MediaStore.Images.ImageColumns._ID, // 0, int
+ MediaStore.Images.ImageColumns.TITLE, // 1, string
+ MediaStore.Images.ImageColumns.MIME_TYPE, // 2, string
+ MediaStore.Images.ImageColumns.DATE_TAKEN, // 3, int
+ MediaStore.Images.ImageColumns.DATE_MODIFIED, // 4, int
+ MediaStore.Images.ImageColumns.DATA, // 5, string
+ MediaStore.Images.ImageColumns.ORIENTATION, // 6, int, 0, 90, 180, 270
+ MediaStore.Images.ImageColumns.WIDTH, // 7, int
+ MediaStore.Images.ImageColumns.HEIGHT, // 8, int
+ };
+
+ private static final int mSupportedUIActions =
+ FilmStripView.ImageData.ACTION_DEMOTE
+ | FilmStripView.ImageData.ACTION_PROMOTE;
+ private static final int mSupportedDataActions =
+ LocalData.ACTION_DELETE;
+
+ /** 32K buffer. */
+ private static final byte[] DECODE_TEMP_STORAGE = new byte[32 * 1024];
+
+ /** from MediaStore, can only be 0, 90, 180, 270 */
+ public int orientation;
+
+ static PhotoData buildFromCursor(Cursor c) {
+ PhotoData d = new PhotoData();
+ d.id = c.getLong(COL_ID);
+ d.title = c.getString(COL_TITLE);
+ d.mimeType = c.getString(COL_MIME_TYPE);
+ d.dateTaken = c.getLong(COL_DATE_TAKEN);
+ d.dateModified = c.getLong(COL_DATE_MODIFIED);
+ d.path = c.getString(COL_DATA);
+ d.orientation = c.getInt(COL_ORIENTATION);
+ d.width = c.getInt(COL_WIDTH);
+ d.height = c.getInt(COL_HEIGHT);
+ if (d.width <= 0 || d.height <= 0) {
+ Log.w(TAG, "Warning! zero dimension for "
+ + d.path + ":" + d.width + "x" + d.height);
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inJustDecodeBounds = true;
+ BitmapFactory.decodeFile(d.path, opts);
+ if (opts.outWidth != -1 && opts.outHeight != -1) {
+ d.width = opts.outWidth;
+ d.height = opts.outHeight;
+ } else {
+ Log.w(TAG, "Warning! dimension decode failed for " + d.path);
+ Bitmap b = BitmapFactory.decodeFile(d.path);
+ if (b == null) {
+ return null;
+ }
+ d.width = b.getWidth();
+ d.height = b.getHeight();
+ }
+ }
+ if (d.orientation == 90 || d.orientation == 270) {
+ int b = d.width;
+ d.width = d.height;
+ d.height = b;
+ }
+ return d;
+ }
+
+ @Override
+ public String toString() {
+ return "Photo:" + ",data=" + path + ",mimeType=" + mimeType
+ + "," + width + "x" + height + ",orientation=" + orientation
+ + ",date=" + new Date(dateTaken);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_PHOTO;
+ }
+
+ @Override
+ public boolean isUIActionSupported(int action) {
+ return ((action & mSupportedUIActions) == action);
+ }
+
+ @Override
+ public boolean isDataActionSupported(int action) {
+ return ((action & mSupportedDataActions) == action);
+ }
+
+ @Override
+ public boolean delete(Context c) {
+ ContentResolver cr = c.getContentResolver();
+ cr.delete(CONTENT_URI, MediaStore.Images.ImageColumns._ID + "=" + id, null);
+ return super.delete(c);
+ }
+
+ @Override
+ public Uri getContentUri() {
+ Uri baseUri = CONTENT_URI;
+ return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
+ }
+
+ @Override
+ public boolean refresh(ContentResolver resolver) {
+ Cursor c = resolver.query(
+ getContentUri(), QUERY_PROJECTION, null, null, null);
+ if (c == null || !c.moveToFirst()) {
+ return false;
+ }
+ PhotoData newData = buildFromCursor(c);
+ id = newData.id;
+ title = newData.title;
+ mimeType = newData.mimeType;
+ dateTaken = newData.dateTaken;
+ dateModified = newData.dateModified;
+ path = newData.path;
+ orientation = newData.orientation;
+ width = newData.width;
+ height = newData.height;
+ return true;
+ }
+
+ @Override
+ protected BitmapLoadTask getBitmapLoadTask(
+ ImageView v, int decodeWidth, int decodeHeight) {
+ return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight);
+ }
+
+ private final class PhotoBitmapLoadTask extends BitmapLoadTask {
+ private int mDecodeWidth;
+ private int mDecodeHeight;
+
+ public PhotoBitmapLoadTask(ImageView v, int decodeWidth, int decodeHeight) {
+ super(v);
+ mDecodeWidth = decodeWidth;
+ mDecodeHeight = decodeHeight;
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... v) {
+ BitmapFactory.Options opts = null;
+ Bitmap b;
+ int sample = 1;
+ while (mDecodeWidth * sample < width
+ || mDecodeHeight * sample < height) {
+ sample *= 2;
+ }
+ opts = new BitmapFactory.Options();
+ opts.inSampleSize = sample;
+ opts.inTempStorage = DECODE_TEMP_STORAGE;
+ if (isCancelled() || !isUsing()) {
+ return null;
+ }
+ b = BitmapFactory.decodeFile(path, opts);
+ if (orientation != 0) {
+ if (isCancelled() || !isUsing()) {
+ return null;
+ }
+ Matrix m = new Matrix();
+ m.setRotate(orientation);
+ b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
+ }
+ return b;
+ }
+ }
+ }
+
+ public static class VideoData extends LocalMediaData {
+ public static final int COL_ID = 0;
+ public static final int COL_TITLE = 1;
+ public static final int COL_MIME_TYPE = 2;
+ public static final int COL_DATE_TAKEN = 3;
+ public static final int COL_DATE_MODIFIED = 4;
+ public static final int COL_DATA = 5;
+ public static final int COL_WIDTH = 6;
+ public static final int COL_HEIGHT = 7;
+ public static final int COL_RESOLUTION = 8;
+
+ static final Uri CONTENT_URI = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
+
+ private static final int mSupportedUIActions =
+ FilmStripView.ImageData.ACTION_DEMOTE
+ | FilmStripView.ImageData.ACTION_PROMOTE;
+ private static final int mSupportedDataActions =
+ LocalData.ACTION_DELETE
+ | LocalData.ACTION_PLAY;
+
+ static final String QUERY_ORDER = MediaStore.Video.VideoColumns.DATE_TAKEN + " DESC, "
+ + MediaStore.Video.VideoColumns._ID + " DESC";
+ /**
+ * These values should be kept in sync with column IDs (COL_*) above.
+ */
+ static final String[] QUERY_PROJECTION = {
+ MediaStore.Video.VideoColumns._ID, // 0, int
+ MediaStore.Video.VideoColumns.TITLE, // 1, string
+ MediaStore.Video.VideoColumns.MIME_TYPE, // 2, string
+ MediaStore.Video.VideoColumns.DATE_TAKEN, // 3, int
+ MediaStore.Video.VideoColumns.DATE_MODIFIED, // 4, int
+ MediaStore.Video.VideoColumns.DATA, // 5, string
+ MediaStore.Video.VideoColumns.WIDTH, // 6, int
+ MediaStore.Video.VideoColumns.HEIGHT, // 7, int
+ MediaStore.Video.VideoColumns.RESOLUTION // 8, string
+ };
+
+ private Uri mPlayUri;
+
+ static VideoData buildFromCursor(Cursor c) {
+ VideoData d = new VideoData();
+ d.id = c.getLong(COL_ID);
+ d.title = c.getString(COL_TITLE);
+ d.mimeType = c.getString(COL_MIME_TYPE);
+ d.dateTaken = c.getLong(COL_DATE_TAKEN);
+ d.dateModified = c.getLong(COL_DATE_MODIFIED);
+ d.path = c.getString(COL_DATA);
+ d.width = c.getInt(COL_WIDTH);
+ d.height = c.getInt(COL_HEIGHT);
+ d.mPlayUri = d.getContentUri();
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ retriever.setDataSource(d.path);
+ String rotation = retriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+ if (d.width == 0 || d.height == 0) {
+ d.width = Integer.parseInt(retriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
+ d.height = Integer.parseInt(retriever.extractMetadata(
+ MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
+ }
+ retriever.release();
+ if (rotation != null
+ && (rotation.equals("90") || rotation.equals("270"))) {
+ int b = d.width;
+ d.width = d.height;
+ d.height = b;
+ }
+ return d;
+ }
+
+ @Override
+ public String toString() {
+ return "Video:" + ",data=" + path + ",mimeType=" + mimeType
+ + "," + width + "x" + height + ",date=" + new Date(dateTaken);
+ }
+
+ @Override
+ public int getType() {
+ return TYPE_PHOTO;
+ }
+
+ @Override
+ public boolean isUIActionSupported(int action) {
+ return ((action & mSupportedUIActions) == action);
+ }
+
+ @Override
+ public boolean isDataActionSupported(int action) {
+ return ((action & mSupportedDataActions) == action);
+ }
+
+ @Override
+ public boolean delete(Context ctx) {
+ ContentResolver cr = ctx.getContentResolver();
+ cr.delete(CONTENT_URI, MediaStore.Video.VideoColumns._ID + "=" + id, null);
+ return super.delete(ctx);
+ }
+
+ @Override
+ public Uri getContentUri() {
+ Uri baseUri = CONTENT_URI;
+ return baseUri.buildUpon().appendPath(String.valueOf(id)).build();
+ }
+
+ @Override
+ public boolean refresh(ContentResolver resolver) {
+ Cursor c = resolver.query(
+ getContentUri(), QUERY_PROJECTION, null, null, null);
+ if (c == null && !c.moveToFirst()) {
+ return false;
+ }
+ VideoData newData = buildFromCursor(c);
+ id = newData.id;
+ title = newData.title;
+ mimeType = newData.mimeType;
+ dateTaken = newData.dateTaken;
+ dateModified = newData.dateModified;
+ path = newData.path;
+ width = newData.width;
+ height = newData.height;
+ mPlayUri = newData.mPlayUri;
+ return true;
+ }
+
+ @Override
+ public View getView(final Context ctx,
+ int decodeWidth, int decodeHeight, Drawable placeHolder) {
+
+ // ImageView for the bitmap.
+ ImageView iv = new ImageView(ctx);
+ iv.setLayoutParams(new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
+ fillImageView(ctx, iv, decodeWidth, decodeHeight, placeHolder);
+
+ // ImageView for the play icon.
+ ImageView icon = new ImageView(ctx);
+ icon.setImageResource(R.drawable.ic_control_play);
+ icon.setScaleType(ImageView.ScaleType.CENTER);
+ icon.setLayoutParams(new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.CENTER));
+ icon.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ Util.playVideo(ctx, mPlayUri, title);
+ }
+ });
+
+ FrameLayout f = new FrameLayout(ctx);
+ f.addView(iv);
+ f.addView(icon);
+ return f;
+ }
+
+ @Override
+ protected BitmapLoadTask getBitmapLoadTask(
+ ImageView v, int decodeWidth, int decodeHeight) {
+ return new VideoBitmapLoadTask(v);
+ }
+
+ private final class VideoBitmapLoadTask extends BitmapLoadTask {
+
+ public VideoBitmapLoadTask(ImageView v) {
+ super(v);
+ }
+
+ @Override
+ protected Bitmap doInBackground(Void... v) {
+ if (isCancelled() || !isUsing()) {
+ return null;
+ }
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ retriever.setDataSource(path);
+ byte[] data = retriever.getEmbeddedPicture();
+ Bitmap bitmap = null;
+ if (isCancelled() || !isUsing()) {
+ retriever.release();
+ return null;
+ }
+ if (data != null) {
+ bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+ }
+ if (bitmap == null) {
+ bitmap = retriever.getFrameAtTime();
+ }
+ retriever.release();
+ return bitmap;
+ }
+ }
+ }
+
+ /**
+ * An {@link AsyncTask} class that loads the bitmap in the background thread.
+ * Sub-classes should implement their own
+ * {@code BitmapLoadTask#doInBackground(Void...)}."
+ */
+ protected abstract class BitmapLoadTask extends AsyncTask<Void, Void, Bitmap> {
+ protected ImageView mView;
+
+ protected BitmapLoadTask(ImageView v) {
+ mView = v;
+ }
+
+ @Override
+ protected void onPostExecute(Bitmap bitmap) {
+ if (!isUsing()) return;
+ if (bitmap == null) {
+ Log.e(TAG, "Failed decoding bitmap for file:" + path);
+ return;
+ }
+ BitmapDrawable d = new BitmapDrawable(bitmap);
+ mView.setScaleType(ImageView.ScaleType.FIT_XY);
+ mView.setImageDrawable(d);
+ }
+ }
+}
diff --git a/src/com/android/camera/data/SimpleViewData.java b/src/com/android/camera/data/SimpleViewData.java
new file mode 100644
index 000000000..4d64c5360
--- /dev/null
+++ b/src/com/android/camera/data/SimpleViewData.java
@@ -0,0 +1,143 @@
+/*
+ * 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.camera.data;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.view.View;
+
+import com.android.camera.ui.FilmStripView;
+import com.android.camera.util.PhotoSphereHelper;
+
+/**
+ * A LocalData that does nothing but only shows a view.
+ */
+public class SimpleViewData implements LocalData {
+ private int mWidth;
+ private int mHeight;
+ private View mView;
+ private long mDateTaken;
+ private long mDateModified;
+
+ public SimpleViewData(
+ View v, int width, int height,
+ int dateTaken, int dateModified) {
+ mView = v;
+ mWidth = width;
+ mHeight = height;
+ mDateTaken = dateTaken;
+ mDateModified = dateModified;
+ }
+
+ @Override
+ public long getDateTaken() {
+ return mDateTaken;
+ }
+
+ @Override
+ public long getDateModified() {
+ return mDateModified;
+ }
+
+ @Override
+ public String getTitle() {
+ return "";
+ }
+
+ @Override
+ public int getWidth() {
+ return mWidth;
+ }
+
+ @Override
+ public int getHeight() {
+ return mHeight;
+ }
+
+ @Override
+ public int getType() {
+ return FilmStripView.ImageData.TYPE_PHOTO;
+ }
+
+ @Override
+ public String getPath() {
+ return "";
+ }
+
+ @Override
+ public Uri getContentUri() {
+ return Uri.EMPTY;
+ }
+
+ @Override
+ public boolean refresh(ContentResolver resolver) {
+ return false;
+ }
+
+ @Override
+ public boolean isUIActionSupported(int action) {
+ return false;
+ }
+
+ @Override
+ public boolean isDataActionSupported(int action) {
+ return false;
+ }
+
+ @Override
+ public boolean delete(Context c) {
+ return false;
+ }
+
+ @Override
+ public View getView(Context c, int width, int height, Drawable placeHolder) {
+ return mView;
+ }
+
+ @Override
+ public void prepare() {
+ // do nothing.
+ }
+
+ @Override
+ public void recycle() {
+ // do nothing.
+ }
+
+ @Override
+ public void isPhotoSphere(Context context, PanoramaSupportCallback callback) {
+ // Not a photo sphere panorama.
+ callback.panoramaInfoAvailable(false, false);
+ }
+
+ @Override
+ public void viewPhotoSphere(PhotoSphereHelper.PanoramaViewHelper helper) {
+ // do nothing.
+ }
+
+ @Override
+ public void onFullScreen(boolean fullScreen) {
+ // do nothing.
+ }
+
+ @Override
+ public boolean canSwipeInFullScreen() {
+ return true;
+ }
+}