summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Jurka <mikejurka@google.com>2013-10-29 15:50:06 +0100
committerMichael Jurka <mikejurka@google.com>2013-10-29 22:50:30 +0100
commit619a180be5a67f5bcd7021d300bd35e8b5296e7f (patch)
tree950085d27748775b4295d4a1498cbd66d93af3ff
parent88400d521e9c46382d835f42c1d50235cf99b2eb (diff)
downloadandroid_packages_apps_Trebuchet-619a180be5a67f5bcd7021d300bd35e8b5296e7f.tar.gz
android_packages_apps_Trebuchet-619a180be5a67f5bcd7021d300bd35e8b5296e7f.tar.bz2
android_packages_apps_Trebuchet-619a180be5a67f5bcd7021d300bd35e8b5296e7f.zip
Make wallpaper picker/cropper more robust
- don't crash if image passed to wallpaper picker is invalid - close input streams correctly Bug: 11413915 Bug: 11380658 Bug: 11362731 Change-Id: I973e6bdc532d24a64efd6d174e89fdac626d7ee3
-rw-r--r--res/values/strings.xml8
-rw-r--r--src/com/android/launcher3/SavedWallpaperImages.java2
-rw-r--r--src/com/android/launcher3/WallpaperCropActivity.java97
-rw-r--r--src/com/android/launcher3/WallpaperPickerActivity.java74
-rw-r--r--src/com/android/photos/BitmapRegionTileSource.java109
5 files changed, 195 insertions, 95 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index cafa42442..1997c8b9a 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -30,6 +30,14 @@
<string name="folder_name"></string>
<!-- Button label on Wallpaper picker screen; user selects this button to set a specific wallpaper -->
<string name="wallpaper_instructions">Set wallpaper</string>
+ <!-- Error message when an image is selected as a wallpaper,
+ but the wallpaper picker cannot load it -->
+ <string name="image_load_fail">Coudn\'t load image</string>
+ <!-- Error message when an image is selected as a wallpaper,
+ but the wallpaper cropper cannot load it. The user will
+ usually see this when using another app and trying to set
+ an image as the wallpaper -->
+ <string name="wallpaper_load_fail">Couldn\'t load image as wallpaper</string>
<!-- Shown when wallpapers are selected in Wallpaper picker -->
<!-- String indicating how many media item(s) is(are) selected
eg. 1 selected [CHAR LIMIT=30] -->
diff --git a/src/com/android/launcher3/SavedWallpaperImages.java b/src/com/android/launcher3/SavedWallpaperImages.java
index 086d08580..58add7022 100644
--- a/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/src/com/android/launcher3/SavedWallpaperImages.java
@@ -62,7 +62,7 @@ public class SavedWallpaperImages extends BaseAdapter implements ListAdapter {
File file = new File(a.getFilesDir(), imageFilename);
BitmapRegionTileSource.FilePathBitmapSource bitmapSource =
new BitmapRegionTileSource.FilePathBitmapSource(file.getAbsolutePath(), 1024);
- a.setCropViewTileSource(bitmapSource, false, true);
+ a.setCropViewTileSource(bitmapSource, false, true, null);
}
@Override
public void onSave(WallpaperPickerActivity a) {
diff --git a/src/com/android/launcher3/WallpaperCropActivity.java b/src/com/android/launcher3/WallpaperCropActivity.java
index 29e8c972a..491316d74 100644
--- a/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/src/com/android/launcher3/WallpaperCropActivity.java
@@ -41,10 +41,12 @@ import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
+import android.widget.Toast;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.exif.ExifInterface;
import com.android.photos.BitmapRegionTileSource;
+import com.android.photos.BitmapRegionTileSource.BitmapSource;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
@@ -109,12 +111,24 @@ public class WallpaperCropActivity extends Activity {
});
// Load image in background
- setCropViewTileSource(
- new BitmapRegionTileSource.UriBitmapSource(this, imageUri, 1024), true, false);
+ final BitmapRegionTileSource.UriBitmapSource bitmapSource =
+ new BitmapRegionTileSource.UriBitmapSource(this, imageUri, 1024);
+ Runnable onLoad = new Runnable() {
+ public void run() {
+ if (bitmapSource.getLoadingState() != BitmapSource.State.LOADED) {
+ Toast.makeText(WallpaperCropActivity.this,
+ getString(R.string.wallpaper_load_fail),
+ Toast.LENGTH_LONG).show();
+ finish();
+ }
+ }
+ };
+ setCropViewTileSource(bitmapSource, true, false, onLoad);
}
- public void setCropViewTileSource(final BitmapRegionTileSource.BitmapSource bitmapSource,
- final boolean touchEnabled, final boolean moveToLeft) {
+ public void setCropViewTileSource(
+ final BitmapRegionTileSource.BitmapSource bitmapSource, final boolean touchEnabled,
+ final boolean moveToLeft, final Runnable postExecute) {
final Context context = WallpaperCropActivity.this;
final View progressView = findViewById(R.id.loading);
final AsyncTask<Void, Void, Void> loadBitmapTask = new AsyncTask<Void, Void, Void>() {
@@ -127,13 +141,18 @@ public class WallpaperCropActivity extends Activity {
protected void onPostExecute(Void arg) {
if (!isCancelled()) {
progressView.setVisibility(View.INVISIBLE);
- mCropView.setTileSource(
- new BitmapRegionTileSource(context, bitmapSource), null);
- mCropView.setTouchEnabled(touchEnabled);
- if (moveToLeft) {
- mCropView.moveToLeft();
+ if (bitmapSource.getLoadingState() == BitmapSource.State.LOADED) {
+ mCropView.setTileSource(
+ new BitmapRegionTileSource(context, bitmapSource), null);
+ mCropView.setTouchEnabled(touchEnabled);
+ if (moveToLeft) {
+ mCropView.moveToLeft();
+ }
}
}
+ if (postExecute != null) {
+ postExecute.run();
+ }
}
};
// We don't want to show the spinner every time we load an image, because that would be
@@ -235,10 +254,12 @@ public class WallpaperCropActivity extends Activity {
InputStream is = context.getContentResolver().openInputStream(uri);
BufferedInputStream bis = new BufferedInputStream(is);
ei.readExif(bis);
+ bis.close();
} else {
InputStream is = res.openRawResource(resId);
BufferedInputStream bis = new BufferedInputStream(is);
ei.readExif(bis);
+ bis.close();
}
Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
if (ori != null) {
@@ -408,7 +429,6 @@ public class WallpaperCropActivity extends Activity {
String mInFilePath;
byte[] mInImageBytes;
int mInResId = 0;
- InputStream mInStream;
RectF mCropBounds = null;
int mOutWidth, mOutHeight;
int mRotation;
@@ -481,37 +501,36 @@ public class WallpaperCropActivity extends Activity {
}
// Helper to setup input stream
- private void regenerateInputStream() {
+ private InputStream regenerateInputStream() {
if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {
Log.w(LOGTAG, "cannot read original file, no input URI, resource ID, or " +
"image byte array given");
} else {
- Utils.closeSilently(mInStream);
try {
if (mInUri != null) {
- mInStream = new BufferedInputStream(
+ return new BufferedInputStream(
mContext.getContentResolver().openInputStream(mInUri));
} else if (mInFilePath != null) {
- mInStream = mContext.openFileInput(mInFilePath);
+ return mContext.openFileInput(mInFilePath);
} else if (mInImageBytes != null) {
- mInStream = new BufferedInputStream(
- new ByteArrayInputStream(mInImageBytes));
+ return new BufferedInputStream(new ByteArrayInputStream(mInImageBytes));
} else {
- mInStream = new BufferedInputStream(
- mResources.openRawResource(mInResId));
+ return new BufferedInputStream(mResources.openRawResource(mInResId));
}
} catch (FileNotFoundException e) {
Log.w(LOGTAG, "cannot read file: " + mInUri.toString(), e);
}
}
+ return null;
}
public Point getImageBounds() {
- regenerateInputStream();
- if (mInStream != null) {
+ InputStream is = regenerateInputStream();
+ if (is != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
- BitmapFactory.decodeStream(mInStream, null, options);
+ BitmapFactory.decodeStream(is, null, options);
+ Utils.closeSilently(is);
if (options.outWidth != 0 && options.outHeight != 0) {
return new Point(options.outWidth, options.outHeight);
}
@@ -529,22 +548,26 @@ public class WallpaperCropActivity extends Activity {
public boolean cropBitmap() {
boolean failure = false;
- regenerateInputStream();
WallpaperManager wallpaperManager = null;
if (mSetWallpaper) {
wallpaperManager = WallpaperManager.getInstance(mContext.getApplicationContext());
}
- if (mSetWallpaper && mNoCrop && mInStream != null) {
+
+
+ if (mSetWallpaper && mNoCrop) {
try {
- wallpaperManager.setStream(mInStream);
+ InputStream is = regenerateInputStream();
+ if (is != null) {
+ wallpaperManager.setStream(is);
+ Utils.closeSilently(is);
+ }
} catch (IOException e) {
Log.w(LOGTAG, "cannot write stream to wallpaper", e);
failure = true;
}
return !failure;
- }
- if (mInStream != null) {
+ } else {
// Find crop bounds (scaled to original image size)
Rect roundedTrueCrop = new Rect();
Matrix rotateMatrix = new Matrix();
@@ -557,6 +580,11 @@ public class WallpaperCropActivity extends Activity {
mCropBounds = new RectF(roundedTrueCrop);
Point bounds = getImageBounds();
+ if (bounds == null) {
+ Log.w(LOGTAG, "cannot get bounds for image");
+ failure = true;
+ return false;
+ }
float[] rotatedBounds = new float[] { bounds.x, bounds.y };
rotateMatrix.mapPoints(rotatedBounds);
@@ -567,7 +595,6 @@ public class WallpaperCropActivity extends Activity {
inverseRotateMatrix.mapRect(mCropBounds);
mCropBounds.offset(bounds.x/2, bounds.y/2);
- regenerateInputStream();
}
mCropBounds.roundOut(roundedTrueCrop);
@@ -585,7 +612,14 @@ public class WallpaperCropActivity extends Activity {
// Attempt to open a region decoder
BitmapRegionDecoder decoder = null;
try {
- decoder = BitmapRegionDecoder.newInstance(mInStream, true);
+ InputStream is = regenerateInputStream();
+ if (is == null) {
+ Log.w(LOGTAG, "cannot get input stream for uri=" + mInUri.toString());
+ failure = true;
+ return false;
+ }
+ decoder = BitmapRegionDecoder.newInstance(is, false);
+ Utils.closeSilently(is);
} catch (IOException e) {
Log.w(LOGTAG, "cannot open region decoder for file: " + mInUri.toString(), e);
}
@@ -603,14 +637,15 @@ public class WallpaperCropActivity extends Activity {
if (crop == null) {
// BitmapRegionDecoder has failed, try to crop in-memory
- regenerateInputStream();
+ InputStream is = regenerateInputStream();
Bitmap fullSize = null;
- if (mInStream != null) {
+ if (is != null) {
BitmapFactory.Options options = new BitmapFactory.Options();
if (scaleDownSampleSize > 1) {
options.inSampleSize = scaleDownSampleSize;
}
- fullSize = BitmapFactory.decodeStream(mInStream, null, options);
+ fullSize = BitmapFactory.decodeStream(is, null, options);
+ Utils.closeSilently(is);
}
if (fullSize != null) {
mCropBounds.left /= scaleDownSampleSize;
diff --git a/src/com/android/launcher3/WallpaperPickerActivity.java b/src/com/android/launcher3/WallpaperPickerActivity.java
index c58d66063..efc311070 100644
--- a/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -67,8 +67,10 @@ import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListAdapter;
+import android.widget.Toast;
import com.android.photos.BitmapRegionTileSource;
+import com.android.photos.BitmapRegionTileSource.BitmapSource;
import java.io.File;
import java.io.FileOutputStream;
@@ -84,7 +86,7 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
private static final String DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb.jpg";
- private View mSelectedThumb;
+ private View mSelectedTile;
private boolean mIgnoreNextTap;
private OnClickListener mThumbnailOnClickListener;
@@ -128,13 +130,39 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
public static class UriWallpaperInfo extends WallpaperTileInfo {
private Uri mUri;
+ private boolean mFirstClick = true;
+ private BitmapRegionTileSource.UriBitmapSource mBitmapSource;
public UriWallpaperInfo(Uri uri) {
mUri = uri;
}
@Override
- public void onClick(WallpaperPickerActivity a) {
- a.setCropViewTileSource(new BitmapRegionTileSource.UriBitmapSource(
- a, mUri, BitmapRegionTileSource.MAX_PREVIEW_SIZE), true, false);
+ public void onClick(final WallpaperPickerActivity a) {
+ final Runnable onLoad;
+ if (!mFirstClick) {
+ onLoad = null;
+ } else {
+ mFirstClick = false;
+ onLoad = new Runnable() {
+ public void run() {
+ if (mBitmapSource != null &&
+ mBitmapSource.getLoadingState() == BitmapSource.State.LOADED) {
+ mView.setVisibility(View.VISIBLE);
+ a.selectTile(mView);
+ } else {
+ ViewGroup parent = (ViewGroup) mView.getParent();
+ if (parent != null) {
+ parent.removeView(mView);
+ Toast.makeText(a,
+ a.getString(R.string.image_load_fail),
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+ }
+ };
+ }
+ mBitmapSource = new BitmapRegionTileSource.UriBitmapSource(
+ a, mUri, BitmapRegionTileSource.MAX_PREVIEW_SIZE);
+ a.setCropViewTileSource(mBitmapSource, true, false, onLoad);
}
@Override
public void onSave(final WallpaperPickerActivity a) {
@@ -304,17 +332,8 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
return;
}
WallpaperTileInfo info = (WallpaperTileInfo) v.getTag();
- if (info.isSelectable()) {
- if (mSelectedThumb != null) {
- mSelectedThumb.setSelected(false);
- mSelectedThumb = null;
- }
- mSelectedThumb = v;
- v.setSelected(true);
- // TODO: Remove this once the accessibility framework and
- // services have better support for selection state.
- v.announceForAccessibility(
- getString(R.string.announce_selection, v.getContentDescription()));
+ if (info.isSelectable() && v.getVisibility() == View.VISIBLE) {
+ selectTile(v);
}
info.onClick(WallpaperPickerActivity.this);
}
@@ -440,8 +459,8 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (mSelectedThumb != null) {
- WallpaperTileInfo info = (WallpaperTileInfo) mSelectedThumb.getTag();
+ if (mSelectedTile != null) {
+ WallpaperTileInfo info = (WallpaperTileInfo) mSelectedTile.getTag();
info.onSave(WallpaperPickerActivity.this);
}
}
@@ -520,15 +539,23 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
CheckableFrameLayout c = (CheckableFrameLayout) mWallpapersView.getChildAt(i);
c.setChecked(false);
}
- mSelectedThumb.setSelected(true);
+ mSelectedTile.setSelected(true);
mActionMode = null;
}
};
}
- @Override
- public void setCropViewTileSource(final BitmapRegionTileSource.BitmapSource bitmapSource,
- final boolean touchEnabled, boolean moveToLeft) {
- super.setCropViewTileSource(bitmapSource, touchEnabled, moveToLeft);
+
+ private void selectTile(View v) {
+ if (mSelectedTile != null) {
+ mSelectedTile.setSelected(false);
+ mSelectedTile = null;
+ }
+ mSelectedTile = v;
+ v.setSelected(true);
+ // TODO: Remove this once the accessibility framework and
+ // services have better support for selection state.
+ v.announceForAccessibility(
+ getString(R.string.announce_selection, v.getContentDescription()));
}
private void initializeScrollForRtl() {
@@ -692,8 +719,9 @@ public class WallpaperPickerActivity extends WallpaperCropActivity {
private void addTemporaryWallpaperTile(final Uri uri) {
mTempWallpaperTiles.add(uri);
// Add a tile for the image picked from Gallery
- FrameLayout pickedImageThumbnail = (FrameLayout) getLayoutInflater().
+ final FrameLayout pickedImageThumbnail = (FrameLayout) getLayoutInflater().
inflate(R.layout.wallpaper_picker_item, mWallpapersView, false);
+ pickedImageThumbnail.setVisibility(View.GONE);
setWallpaperItemPaddingToZero(pickedImageThumbnail);
mWallpapersView.addView(pickedImageThumbnail, 0);
diff --git a/src/com/android/photos/BitmapRegionTileSource.java b/src/com/android/photos/BitmapRegionTileSource.java
index b5774f40a..b85caaa1c 100644
--- a/src/com/android/photos/BitmapRegionTileSource.java
+++ b/src/com/android/photos/BitmapRegionTileSource.java
@@ -31,6 +31,7 @@ import android.os.Build.VERSION_CODES;
import android.util.Log;
import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.common.Utils;
import com.android.gallery3d.exif.ExifInterface;
import com.android.gallery3d.glrenderer.BasicTexture;
import com.android.gallery3d.glrenderer.BitmapTexture;
@@ -62,10 +63,12 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
private Bitmap mPreview;
private int mPreviewSize;
private int mRotation;
+ public enum State { NOT_LOADED, LOADED, ERROR_LOADING };
+ private State mState = State.NOT_LOADED;
public BitmapSource(int previewSize) {
mPreviewSize = previewSize;
}
- public void loadInBackground() {
+ public boolean loadInBackground() {
ExifInterface ei = new ExifInterface();
if (readExif(ei)) {
Integer ori = ei.getTagIntValue(ExifInterface.TAG_ORIENTATION);
@@ -74,21 +77,32 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
}
}
mDecoder = loadBitmapRegionDecoder();
- int width = mDecoder.getWidth();
- int height = mDecoder.getHeight();
- if (mPreviewSize != 0) {
- int previewSize = Math.min(mPreviewSize, MAX_PREVIEW_SIZE);
- BitmapFactory.Options opts = new BitmapFactory.Options();
- opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
- opts.inPreferQualityOverSpeed = true;
-
- float scale = (float) previewSize / Math.max(width, height);
- opts.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
- opts.inJustDecodeBounds = false;
- mPreview = loadPreviewBitmap(opts);
+ if (mDecoder == null) {
+ mState = State.ERROR_LOADING;
+ return false;
+ } else {
+ int width = mDecoder.getWidth();
+ int height = mDecoder.getHeight();
+ if (mPreviewSize != 0) {
+ int previewSize = Math.min(mPreviewSize, MAX_PREVIEW_SIZE);
+ BitmapFactory.Options opts = new BitmapFactory.Options();
+ opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ opts.inPreferQualityOverSpeed = true;
+
+ float scale = (float) previewSize / Math.max(width, height);
+ opts.inSampleSize = BitmapUtils.computeSampleSizeLarger(scale);
+ opts.inJustDecodeBounds = false;
+ mPreview = loadPreviewBitmap(opts);
+ }
+ mState = State.LOADED;
+ return true;
}
}
+ public State getLoadingState() {
+ return mState;
+ }
+
public BitmapRegionDecoder getBitmapRegionDecoder() {
return mDecoder;
}
@@ -156,7 +170,10 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
@Override
public BitmapRegionDecoder loadBitmapRegionDecoder() {
try {
- return BitmapRegionDecoder.newInstance(regenerateInputStream(), true);
+ InputStream is = regenerateInputStream();
+ BitmapRegionDecoder regionDecoder = BitmapRegionDecoder.newInstance(is, false);
+ Utils.closeSilently(is);
+ return regionDecoder;
} catch (FileNotFoundException e) {
Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
return null;
@@ -168,7 +185,10 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
@Override
public Bitmap loadPreviewBitmap(BitmapFactory.Options options) {
try {
- return BitmapFactory.decodeStream(regenerateInputStream(), null, options);
+ InputStream is = regenerateInputStream();
+ Bitmap b = BitmapFactory.decodeStream(is, null, options);
+ Utils.closeSilently(is);
+ return b;
} catch (FileNotFoundException e) {
Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
return null;
@@ -177,13 +197,15 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
@Override
public boolean readExif(ExifInterface ei) {
try {
- ei.readExif(regenerateInputStream());
+ InputStream is = regenerateInputStream();
+ ei.readExif(is);
+ Utils.closeSilently(is);
return true;
} catch (FileNotFoundException e) {
Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
return false;
} catch (IOException e) {
- Log.e("BitmapRegionTileSource", "Failure while reading URI " + mUri, e);
+ Log.e("BitmapRegionTileSource", "Failed to load URI " + mUri, e);
return false;
}
}
@@ -204,7 +226,10 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
@Override
public BitmapRegionDecoder loadBitmapRegionDecoder() {
try {
- return BitmapRegionDecoder.newInstance(regenerateInputStream(), true);
+ InputStream is = regenerateInputStream();
+ BitmapRegionDecoder regionDecoder = BitmapRegionDecoder.newInstance(is, true);
+ Utils.closeSilently(is);
+ return regionDecoder;
} catch (IOException e) {
Log.e("BitmapRegionTileSource", "Error reading resource", e);
return null;
@@ -217,7 +242,9 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
@Override
public boolean readExif(ExifInterface ei) {
try {
- ei.readExif(regenerateInputStream());
+ InputStream is = regenerateInputStream();
+ ei.readExif(is);
+ Utils.closeSilently(is);
return true;
} catch (IOException e) {
Log.e("BitmapRegionTileSource", "Error reading resource", e);
@@ -243,27 +270,29 @@ public class BitmapRegionTileSource implements TiledImageRenderer.TileSource {
mTileSize = TiledImageRenderer.suggestedTileSize(context);
mRotation = source.getRotation();
mDecoder = source.getBitmapRegionDecoder();
- mWidth = mDecoder.getWidth();
- mHeight = mDecoder.getHeight();
- mOptions = new BitmapFactory.Options();
- mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
- mOptions.inPreferQualityOverSpeed = true;
- mOptions.inTempStorage = new byte[16 * 1024];
- int previewSize = source.getPreviewSize();
- if (previewSize != 0) {
- previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
- // Although this is the same size as the Bitmap that is likely already
- // loaded, the lifecycle is different and interactions are on a different
- // thread. Thus to simplify, this source will decode its own bitmap.
- Bitmap preview = decodePreview(source, previewSize);
- if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
- mPreview = new BitmapTexture(preview);
- } else {
- Log.w(TAG, String.format(
- "Failed to create preview of apropriate size! "
- + " in: %dx%d, out: %dx%d",
- mWidth, mHeight,
- preview.getWidth(), preview.getHeight()));
+ if (mDecoder != null) {
+ mWidth = mDecoder.getWidth();
+ mHeight = mDecoder.getHeight();
+ mOptions = new BitmapFactory.Options();
+ mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
+ mOptions.inPreferQualityOverSpeed = true;
+ mOptions.inTempStorage = new byte[16 * 1024];
+ int previewSize = source.getPreviewSize();
+ if (previewSize != 0) {
+ previewSize = Math.min(previewSize, MAX_PREVIEW_SIZE);
+ // Although this is the same size as the Bitmap that is likely already
+ // loaded, the lifecycle is different and interactions are on a different
+ // thread. Thus to simplify, this source will decode its own bitmap.
+ Bitmap preview = decodePreview(source, previewSize);
+ if (preview.getWidth() <= GL_SIZE_LIMIT && preview.getHeight() <= GL_SIZE_LIMIT) {
+ mPreview = new BitmapTexture(preview);
+ } else {
+ Log.w(TAG, String.format(
+ "Failed to create preview of apropriate size! "
+ + " in: %dx%d, out: %dx%d",
+ mWidth, mHeight,
+ preview.getWidth(), preview.getHeight()));
+ }
}
}
}