summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcretin45 <cretin45@gmail.com>2015-09-29 16:29:29 -0700
committerMichael Bestas <mikeioannina@gmail.com>2017-01-04 22:00:39 +0200
commitc3d5c2c58485fc0789af0e178dd11b881df0f63c (patch)
treec2c989daf1d82ca64f61ecadc60b5ab7b5a095b4
parentd6162483d308b8d796d8fcec975437376c3bb868 (diff)
downloadandroid_packages_apps_Snap-c3d5c2c58485fc0789af0e178dd11b881df0f63c.zip
android_packages_apps_Snap-c3d5c2c58485fc0789af0e178dd11b881df0f63c.tar.gz
android_packages_apps_Snap-c3d5c2c58485fc0789af0e178dd11b881df0f63c.tar.bz2
CameraNext: Use Glide for async bitmap loading
This is what Camera2 code uses. Addresses SAMBAR-766 CameraNext: Fix rotation not updated The thumbnail generated by Glide is not updated when user rotate the image manually. This is because exif is rewrite using nio mmap, however there is no nio unmap available in java. Even though the file channel is closed, the rotation modification is still in buffer, when Glide tries to dtermine the orientation of the image, it still reads the old data. Use force to ensure data is sync to disk and buffer flushed. HAM-1389 Fix memory leaks Two leaks were occuring. One was an unused Parameters in AndroidCameraManagerImpl that was holding onto excess PhotoModules. The second was Glide images for video previews that were never being cleared on recycle. issue-id: CYNGNOS-2731 CameraNext: don't call Glide to load image after Camera exits There is a race condition where the filmstrip can still be trying to load a new image just as the camera exit, and Glide gets upset if it is handed a destroyed activity context to work with. So just check for that condition and go home. Change-Id: I9e76ab40d23213c7a74c26779e345207d5fd7bae Ticket-Id: CRACKLING-1068
-rw-r--r--Android.mk1
-rw-r--r--src/com/android/camera/AndroidCameraManagerImpl.java8
-rw-r--r--src/com/android/camera/CameraActivity.java15
-rwxr-xr-xsrc/com/android/camera/data/CameraDataAdapter.java11
-rw-r--r--src/com/android/camera/data/FixedFirstDataAdapter.java7
-rw-r--r--src/com/android/camera/data/FixedLastDataAdapter.java7
-rw-r--r--src/com/android/camera/data/InProgressDataWrapper.java5
-rw-r--r--src/com/android/camera/data/LocalData.java4
-rw-r--r--src/com/android/camera/data/LocalMediaData.java307
-rw-r--r--src/com/android/camera/data/SimpleViewData.java4
-rw-r--r--src/com/android/camera/exif/ExifInterface.java4
-rw-r--r--src/com/android/camera/ui/FilmStripView.java5
12 files changed, 165 insertions, 213 deletions
diff --git a/Android.mk b/Android.mk
index faf35b8..58772ca 100644
--- a/Android.mk
+++ b/Android.mk
@@ -7,6 +7,7 @@ LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v13
LOCAL_STATIC_JAVA_LIBRARIES += android-support-v4
LOCAL_STATIC_JAVA_LIBRARIES += xmp_toolkit
+LOCAL_STATIC_JAVA_LIBRARIES += glide
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_SRC_FILES += $(call all-java-files-under, src_pd)
diff --git a/src/com/android/camera/AndroidCameraManagerImpl.java b/src/com/android/camera/AndroidCameraManagerImpl.java
index 5212299..b151c19 100644
--- a/src/com/android/camera/AndroidCameraManagerImpl.java
+++ b/src/com/android/camera/AndroidCameraManagerImpl.java
@@ -106,9 +106,6 @@ class AndroidCameraManagerImpl implements CameraManager {
private CameraHandler mCameraHandler;
private android.hardware.Camera mCamera;
- // Used to retain a copy of Parameters for setting parameters.
- private Parameters mParamsToSet;
-
AndroidCameraManagerImpl() {
HandlerThread ht = new HandlerThread("Camera Handler Thread");
ht.start();
@@ -224,11 +221,6 @@ class AndroidCameraManagerImpl implements CameraManager {
if (mCamera != null) {
mParametersIsDirty = true;
-
- // Get a instance of Camera.Parameters for later use.
- if (mParamsToSet == null) {
- mParamsToSet = mCamera.getParameters();
- }
} else {
if (msg.obj != null) {
((CameraOpenErrorCallback) msg.obj).onDeviceOpenFailure(msg.arg1);
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java
index 6b1d8d1..87ebe60 100644
--- a/src/com/android/camera/CameraActivity.java
+++ b/src/com/android/camera/CameraActivity.java
@@ -116,6 +116,10 @@ import com.android.camera.util.PhotoSphereHelper;
import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper;
import com.android.camera.util.UsageStatistics;
import org.codeaurora.snapcam.R;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.GlideBuilder;
+import com.bumptech.glide.MemoryCategory;
+import com.bumptech.glide.load.engine.executor.FifoPriorityThreadPoolExecutor;
import java.io.File;
import java.io.IOException;
@@ -1539,8 +1543,7 @@ public class CameraActivity extends Activity
FilmStripView.ImageData.SIZE_FULL);
// Put a CameraPreviewData at the first position.
mWrappedDataAdapter = new FixedFirstDataAdapter(
- new CameraDataAdapter(new ColorDrawable(
- getResources().getColor(R.color.photo_placeholder))),
+ new CameraDataAdapter(R.color.photo_placeholder),
mCameraPreviewData);
mFilmStripView.setViewGap(
@@ -1610,13 +1613,17 @@ public class CameraActivity extends Activity
display.getSize(size);
int width = size.x;
int height = size.y;
-
int lower = Math.min(width, height);
-
int offset = lower * 7 / 100;
SETTING_LIST_WIDTH_1 = lower / 2 + offset;
SETTING_LIST_WIDTH_2 = lower / 2 - offset;
registerSDcardMountedReceiver();
+
+ if (!Glide.isSetup()) {
+ Glide.setup(new GlideBuilder(getApplicationContext())
+ .setResizeService(new FifoPriorityThreadPoolExecutor(2)));
+ Glide.get(getApplicationContext()).setMemoryCategory(MemoryCategory.HIGH);
+ }
}
private void setRotationAnimation() {
diff --git a/src/com/android/camera/data/CameraDataAdapter.java b/src/com/android/camera/data/CameraDataAdapter.java
index 4b810a0..7059221 100755
--- a/src/com/android/camera/data/CameraDataAdapter.java
+++ b/src/com/android/camera/data/CameraDataAdapter.java
@@ -20,7 +20,6 @@ import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
-import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.provider.MediaStore;
@@ -46,16 +45,16 @@ public class CameraDataAdapter implements LocalDataAdapter {
private LocalDataList mImages;
private Listener mListener;
- private Drawable mPlaceHolder;
+ private final int mPlaceHolderResourceId;
private int mSuggestedWidth = DEFAULT_DECODE_SIZE;
private int mSuggestedHeight = DEFAULT_DECODE_SIZE;
private LocalData mLocalDataToDelete;
- public CameraDataAdapter(Drawable placeHolder) {
+ public CameraDataAdapter(int placeholderResource) {
mImages = new LocalDataList();
- mPlaceHolder = placeHolder;
+ mPlaceHolderResourceId = placeholderResource;
}
@Override
@@ -94,14 +93,14 @@ public class CameraDataAdapter implements LocalDataAdapter {
}
@Override
- public View getView(Activity activity, int dataID) {
+ public View getView(Activity activity, int dataID, boolean inFullScreen) {
if (dataID >= mImages.size() || dataID < 0) {
return null;
}
return mImages.get(dataID).getView(
activity, mSuggestedWidth, mSuggestedHeight,
- mPlaceHolder.getConstantState().newDrawable(), this);
+ mPlaceHolderResourceId, this, inFullScreen);
}
@Override
diff --git a/src/com/android/camera/data/FixedFirstDataAdapter.java b/src/com/android/camera/data/FixedFirstDataAdapter.java
index aa20252..a210cb0 100644
--- a/src/com/android/camera/data/FixedFirstDataAdapter.java
+++ b/src/com/android/camera/data/FixedFirstDataAdapter.java
@@ -108,12 +108,13 @@ public class FixedFirstDataAdapter extends AbstractLocalDataAdapterWrapper
}
@Override
- public View getView(Activity activity, int dataID) {
+ public View getView(Activity activity, int dataID, boolean inFullScreen) {
if (dataID == 0) {
return mFirstData.getView(
- activity, mSuggestedWidth, mSuggestedHeight, null, null);
+ activity, mSuggestedWidth, mSuggestedHeight, R.color.photo_placeholder,
+ null, inFullScreen);
}
- return mAdapter.getView(activity, dataID - 1);
+ return mAdapter.getView(activity, dataID - 1, inFullScreen);
}
@Override
diff --git a/src/com/android/camera/data/FixedLastDataAdapter.java b/src/com/android/camera/data/FixedLastDataAdapter.java
index 4df0652..33fd20d 100644
--- a/src/com/android/camera/data/FixedLastDataAdapter.java
+++ b/src/com/android/camera/data/FixedLastDataAdapter.java
@@ -111,14 +111,15 @@ public class FixedLastDataAdapter extends AbstractLocalDataAdapterWrapper {
}
@Override
- public View getView(Activity activity, int dataID) {
+ public View getView(Activity activity, int dataID, boolean inFullScreen) {
int totalNumber = mAdapter.getTotalNumber();
if (dataID < totalNumber) {
- return mAdapter.getView(activity, dataID);
+ return mAdapter.getView(activity, dataID, inFullScreen);
} else if (dataID == totalNumber) {
return mLastData.getView(activity,
- mSuggestedWidth, mSuggestedHeight, null, null);
+ mSuggestedWidth, mSuggestedHeight, R.color.photo_placeholder,
+ null, inFullScreen);
}
return null;
diff --git a/src/com/android/camera/data/InProgressDataWrapper.java b/src/com/android/camera/data/InProgressDataWrapper.java
index 9ce968e..f212b69 100644
--- a/src/com/android/camera/data/InProgressDataWrapper.java
+++ b/src/com/android/camera/data/InProgressDataWrapper.java
@@ -50,8 +50,9 @@ public class InProgressDataWrapper implements LocalData {
@Override
public View getView(
Activity a, int width, int height,
- Drawable placeHolder, LocalDataAdapter adapter) {
- View v = mLocalData.getView(a, width, height, placeHolder, adapter);
+ int placeHolderResourceId, LocalDataAdapter adapter, boolean inFullScreen) {
+ View v = mLocalData.getView(a, width, height, placeHolderResourceId,
+ adapter, inFullScreen);
if (mHasProgressBar) {
// Return a framelayout with the progressbar and imageview.
diff --git a/src/com/android/camera/data/LocalData.java b/src/com/android/camera/data/LocalData.java
index da64fee..c9d518d 100644
--- a/src/com/android/camera/data/LocalData.java
+++ b/src/com/android/camera/data/LocalData.java
@@ -74,8 +74,8 @@ public interface LocalData extends FilmStripView.ImageData {
*/
public static final int LOCAL_IN_PROGRESS_DATA = 7;
- View getView(Activity a, int width, int height, Drawable placeHolder,
- LocalDataAdapter adapter);
+ View getView(Activity a, int width, int height, int placeHolderResourceId,
+ LocalDataAdapter adapter, boolean full);
/**
* Gets the date when this data is created. The returned date is also used
diff --git a/src/com/android/camera/data/LocalMediaData.java b/src/com/android/camera/data/LocalMediaData.java
index e77578b..c32d6cc 100644
--- a/src/com/android/camera/data/LocalMediaData.java
+++ b/src/com/android/camera/data/LocalMediaData.java
@@ -18,19 +18,13 @@ package com.android.camera.data;
import android.app.Activity;
import android.content.ContentResolver;
-import android.content.ContentValues;
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;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -42,6 +36,9 @@ import com.android.camera.ui.FilmStripView;
import com.android.camera.util.CameraUtil;
import com.android.camera.util.PhotoSphereHelper;
import org.codeaurora.snapcam.R;
+import com.bumptech.glide.BitmapRequestBuilder;
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.resource.bitmap.BitmapEncoder;
import java.io.File;
import java.text.DateFormat;
@@ -55,6 +52,13 @@ import java.util.Locale;
* return a bitmap.
*/
public abstract class LocalMediaData implements LocalData {
+
+ private static final int MEDIASTORE_THUMB_WIDTH = 512;
+ private static final int MEDIASTORE_THUMB_HEIGHT = 384;
+
+ // GL max texture size: keep bitmaps below this value.
+ private static final int MAXIMUM_TEXTURE_SIZE = 2048;
+
protected final long mContentId;
protected final String mTitle;
protected final String mMimeType;
@@ -68,12 +72,18 @@ public abstract class LocalMediaData implements LocalData {
protected final double mLatitude;
protected final double mLongitude;
+ protected ImageView mImageView;
+
/** The panorama metadata information of this media data. */
protected PhotoSphereHelper.PanoramaMetadata mPanoramaMetadata;
/** Used to load photo sphere metadata from image files. */
protected PanoramaMetadataLoader mPanoramaMetadataLoader = null;
+ private static final int JPEG_COMPRESS_QUALITY = 90;
+ private static final BitmapEncoder JPEG_ENCODER =
+ new BitmapEncoder(Bitmap.CompressFormat.JPEG, JPEG_COMPRESS_QUALITY);
+
/**
* Used for thumbnail loading optimization. True if this data has a
* corresponding visible view.
@@ -202,23 +212,25 @@ public abstract class LocalMediaData implements LocalData {
}
protected ImageView fillImageView(Context ctx, ImageView v,
- int decodeWidth, int decodeHeight, Drawable placeHolder,
- LocalDataAdapter adapter) {
- v.setScaleType(ImageView.ScaleType.FIT_XY);
- v.setImageDrawable(placeHolder);
-
- BitmapLoadTask task = getBitmapLoadTask(v, decodeWidth, decodeHeight,
- ctx.getContentResolver(), adapter);
- task.execute();
+ int decodeWidth, int decodeHeight, int placeHolderResourceId,
+ LocalDataAdapter adapter, boolean inFullScreen) {
+ Glide.with(ctx)
+ .loadFromMediaStore(getContentUri(), mMimeType, mDateModifiedInSeconds, 0)
+ .fitCenter()
+ .placeholder(placeHolderResourceId)
+ .into(v);
return v;
}
@Override
public View getView(Activity activity,
- int decodeWidth, int decodeHeight, Drawable placeHolder,
- LocalDataAdapter adapter) {
- return fillImageView(activity, new ImageView(activity),
- decodeWidth, decodeHeight, placeHolder, adapter);
+ int decodeWidth, int decodeHeight, int placeHolderResourceId,
+ LocalDataAdapter adapter, boolean inFullScreen) {
+
+ mImageView = new ImageView(activity);
+
+ return fillImageView(activity, mImageView,
+ decodeWidth, decodeHeight, placeHolderResourceId, adapter, inFullScreen);
}
@Override
@@ -233,6 +245,10 @@ public abstract class LocalMediaData implements LocalData {
synchronized (mUsing) {
mUsing = false;
}
+
+ if (mImageView != null) {
+ Glide.clear(mImageView);
+ }
}
@Override
@@ -280,10 +296,6 @@ public abstract class LocalMediaData implements LocalData {
@Override
public abstract int getViewType();
- protected abstract BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight,
- ContentResolver resolver, LocalDataAdapter adapter);
-
public static final class PhotoData extends LocalMediaData {
private static final String TAG = "CAM_PhotoData";
@@ -467,96 +479,63 @@ public abstract class LocalMediaData implements LocalData {
}
@Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight,
- ContentResolver resolver, LocalDataAdapter adapter) {
- return new PhotoBitmapLoadTask(v, decodeWidth, decodeHeight,
- resolver, adapter);
- }
-
- private final class PhotoBitmapLoadTask extends BitmapLoadTask {
- private final int mDecodeWidth;
- private final int mDecodeHeight;
- private final ContentResolver mResolver;
- private final LocalDataAdapter mAdapter;
-
- private boolean mNeedsRefresh;
-
- public PhotoBitmapLoadTask(ImageView v, int decodeWidth,
- int decodeHeight, ContentResolver resolver,
- LocalDataAdapter adapter) {
- super(v);
- mDecodeWidth = decodeWidth;
- mDecodeHeight = decodeHeight;
- mResolver = resolver;
- mAdapter = adapter;
- }
-
- @Override
- protected Bitmap doInBackground(Void... v) {
- int sampleSize = 1;
- if (mWidth > mDecodeWidth || mHeight > mDecodeHeight) {
- int heightRatio = Math.round((float) mHeight / (float) mDecodeHeight);
- int widthRatio = Math.round((float) mWidth / (float) mDecodeWidth);
- sampleSize = Math.max(heightRatio, widthRatio);
- }
-
- // For correctness, we need to double check the size here. The
- // good news is that decoding bounds take much less time than
- // decoding samples like < 1%.
- // TODO: better organize the decoding and sampling by using a
- // image cache.
- int decodedWidth = 0;
- int decodedHeight = 0;
- BitmapFactory.Options justBoundsOpts = new BitmapFactory.Options();
- justBoundsOpts.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(mPath, justBoundsOpts);
- if (justBoundsOpts.outWidth > 0 && justBoundsOpts.outHeight > 0) {
- decodedWidth = justBoundsOpts.outWidth;
- decodedHeight = justBoundsOpts.outHeight;
- }
-
- // If the width and height is valid and not matching the values
- // from MediaStore, then update the MediaStore. This only
- // happened when the MediaStore had been told a wrong data.
- if (decodedWidth > 0 && decodedHeight > 0 &&
- (decodedWidth != mWidth || decodedHeight != mHeight)) {
- ContentValues values = new ContentValues();
- values.put(Images.Media.WIDTH, decodedWidth);
- values.put(Images.Media.HEIGHT, decodedHeight);
- mResolver.update(getContentUri(), values, null, null);
- mNeedsRefresh = true;
- Log.w(TAG, "Uri " + getContentUri() + " has been updated with" +
- " correct size!");
- return null;
- }
+ protected ImageView fillImageView(Context context, final ImageView v, final int decodeWidth,
+ final int decodeHeight, int placeHolderResourceId, LocalDataAdapter adapter,
+ boolean inFullScreen) {
+ loadImage(context, v, decodeWidth, decodeHeight, placeHolderResourceId, inFullScreen);
+ return v;
+ }
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inSampleSize = sampleSize;
- opts.inTempStorage = DECODE_TEMP_STORAGE;
- if (isCancelled() || !isUsing()) {
- return null;
- }
- Bitmap b = BitmapFactory.decodeFile(mPath, opts);
+ private void loadImage(Context context, ImageView imageView, int decodeWidth,
+ int decodeHeight, int placeHolderResourceId, boolean inFullScreen) {
- if (mOrientation != 0 && b != null) {
- if (isCancelled() || !isUsing()) {
- return null;
- }
- Matrix m = new Matrix();
- m.setRotate(mOrientation);
- b = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
- }
- return b;
+ if (decodeWidth <= 0 || decodeHeight <=0) {
+ return;
}
- @Override
- protected void onPostExecute(Bitmap bitmap) {
- super.onPostExecute(bitmap);
- if (mNeedsRefresh && mAdapter != null) {
- mAdapter.refresh(mResolver, getContentUri());
- }
+ final int overrideWidth;
+ final int overrideHeight;
+ final BitmapRequestBuilder<Uri, Bitmap> thumbnailRequest;
+ if (inFullScreen) {
+ // Load up to the maximum size Bitmap we can render.
+ overrideWidth = Math.min(getWidth(), MAXIMUM_TEXTURE_SIZE);
+ overrideHeight = Math.min(getHeight(), MAXIMUM_TEXTURE_SIZE);
+
+ // Load two thumbnails, first the small low quality thumb from the media store,
+ // then a medium quality thumbWidth/thumbHeight image. Using two thumbnails ensures
+ // we don't flicker to grey while we load the maximum size image.
+ thumbnailRequest = loadUri(context)
+ .override(decodeWidth, decodeHeight)
+ .fitCenter()
+ .thumbnail(loadMediaStoreThumb(context));
+ } else {
+ // Load a medium quality thumbWidth/thumbHeight image.
+ overrideWidth = decodeWidth;
+ overrideHeight = decodeHeight;
+
+ // Load a single small low quality thumbnail from the media store.
+ thumbnailRequest = loadMediaStoreThumb(context);
}
+ loadUri(context)
+ .placeholder(placeHolderResourceId)
+ .fitCenter()
+ .override(overrideWidth, overrideHeight)
+ .thumbnail(thumbnailRequest)
+ .into(imageView);
+ }
+
+ /** Loads a thumbnail with a size targeted to use MediaStore.Images.Thumbnails. */
+ private BitmapRequestBuilder<Uri, Bitmap> loadMediaStoreThumb(Context context) {
+ return loadUri(context)
+ .override(MEDIASTORE_THUMB_WIDTH, MEDIASTORE_THUMB_HEIGHT);
+ }
+
+ /** Loads an image using a MediaStore Uri with our default options. */
+ private BitmapRequestBuilder<Uri, Bitmap> loadUri(Context context) {
+ return Glide.with(context)
+ .loadFromMediaStore(getContentUri(), mMimeType, mDateModifiedInSeconds, mOrientation)
+ .asBitmap()
+ .encoder(JPEG_ENCODER);
}
@Override
@@ -750,17 +729,51 @@ public abstract class LocalMediaData implements LocalData {
}
@Override
+ protected ImageView fillImageView(Context context, final ImageView v, final int decodeWidth,
+ final int decodeHeight, int placeHolderResourceId, LocalDataAdapter adapter,
+ boolean inFullScreen) {
+
+ //TODO: Figure out why these can be <= 0.
+ if (decodeWidth <= 0 || decodeHeight <=0) {
+ return v;
+ }
+
+ // band-aid over a race condition where the filmstrip is in the process
+ // of refreshing because of new media just as the camera exits
+ if ((context instanceof Activity) && ((Activity)context).isDestroyed()) {
+ Log.d(TAG, "aborted fillImageView because context was destroyed");
+ return v;
+ }
+
+ Glide.with(context)
+ .loadFromMediaStore(getContentUri(), mMimeType, mDateModifiedInSeconds, 0)
+ .asBitmap()
+ .encoder(JPEG_ENCODER)
+ .thumbnail(Glide.with(context)
+ .loadFromMediaStore(getContentUri(), mMimeType, mDateModifiedInSeconds, 0)
+ .asBitmap()
+ .encoder(JPEG_ENCODER)
+ .override(MEDIASTORE_THUMB_WIDTH, MEDIASTORE_THUMB_HEIGHT))
+ .placeholder(placeHolderResourceId)
+ .fitCenter()
+ .override(decodeWidth, decodeHeight)
+ .into(v);
+
+ return v;
+ }
+
+ @Override
public View getView(final Activity activity,
- int decodeWidth, int decodeHeight, Drawable placeHolder,
- LocalDataAdapter adapter) {
+ int decodeWidth, int decodeHeight, int placeHolderResourceId,
+ LocalDataAdapter adapter, boolean inFullScreen) {
// ImageView for the bitmap.
- ImageView iv = new ImageView(activity);
- iv.setLayoutParams(new FrameLayout.LayoutParams(
+ mImageView = new ImageView(activity);
+ mImageView.setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT, Gravity.CENTER));
- fillImageView(activity, iv, decodeWidth, decodeHeight, placeHolder,
- adapter);
+ fillImageView(activity, mImageView, decodeWidth, decodeHeight, placeHolderResourceId,
+ adapter, inFullScreen);
// ImageView for the play icon.
ImageView icon = new ImageView(activity);
@@ -777,7 +790,7 @@ public abstract class LocalMediaData implements LocalData {
});
FrameLayout f = new FrameLayout(activity);
- f.addView(iv);
+ f.addView(mImageView);
f.addView(icon);
return f;
}
@@ -788,46 +801,6 @@ public abstract class LocalMediaData implements LocalData {
}
@Override
- protected BitmapLoadTask getBitmapLoadTask(
- ImageView v, int decodeWidth, int decodeHeight,
- ContentResolver resolver, LocalDataAdapter adapter) {
- 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();
- Bitmap bitmap = null;
- try {
- retriever.setDataSource(mPath);
- byte[] data = retriever.getEmbeddedPicture();
- if (!isCancelled() && isUsing()) {
- if (data != null) {
- bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
- }
- if (bitmap == null) {
- bitmap = retriever.getFrameAtTime();
- }
- }
- } catch (IllegalArgumentException e) {
- Log.e(TAG, "MediaMetadataRetriever.setDataSource() fail:"
- + e.getMessage());
- }
- retriever.release();
- return bitmap;
- }
- }
-
- @Override
public boolean rotate90Degrees(Context context, LocalDataAdapter adapter,
int currentDataId, boolean clockwise) {
// We don't support rotation for video data.
@@ -836,30 +809,4 @@ public abstract class LocalMediaData implements LocalData {
}
}
- /**
- * 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:" + mPath);
- 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
index ba44594..18c4af6 100644
--- a/src/com/android/camera/data/SimpleViewData.java
+++ b/src/com/android/camera/data/SimpleViewData.java
@@ -120,8 +120,8 @@ public class SimpleViewData implements LocalData {
}
@Override
- public View getView(Activity activity, int width, int height, Drawable placeHolder,
- LocalDataAdapter adapter) {
+ public View getView(Activity activity, int width, int height, int placeHolderResourceId,
+ LocalDataAdapter adapter, boolean inFullScreen) {
return mView;
}
diff --git a/src/com/android/camera/exif/ExifInterface.java b/src/com/android/camera/exif/ExifInterface.java
index 0f495f2..3049d26 100644
--- a/src/com/android/camera/exif/ExifInterface.java
+++ b/src/com/android/camera/exif/ExifInterface.java
@@ -36,6 +36,7 @@ import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.FileChannel.MapMode;
+import java.nio.MappedByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -1039,11 +1040,12 @@ public class ExifInterface {
}
// Map only exif header into memory.
- ByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, exifSize);
+ MappedByteBuffer buf = file.getChannel().map(MapMode.READ_WRITE, 0, exifSize);
// Attempt to overwrite tag values without changing lengths (avoids
// file copy).
ret = rewriteExif(buf, tags);
+ buf.force();
} catch (IOException e) {
closeSilently(file);
throw e;
diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java
index 3ac0bf6..47f480e 100644
--- a/src/com/android/camera/ui/FilmStripView.java
+++ b/src/com/android/camera/ui/FilmStripView.java
@@ -281,10 +281,11 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
*
* @param activity The {@link Activity} context to create the view.
* @param dataID The ID of the image data to be presented.
+ * @param inFullScreen if the filmstrip is in fullscreen
* @return The view representing the image data. Null if unavailable or
* the {@code dataID} is out of range.
*/
- public View getView(Activity activity, int dataID);
+ public View getView(Activity activity, int dataID, boolean inFullScreen);
/**
* Returns the {@link ImageData} specified by the ID.
@@ -923,7 +924,7 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener {
return null;
}
data.prepare();
- View v = mDataAdapter.getView(mActivity, dataID);
+ View v = mDataAdapter.getView(mActivity, dataID, inFullScreen());
if (v == null) {
return null;
}